diff --git a/Telegram/Telegram-iOS/en.lproj/Localizable.strings b/Telegram/Telegram-iOS/en.lproj/Localizable.strings
index f189e1295f..57ed87606b 100644
--- a/Telegram/Telegram-iOS/en.lproj/Localizable.strings
+++ b/Telegram/Telegram-iOS/en.lproj/Localizable.strings
@@ -13819,12 +13819,12 @@ Sorry for the inconvenience.";
 "GroupInfo.Permissions.ChargeForMessages" = "Charge for Messages";
 "GroupInfo.Permissions.ChargeForMessagesInfo" = "If you turn this on, regular members of the group will have to pay Stars to send messages.";
 "GroupInfo.Permissions.MessagePrice" = "SET YOUR PRICE PER MESSAGE";
-"GroupInfo.Permissions.MessagePriceInfo" = "Your group will receive 85% of the selected fee (%1$@) for each incoming message.";
+"GroupInfo.Permissions.MessagePriceInfo" = "Your group will receive %1$@% of the selected fee (%2$@) for each incoming message.";
 
 "Privacy.Messages.ChargeForMessages" = "Charge for Messages";
 "Privacy.Messages.ChargeForMessagesInfo" = "Charge a fee for messages from people outide your contacts or those you haven't messaged first.";
 "Privacy.Messages.MessagePrice" = "SET YOUR PRICE PER MESSAGE";
-"Privacy.Messages.MessagePriceInfo" = "Your will receive 85% of the selected fee (%1$@) for each incoming message.";
+"Privacy.Messages.MessagePriceInfo" = "Your will receive %1$@% of the selected fee (%2$@) for each incoming message.";
 
 "Privacy.Messages.RemoveFeeHeader" = "EXCEPTIONS";
 "Privacy.Messages.RemoveFee" = "Remove Fee";
@@ -13874,3 +13874,5 @@ Sorry for the inconvenience.";
 "Gift.Send.PayWithStars.Info" = "Your balance is **%@**. [Get More Stars >]()";
 
 "Chat.PanelCustomStatusShortInfo" = "%@ is a mark for [Premium subscribers >]()";
+
+"Chat.InputTextPaidMessagePlaceholder" = "Message for %@";
diff --git a/submodules/AccountContext/Sources/AccountContext.swift b/submodules/AccountContext/Sources/AccountContext.swift
index 686709c540..57f228240a 100644
--- a/submodules/AccountContext/Sources/AccountContext.swift
+++ b/submodules/AccountContext/Sources/AccountContext.swift
@@ -1353,20 +1353,43 @@ public struct StickersSearchConfiguration {
 
 public struct StarsSubscriptionConfiguration {
     static var defaultValue: StarsSubscriptionConfiguration {
-        return StarsSubscriptionConfiguration(maxFee: 2500, usdWithdrawRate: 1200)
+        return StarsSubscriptionConfiguration(
+            maxFee: 2500,
+            usdWithdrawRate: 1200,
+            paidMessageMaxAmount: 10000,
+            paidMessageCommissionPermille: 850
+        )
     }
     
-    public let maxFee: Int64?
-    public let usdWithdrawRate: Int64?
+    public let maxFee: Int64
+    public let usdWithdrawRate: Int64
+    public let paidMessageMaxAmount: Int64
+    public let paidMessageCommissionPermille: Int32
     
-    fileprivate init(maxFee: Int64?, usdWithdrawRate: Int64?) {
+    fileprivate init(
+        maxFee: Int64,
+        usdWithdrawRate: Int64,
+        paidMessageMaxAmount: Int64,
+        paidMessageCommissionPermille: Int32
+    ) {
         self.maxFee = maxFee
         self.usdWithdrawRate = usdWithdrawRate
+        self.paidMessageMaxAmount = paidMessageMaxAmount
+        self.paidMessageCommissionPermille = paidMessageCommissionPermille
     }
     
     public static func with(appConfiguration: AppConfiguration) -> StarsSubscriptionConfiguration {
-        if let data = appConfiguration.data, let value = data["stars_subscription_amount_max"] as? Double, let usdRate = data["stars_usd_withdraw_rate_x1000"] as? Double {
-            return StarsSubscriptionConfiguration(maxFee: Int64(value), usdWithdrawRate: Int64(usdRate))
+        if let data = appConfiguration.data {
+            let maxFee = (data["stars_subscription_amount_max"] as? Double).flatMap(Int64.init) ?? StarsSubscriptionConfiguration.defaultValue.maxFee
+            let usdWithdrawRate = (data["stars_usd_withdraw_rate_x1000"] as? Double).flatMap(Int64.init) ?? StarsSubscriptionConfiguration.defaultValue.usdWithdrawRate
+            let paidMessageMaxAmount = (data["stars_paid_message_amount_max"] as? Double).flatMap(Int64.init) ?? StarsSubscriptionConfiguration.defaultValue.paidMessageMaxAmount
+            let paidMessageCommissionPermille = (data["stars_paid_message_commission_permille"] as? Double).flatMap(Int32.init) ?? StarsSubscriptionConfiguration.defaultValue.paidMessageCommissionPermille
+            return StarsSubscriptionConfiguration(
+                maxFee: maxFee,
+                usdWithdrawRate: usdWithdrawRate,
+                paidMessageMaxAmount: paidMessageMaxAmount,
+                paidMessageCommissionPermille: paidMessageCommissionPermille
+            )
         } else {
             return .defaultValue
         }
diff --git a/submodules/AccountContext/Sources/ShareController.swift b/submodules/AccountContext/Sources/ShareController.swift
index 122c247bda..6e33940d3e 100644
--- a/submodules/AccountContext/Sources/ShareController.swift
+++ b/submodules/AccountContext/Sources/ShareController.swift
@@ -76,5 +76,5 @@ public enum ShareControllerSubject {
     case image([ImageRepresentationWithReference])
     case media(AnyMediaReference, MediaParameters?)
     case mapMedia(TelegramMediaMap)
-    case fromExternal(([PeerId], [PeerId: Int64], String, ShareControllerAccountContext, Bool) -> Signal<ShareControllerExternalStatus, ShareControllerError>)
+    case fromExternal(Int, ([PeerId], [PeerId: Int64], [PeerId: StarsAmount], String, ShareControllerAccountContext, Bool) -> Signal<ShareControllerExternalStatus, ShareControllerError>)
 }
diff --git a/submodules/GameUI/Sources/GameControllerNode.swift b/submodules/GameUI/Sources/GameControllerNode.swift
index c0274d25b1..06923b10d1 100644
--- a/submodules/GameUI/Sources/GameControllerNode.swift
+++ b/submodules/GameUI/Sources/GameControllerNode.swift
@@ -144,7 +144,7 @@ final class GameControllerNode: ViewControllerTracingNode {
         if eventName == "share_game" || eventName == "share_score" {
             if let (botPeer, gameName) = self.shareData(), let addressName = botPeer.addressName, !addressName.isEmpty, !gameName.isEmpty {
                 if eventName == "share_score" {
-                    self.present(ShareController(context: self.context, subject: .fromExternal({ [weak self] peerIds, threadIds, text, account, _ in
+                    self.present(ShareController(context: self.context, subject: .fromExternal(1, { [weak self] peerIds, threadIds, requireStars, text, account, _ in
                         if let strongSelf = self, let message = strongSelf.message, let account = account as? ShareControllerAppAccountContext {
                             let signals = peerIds.map { TelegramEngine(account: account.context.account).messages.forwardGameWithScore(messageId: message.id, to: $0, threadId: threadIds[$0], as: nil) }
                             return .single(.preparing(false))
diff --git a/submodules/InviteLinksUI/Sources/InviteLinkEditController.swift b/submodules/InviteLinksUI/Sources/InviteLinkEditController.swift
index e1b84e2123..ceb9f8df51 100644
--- a/submodules/InviteLinksUI/Sources/InviteLinkEditController.swift
+++ b/submodules/InviteLinksUI/Sources/InviteLinkEditController.swift
@@ -493,13 +493,10 @@ private func inviteLinkEditControllerEntries(invite: ExportedInvitation?, state:
         if state.subscriptionEnabled {
             var label: String = ""
             if let subscriptionFee = state.subscriptionFee, subscriptionFee > StarsAmount.zero {
-                var usdRate = 0.012
-                if let usdWithdrawRate = configuration.usdWithdrawRate {
-                    usdRate = Double(usdWithdrawRate) / 1000.0 / 100.0
-                }
+                let usdRate = Double(configuration.usdWithdrawRate) / 1000.0 / 100.0
                 label = presentationData.strings.InviteLink_Create_FeePerMonth("≈\(formatTonUsdValue(subscriptionFee.value, divide: false, rate: usdRate, dateTimeFormat: presentationData.dateTimeFormat))").string
             }
-            entries.append(.subscriptionFee(presentationData.theme, presentationData.strings.InviteLink_Create_FeePlaceholder, isEditingEnabled, state.subscriptionFee, label, configuration.maxFee.flatMap({ StarsAmount(value: $0, nanos: 0) })))
+            entries.append(.subscriptionFee(presentationData.theme, presentationData.strings.InviteLink_Create_FeePlaceholder, isEditingEnabled, state.subscriptionFee, label, StarsAmount(value: configuration.maxFee, nanos: 0)))
         }
         let infoText: String
         if let _ = invite, state.subscriptionEnabled {
diff --git a/submodules/InviteLinksUI/Sources/InviteLinkViewController.swift b/submodules/InviteLinksUI/Sources/InviteLinkViewController.swift
index c1191eb94c..e303fe8b3b 100644
--- a/submodules/InviteLinksUI/Sources/InviteLinkViewController.swift
+++ b/submodules/InviteLinksUI/Sources/InviteLinkViewController.swift
@@ -594,10 +594,7 @@ public final class InviteLinkViewController: ViewController {
                     guard let peer else {
                         return
                     }
-                    var usdRate = 0.012
-                    if let usdWithdrawRate = configuration.usdWithdrawRate {
-                        usdRate = Double(usdWithdrawRate) / 1000.0 / 100.0
-                    }
+                    let usdRate = Double(configuration.usdWithdrawRate) / 1000.0 / 100.0
                     let subscriptionController = context.sharedContext.makeStarsSubscriptionScreen(context: context, peer: peer, pricing: pricing, importer: importer, usdRate: usdRate)
                     self?.controller?.push(subscriptionController)
                 })
@@ -834,11 +831,8 @@ public final class InviteLinkViewController: ViewController {
                     context.account.postbox.loadedPeerWithId(adminId)
                 ) |> deliverOnMainQueue).start(next: { [weak self] presentationData, state, requestsState, creatorPeer in
                     if let strongSelf = self {
-                        var usdRate = 0.012
-                        if let usdWithdrawRate = configuration.usdWithdrawRate {
-                            usdRate = Double(usdWithdrawRate) / 1000.0 / 100.0
-                        }
-                                                                        
+                        let usdRate = Double(configuration.usdWithdrawRate) / 1000.0 / 100.0
+             
                         var entries: [InviteLinkViewEntry] = []
                         
                         entries.append(.link(presentationData.theme, invite))
diff --git a/submodules/PeerInfoUI/Sources/ChannelPermissionsController.swift b/submodules/PeerInfoUI/Sources/ChannelPermissionsController.swift
index b1c1d646c5..f41f3921d1 100644
--- a/submodules/PeerInfoUI/Sources/ChannelPermissionsController.swift
+++ b/submodules/PeerInfoUI/Sources/ChannelPermissionsController.swift
@@ -720,7 +720,7 @@ private func channelPermissionsControllerEntries(context: AccountContext, presen
             entries.append(.conversionInfo(presentationData.theme, presentationData.strings.GroupInfo_Permissions_BroadcastConvertInfo(presentationStringsFormattedNumber(participantsLimit, presentationData.dateTimeFormat.groupingSeparator)).string))
         }
         
-        if channel.hasPermission(.banMembers) {
+        if cachedData.flags.contains(.paidMessagesAvailable) && channel.hasPermission(.banMembers) {
             let sendPaidMessageStars = state.modifiedStarsAmount?.value ?? (cachedData.sendPaidMessageStars?.value ?? 0)
             let chargeEnabled = sendPaidMessageStars > 0
             entries.append(.chargeForMessages(presentationData.theme, presentationData.strings.GroupInfo_Permissions_ChargeForMessages, chargeEnabled))
@@ -728,15 +728,13 @@ private func channelPermissionsControllerEntries(context: AccountContext, presen
             
             if chargeEnabled {
                 var price: String = ""
-                var usdRate = 0.012
-                if let usdWithdrawRate = configuration.usdWithdrawRate {
-                    usdRate = Double(usdWithdrawRate) / 1000.0 / 100.0
-                }
+                let usdRate = Double(configuration.usdWithdrawRate) / 1000.0 / 100.0
+                
                 price = "≈\(formatTonUsdValue(sendPaidMessageStars, divide: false, rate: usdRate, dateTimeFormat: presentationData.dateTimeFormat))"
                 
                 entries.append(.messagePriceHeader(presentationData.theme, presentationData.strings.GroupInfo_Permissions_MessagePrice))
                 entries.append(.messagePrice(presentationData.theme, sendPaidMessageStars, price))
-                entries.append(.messagePriceInfo(presentationData.theme, presentationData.strings.GroupInfo_Permissions_MessagePriceInfo(price).string))
+                entries.append(.messagePriceInfo(presentationData.theme, presentationData.strings.GroupInfo_Permissions_MessagePriceInfo("\(configuration.paidMessageCommissionPermille / 10)", price).string))
             }
         }
         
diff --git a/submodules/SettingsUI/Sources/Privacy and Security/IncomingMessagePrivacyScreen.swift b/submodules/SettingsUI/Sources/Privacy and Security/IncomingMessagePrivacyScreen.swift
index 0009407f80..e7b6151db8 100644
--- a/submodules/SettingsUI/Sources/Privacy and Security/IncomingMessagePrivacyScreen.swift	
+++ b/submodules/SettingsUI/Sources/Privacy and Security/IncomingMessagePrivacyScreen.swift	
@@ -50,7 +50,7 @@ private enum GlobalAutoremoveEntry: ItemListNodeEntry {
     case footer(value: GlobalPrivacySettings.NonContactChatsPrivacy)
     case priceHeader
     case price(value: Int64, price: String)
-    case priceInfo(value: String)
+    case priceInfo(commission: Int32, value: String)
     case exceptionsHeader
     case exceptions(count: Int)
     case exceptionsInfo
@@ -153,8 +153,8 @@ private enum GlobalAutoremoveEntry: ItemListNodeEntry {
             return MessagePriceItem(theme: presentationData.theme, strings: presentationData.strings, minValue: 1, maxValue: 10000, value: value, price: price, sectionId: self.section, updated: { value in
                 arguments.updateValue(.paidMessages(StarsAmount(value: value, nanos: 0)))
             })
-        case let .priceInfo(value):
-            return ItemListTextItem(presentationData: presentationData, text: .markdown(presentationData.strings.Privacy_Messages_MessagePriceInfo(value).string), sectionId: self.section)
+        case let .priceInfo(commission, value):
+            return ItemListTextItem(presentationData: presentationData, text: .markdown(presentationData.strings.Privacy_Messages_MessagePriceInfo("\(commission)", value).string), sectionId: self.section)
         case .exceptionsHeader:
             return ItemListSectionHeaderItem(presentationData: presentationData, text: presentationData.strings.Privacy_Messages_RemoveFeeHeader, sectionId: self.section)
         case let .exceptions(count):
@@ -184,14 +184,12 @@ private func incomingMessagePrivacyScreenEntries(presentationData: PresentationD
         entries.append(.footer(value: state.updatedValue))
         entries.append(.priceHeader)
         
-        var usdRate = 0.012
-        if let usdWithdrawRate = configuration.usdWithdrawRate {
-            usdRate = Double(usdWithdrawRate) / 1000.0 / 100.0
-        }
+        let usdRate = Double(configuration.usdWithdrawRate) / 1000.0 / 100.0
+        
         let price = "≈\(formatTonUsdValue(amount.value, divide: false, rate: usdRate, dateTimeFormat: presentationData.dateTimeFormat))"
         
         entries.append(.price(value: amount.value, price: price))
-        entries.append(.priceInfo(value: price))
+        entries.append(.priceInfo(commission: configuration.paidMessageCommissionPermille / 10, value: price))
         entries.append(.exceptionsHeader)
         entries.append(.exceptions(count: state.disableFor.count))
         entries.append(.exceptionsInfo)
diff --git a/submodules/ShareController/Sources/ShareController.swift b/submodules/ShareController/Sources/ShareController.swift
index def38e6cfa..f2152f33bb 100644
--- a/submodules/ShareController/Sources/ShareController.swift
+++ b/submodules/ShareController/Sources/ShareController.swift
@@ -676,6 +676,8 @@ public final class ShareController: ViewController {
             messageCount = messages.count
         } else if case let .image(images) = self.subject {
             messageCount = images.count
+        } else if case let .fromExternal(count, _) = self.subject {
+            messageCount = count
         }
         
         var mediaParameters: ShareControllerSubject.MediaParameters?
@@ -1253,18 +1255,18 @@ public final class ShareController: ViewController {
             }
         )
         |> take(1)
-        |> map { views -> ([EnginePeer.Id: EnginePeer?], [EnginePeer.Id: Int64]) in
+        |> map { views -> ([EnginePeer.Id: EnginePeer?], [EnginePeer.Id: StarsAmount]) in
             var result: [EnginePeer.Id: EnginePeer?] = [:]
-            var requiresStars: [EnginePeer.Id: Int64] = [:]
+            var requiresStars: [EnginePeer.Id: StarsAmount] = [:]
             for peerId in peerIds {
                 if let view = views.views[PostboxViewKey.basicPeer(peerId)] as? BasicPeerView, let peer = view.peer {
                     result[peerId] = EnginePeer(peer)
                     if peer is TelegramUser, let cachedPeerDataView = views.views[PostboxViewKey.cachedPeerData(peerId: peerId)] as? CachedPeerDataView {
                         if let cachedData = cachedPeerDataView.cachedPeerData as? CachedUserData {
-                            requiresStars[peerId] = cachedData.sendPaidMessageStars?.value
+                            requiresStars[peerId] = cachedData.sendPaidMessageStars
                         }
                     } else if let channel = peer as? TelegramChannel {
-                        requiresStars[peerId] = channel.sendPaidMessageStars?.value
+                        requiresStars[peerId] = channel.sendPaidMessageStars
                     }
                 }
             }
@@ -1284,7 +1286,7 @@ public final class ShareController: ViewController {
                 subject = selectedValue.subject
             }
             
-            func transformMessages(_ messages: [StandaloneSendEnqueueMessage], showNames: Bool, silently: Bool, sendPaidMessageStars: Int64?) -> [StandaloneSendEnqueueMessage] {
+            func transformMessages(_ messages: [StandaloneSendEnqueueMessage], showNames: Bool, silently: Bool, sendPaidMessageStars: StarsAmount?) -> [StandaloneSendEnqueueMessage] {
                 return messages.map { message in
                     var message = message
                     if !showNames {
@@ -1296,7 +1298,7 @@ public final class ShareController: ViewController {
                     if silently {
                         message.isSilent = true
                     }
-                    message.sendPaidMessageStars = sendPaidMessageStars.flatMap { StarsAmount(value: $0, nanos: 0) }
+                    message.sendPaidMessageStars = sendPaidMessageStars
                     return message
                 }
             }
@@ -1839,8 +1841,8 @@ public final class ShareController: ViewController {
                         messages: messagesToEnqueue
                     ))
                 }
-            case let .fromExternal(f):
-                return f(peerIds, topicIds, text, strongSelf.currentContext, silently)
+            case let .fromExternal(_, f):
+                return f(peerIds, topicIds, requiresStars, text, strongSelf.currentContext, silently)
                 |> map { state -> ShareState in
                     switch state {
                     case let .preparing(long):
@@ -1907,18 +1909,18 @@ public final class ShareController: ViewController {
             }
         )
         |> take(1)
-        |> map { views -> ([EnginePeer.Id: EnginePeer?], [EnginePeer.Id: Int64]) in
+        |> map { views -> ([EnginePeer.Id: EnginePeer?], [EnginePeer.Id: StarsAmount]) in
             var result: [EnginePeer.Id: EnginePeer?] = [:]
-            var requiresStars: [EnginePeer.Id: Int64] = [:]
+            var requiresStars: [EnginePeer.Id: StarsAmount] = [:]
             for peerId in peerIds {
                 if let view = views.views[PostboxViewKey.basicPeer(peerId)] as? BasicPeerView, let peer = view.peer {
                     result[peerId] = EnginePeer(peer)
                     if peer is TelegramUser, let cachedPeerDataView = views.views[PostboxViewKey.cachedPeerData(peerId: peerId)] as? CachedPeerDataView {
                         if let cachedData = cachedPeerDataView.cachedPeerData as? CachedUserData {
-                            requiresStars[peerId] = cachedData.sendPaidMessageStars?.value
+                            requiresStars[peerId] = cachedData.sendPaidMessageStars
                         }
                     } else if let channel = peer as? TelegramChannel {
-                        requiresStars[peerId] = channel.sendPaidMessageStars?.value
+                        requiresStars[peerId] = channel.sendPaidMessageStars
                     }
                 }
             }
@@ -1938,7 +1940,7 @@ public final class ShareController: ViewController {
                 subject = selectedValue.subject
             }
             
-            func transformMessages(_ messages: [EnqueueMessage], showNames: Bool, silently: Bool, sendPaidMessageStars: Int64?) -> [EnqueueMessage] {
+            func transformMessages(_ messages: [EnqueueMessage], showNames: Bool, silently: Bool, sendPaidMessageStars: StarsAmount?) -> [EnqueueMessage] {
                 return messages.map { message in
                     return message.withUpdatedAttributes({ attributes in
                         var attributes = attributes
@@ -1949,7 +1951,7 @@ public final class ShareController: ViewController {
                             attributes.append(NotificationInfoMessageAttribute(flags: .muted))
                         }
                         if let sendPaidMessageStars {
-                            attributes.append(PaidStarsMessageAttribute(stars: StarsAmount(value: sendPaidMessageStars, nanos: 0), postponeSending: false))
+                            attributes.append(PaidStarsMessageAttribute(stars: sendPaidMessageStars, postponeSending: false))
                         }
                         return attributes
                     })
@@ -2321,8 +2323,8 @@ public final class ShareController: ViewController {
                     messagesToEnqueue = transformMessages(messagesToEnqueue, showNames: showNames, silently: silently, sendPaidMessageStars: requiresStars[peerId])
                     shareSignals.append(enqueueMessages(account: currentContext.context.account, peerId: peerId, messages: messagesToEnqueue))
                 }
-            case let .fromExternal(f):
-                return f(peerIds, topicIds, text, currentContext, silently)
+            case let .fromExternal(_, f):
+                return f(peerIds, topicIds, requiresStars, text, currentContext, silently)
                 |> map { state -> ShareState in
                     switch state {
                     case let .preparing(long):
diff --git a/submodules/ShareItems/Sources/ShareItems.swift b/submodules/ShareItems/Sources/ShareItems.swift
index 84c74e819c..d063a8e0cf 100644
--- a/submodules/ShareItems/Sources/ShareItems.swift
+++ b/submodules/ShareItems/Sources/ShareItems.swift
@@ -409,7 +409,7 @@ public func preparedShareItems(postbox: Postbox, network: Network, to peerId: Pe
     })
 }
 
-public func sentShareItems(accountPeerId: PeerId, postbox: Postbox, network: Network, stateManager: AccountStateManager, auxiliaryMethods: AccountAuxiliaryMethods, to peerIds: [PeerId], threadIds: [PeerId: Int64], items: [PreparedShareItemContent], silently: Bool, additionalText: String) -> Signal<Float, Void> {
+public func sentShareItems(accountPeerId: PeerId, postbox: Postbox, network: Network, stateManager: AccountStateManager, auxiliaryMethods: AccountAuxiliaryMethods, to peerIds: [PeerId], threadIds: [PeerId: Int64], requireStars: [PeerId: StarsAmount], items: [PreparedShareItemContent], silently: Bool, additionalText: String) -> Signal<Float, Void> {
     var messages: [StandaloneSendEnqueueMessage] = []
     var groupingKey: Int64?
     var mediaTypes: (photo: Int, video: Int, music: Int, other: Int) = (0, 0, 0, 0)
@@ -498,6 +498,16 @@ public func sentShareItems(accountPeerId: PeerId, postbox: Postbox, network: Net
     
     var peerSignals: Signal<Float, StandaloneSendMessagesError> = .single(0.0)
     for peerId in peerIds {
+        var peerMessages = messages
+        if let amount = requireStars[peerId] {
+            var updatedMessages: [StandaloneSendEnqueueMessage] = []
+            for message in peerMessages {
+                var message = message
+                message.sendPaidMessageStars = amount
+                updatedMessages.append(message)
+            }
+            peerMessages = updatedMessages
+        }
         peerSignals = peerSignals |> then(standaloneSendEnqueueMessages(
             accountPeerId: accountPeerId,
             postbox: postbox,
@@ -506,7 +516,7 @@ public func sentShareItems(accountPeerId: PeerId, postbox: Postbox, network: Net
             auxiliaryMethods: auxiliaryMethods,
             peerId: peerId,
             threadId: threadIds[peerId],
-            messages: messages
+            messages: peerMessages
         )
         |> mapToSignal { status -> Signal<Float, StandaloneSendMessagesError> in
             switch status {
diff --git a/submodules/TelegramApi/Sources/Api0.swift b/submodules/TelegramApi/Sources/Api0.swift
index 26afc9bdca..42feaf44c6 100644
--- a/submodules/TelegramApi/Sources/Api0.swift
+++ b/submodules/TelegramApi/Sources/Api0.swift
@@ -1390,7 +1390,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
     dict[1314881805] = { return Api.payments.PaymentResult.parse_paymentResult($0) }
     dict[-666824391] = { return Api.payments.PaymentResult.parse_paymentVerificationNeeded($0) }
     dict[-74456004] = { return Api.payments.SavedInfo.parse_savedInfo($0) }
-    dict[-1779201615] = { return Api.payments.SavedStarGifts.parse_savedStarGifts($0) }
+    dict[-418915641] = { return Api.payments.SavedStarGifts.parse_savedStarGifts($0) }
     dict[377215243] = { return Api.payments.StarGiftUpgradePreview.parse_starGiftUpgradePreview($0) }
     dict[-2069218660] = { return Api.payments.StarGiftWithdrawalUrl.parse_starGiftWithdrawalUrl($0) }
     dict[-1877571094] = { return Api.payments.StarGifts.parse_starGifts($0) }
diff --git a/submodules/TelegramApi/Sources/Api35.swift b/submodules/TelegramApi/Sources/Api35.swift
index c8dbfa6fa7..6c7f89773e 100644
--- a/submodules/TelegramApi/Sources/Api35.swift
+++ b/submodules/TelegramApi/Sources/Api35.swift
@@ -1,16 +1,21 @@
 public extension Api.payments {
     enum SavedStarGifts: TypeConstructorDescription {
-        case savedStarGifts(flags: Int32, count: Int32, chatNotificationsEnabled: Api.Bool?, gifts: [Api.SavedStarGift], nextOffset: String?, chats: [Api.Chat], users: [Api.User])
+        case savedStarGifts(flags: Int32, count: Int32, chatNotificationsEnabled: Api.Bool?, pinnedToTop: [Int64]?, gifts: [Api.SavedStarGift], nextOffset: String?, chats: [Api.Chat], users: [Api.User])
     
     public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
     switch self {
-                case .savedStarGifts(let flags, let count, let chatNotificationsEnabled, let gifts, let nextOffset, let chats, let users):
+                case .savedStarGifts(let flags, let count, let chatNotificationsEnabled, let pinnedToTop, let gifts, let nextOffset, let chats, let users):
                     if boxed {
-                        buffer.appendInt32(-1779201615)
+                        buffer.appendInt32(-418915641)
                     }
                     serializeInt32(flags, buffer: buffer, boxed: false)
                     serializeInt32(count, buffer: buffer, boxed: false)
                     if Int(flags) & Int(1 << 1) != 0 {chatNotificationsEnabled!.serialize(buffer, true)}
+                    if Int(flags) & Int(1 << 2) != 0 {buffer.appendInt32(481674261)
+                    buffer.appendInt32(Int32(pinnedToTop!.count))
+                    for item in pinnedToTop! {
+                        serializeInt64(item, buffer: buffer, boxed: false)
+                    }}
                     buffer.appendInt32(481674261)
                     buffer.appendInt32(Int32(gifts.count))
                     for item in gifts {
@@ -33,8 +38,8 @@ public extension Api.payments {
     
     public func descriptionFields() -> (String, [(String, Any)]) {
         switch self {
-                case .savedStarGifts(let flags, let count, let chatNotificationsEnabled, let gifts, let nextOffset, let chats, let users):
-                return ("savedStarGifts", [("flags", flags as Any), ("count", count as Any), ("chatNotificationsEnabled", chatNotificationsEnabled as Any), ("gifts", gifts as Any), ("nextOffset", nextOffset as Any), ("chats", chats as Any), ("users", users as Any)])
+                case .savedStarGifts(let flags, let count, let chatNotificationsEnabled, let pinnedToTop, let gifts, let nextOffset, let chats, let users):
+                return ("savedStarGifts", [("flags", flags as Any), ("count", count as Any), ("chatNotificationsEnabled", chatNotificationsEnabled as Any), ("pinnedToTop", pinnedToTop as Any), ("gifts", gifts as Any), ("nextOffset", nextOffset as Any), ("chats", chats as Any), ("users", users as Any)])
     }
     }
     
@@ -47,29 +52,34 @@ public extension Api.payments {
             if Int(_1!) & Int(1 << 1) != 0 {if let signature = reader.readInt32() {
                 _3 = Api.parse(reader, signature: signature) as? Api.Bool
             } }
-            var _4: [Api.SavedStarGift]?
+            var _4: [Int64]?
+            if Int(_1!) & Int(1 << 2) != 0 {if let _ = reader.readInt32() {
+                _4 = Api.parseVector(reader, elementSignature: 570911930, elementType: Int64.self)
+            } }
+            var _5: [Api.SavedStarGift]?
             if let _ = reader.readInt32() {
-                _4 = Api.parseVector(reader, elementSignature: 0, elementType: Api.SavedStarGift.self)
+                _5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.SavedStarGift.self)
             }
-            var _5: String?
-            if Int(_1!) & Int(1 << 0) != 0 {_5 = parseString(reader) }
-            var _6: [Api.Chat]?
+            var _6: String?
+            if Int(_1!) & Int(1 << 0) != 0 {_6 = parseString(reader) }
+            var _7: [Api.Chat]?
             if let _ = reader.readInt32() {
-                _6 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
+                _7 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
             }
-            var _7: [Api.User]?
+            var _8: [Api.User]?
             if let _ = reader.readInt32() {
-                _7 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
+                _8 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
             }
             let _c1 = _1 != nil
             let _c2 = _2 != nil
             let _c3 = (Int(_1!) & Int(1 << 1) == 0) || _3 != nil
-            let _c4 = _4 != nil
-            let _c5 = (Int(_1!) & Int(1 << 0) == 0) || _5 != nil
-            let _c6 = _6 != nil
+            let _c4 = (Int(_1!) & Int(1 << 2) == 0) || _4 != nil
+            let _c5 = _5 != nil
+            let _c6 = (Int(_1!) & Int(1 << 0) == 0) || _6 != nil
             let _c7 = _7 != nil
-            if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 {
-                return Api.payments.SavedStarGifts.savedStarGifts(flags: _1!, count: _2!, chatNotificationsEnabled: _3, gifts: _4!, nextOffset: _5, chats: _6!, users: _7!)
+            let _c8 = _8 != nil
+            if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 {
+                return Api.payments.SavedStarGifts.savedStarGifts(flags: _1!, count: _2!, chatNotificationsEnabled: _3, pinnedToTop: _4, gifts: _5!, nextOffset: _6, chats: _7!, users: _8!)
             }
             else {
                 return nil
diff --git a/submodules/TelegramApi/Sources/Api38.swift b/submodules/TelegramApi/Sources/Api38.swift
index a7f8b72dae..9c10a1bc0b 100644
--- a/submodules/TelegramApi/Sources/Api38.swift
+++ b/submodules/TelegramApi/Sources/Api38.swift
@@ -9717,6 +9717,26 @@ public extension Api.functions.payments {
                     })
                 }
 }
+public extension Api.functions.payments {
+                static func toggleStarGiftsPinnedToTop(peer: Api.InputPeer, stargift: [Api.InputSavedStarGift]) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
+                    let buffer = Buffer()
+                    buffer.appendInt32(353626032)
+                    peer.serialize(buffer, true)
+                    buffer.appendInt32(481674261)
+                    buffer.appendInt32(Int32(stargift.count))
+                    for item in stargift {
+                        item.serialize(buffer, true)
+                    }
+                    return (FunctionDescription(name: "payments.toggleStarGiftsPinnedToTop", parameters: [("peer", String(describing: peer)), ("stargift", String(describing: stargift))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Bool? in
+                        let reader = BufferReader(buffer)
+                        var result: Api.Bool?
+                        if let signature = reader.readInt32() {
+                            result = Api.parse(reader, signature: signature) as? Api.Bool
+                        }
+                        return result
+                    })
+                }
+}
 public extension Api.functions.payments {
                 static func transferStarGift(stargift: Api.InputSavedStarGift, toId: Api.InputPeer) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) {
                     let buffer = Buffer()
diff --git a/submodules/TelegramCore/Sources/PendingMessages/StandaloneSendMessage.swift b/submodules/TelegramCore/Sources/PendingMessages/StandaloneSendMessage.swift
index b41bf14e64..4fac57c73d 100644
--- a/submodules/TelegramCore/Sources/PendingMessages/StandaloneSendMessage.swift
+++ b/submodules/TelegramCore/Sources/PendingMessages/StandaloneSendMessage.swift
@@ -129,6 +129,7 @@ public func standaloneSendEnqueueMessages(
     struct MessageResult {
         var result: PendingMessageUploadedContentResult
         var media: [Media]
+        var attributes: [MessageAttribute]
     }
     
     let signals: [Signal<MessageResult, PendingMessageUploadError>] = messages.map { message in
@@ -178,7 +179,10 @@ public func standaloneSendEnqueueMessages(
         if message.isSilent {
             attributes.append(NotificationInfoMessageAttribute(flags: .muted))
         }
-        
+        if let sendPaidMessageStars = message.sendPaidMessageStars {
+            attributes.append(PaidStarsMessageAttribute(stars: sendPaidMessageStars, postponeSending: false))
+        }
+                
         let content = messageContentToUpload(accountPeerId: accountPeerId, network: network, postbox: postbox, auxiliaryMethods: auxiliaryMethods, transformOutgoingMessageMedia: { _, _, _, _ in
             return .single(nil)
         }, messageMediaPreuploadManager: MessageMediaPreuploadManager(), revalidationContext: MediaReferenceRevalidationContext(), forceReupload: false, isGrouped: false, passFetchProgress: true, forceNoBigParts: false, peerId: peerId, messageId: nil, attributes: attributes, text: text, media: media)
@@ -191,7 +195,7 @@ public func standaloneSendEnqueueMessages(
         }
         return contentResult
         |> map { contentResult in
-            return MessageResult(result: contentResult, media: media)
+            return MessageResult(result: contentResult, media: media, attributes: attributes)
         }
     }
     
@@ -201,7 +205,7 @@ public func standaloneSendEnqueueMessages(
     }
     |> mapToSignal { contentResults -> Signal<StandaloneSendMessageStatus, StandaloneSendMessagesError> in
         var progressSum: Float = 0.0
-        var allResults: [(result: PendingMessageUploadedContentAndReuploadInfo, media: [Media])] = []
+        var allResults: [(result: PendingMessageUploadedContentAndReuploadInfo, media: [Media], attributes: [MessageAttribute])] = []
         var allDone = true
         for result in contentResults {
             switch result.result {
@@ -209,13 +213,13 @@ public func standaloneSendEnqueueMessages(
                 allDone = false
                 progressSum += value.progress
             case let .content(content):
-                allResults.append((content, result.media))
+                allResults.append((content, result.media, result.attributes))
             }
         }
         if allDone {
             var sendSignals: [Signal<Never, StandaloneSendMessagesError>] = []
             
-            for (content, media) in allResults {
+            for (content, media, attributes) in allResults {
                 var text: String = ""
                 switch content.content {
                 case let .text(textValue):
@@ -235,7 +239,7 @@ public func standaloneSendEnqueueMessages(
                     peerId: peerId,
                     content: content,
                     text: text,
-                    attributes: [],
+                    attributes: attributes,
                     media: media,
                     threadId: threadId
                 ))
@@ -328,6 +332,7 @@ private func sendUploadedMessageContent(
             var videoTimestamp: Int32?
             var sendAsPeerId: PeerId?
             var bubbleUpEmojiOrStickersets = false
+            var allowPaidStars: Int64?
             
             var flags: Int32 = 0
 
@@ -365,6 +370,8 @@ private func sendUploadedMessageContent(
                 } else if let attribute = attribute as? ForwardVideoTimestampAttribute {
                     flags |= Int32(1 << 20)
                     videoTimestamp = attribute.timestamp
+                } else if let attribute = attribute as? PaidStarsMessageAttribute {
+                    allowPaidStars = attribute.stars.value
                 }
             }
             
@@ -390,6 +397,11 @@ private func sendUploadedMessageContent(
                 flags |= (1 << 13)
             }
             
+            if let _ = allowPaidStars {
+                flags |= 1 << 21
+            }
+            
+            
             let dependencyTag: PendingMessageRequestDependencyTag? = nil//(messageId: messageId)
             
             let sendMessageRequest: Signal<NetworkRequestResult<Api.Updates>, MTRpcError>
@@ -415,7 +427,7 @@ private func sendUploadedMessageContent(
                         }
                     }
                 
-                    sendMessageRequest = network.requestWithAdditionalInfo(Api.functions.messages.sendMessage(flags: flags, peer: inputPeer, replyTo: replyTo, message: text, randomId: uniqueId, replyMarkup: nil, entities: messageEntities, scheduleDate: scheduleTime, sendAs: sendAsInputPeer, quickReplyShortcut: nil, effect: nil, allowPaidStars: nil), info: .acknowledgement, tag: dependencyTag)
+                    sendMessageRequest = network.requestWithAdditionalInfo(Api.functions.messages.sendMessage(flags: flags, peer: inputPeer, replyTo: replyTo, message: text, randomId: uniqueId, replyMarkup: nil, entities: messageEntities, scheduleDate: scheduleTime, sendAs: sendAsInputPeer, quickReplyShortcut: nil, effect: nil, allowPaidStars: allowPaidStars), info: .acknowledgement, tag: dependencyTag)
                 case let .media(inputMedia, text):
                     if bubbleUpEmojiOrStickersets {
                         flags |= Int32(1 << 15)
@@ -437,7 +449,7 @@ private func sendUploadedMessageContent(
                         }
                     }
                     
-                sendMessageRequest = network.request(Api.functions.messages.sendMedia(flags: flags, peer: inputPeer, replyTo: replyTo, media: inputMedia, message: text, randomId: uniqueId, replyMarkup: nil, entities: messageEntities, scheduleDate: scheduleTime, sendAs: sendAsInputPeer, quickReplyShortcut: nil, effect: nil, allowPaidStars: nil), tag: dependencyTag)
+                sendMessageRequest = network.request(Api.functions.messages.sendMedia(flags: flags, peer: inputPeer, replyTo: replyTo, media: inputMedia, message: text, randomId: uniqueId, replyMarkup: nil, entities: messageEntities, scheduleDate: scheduleTime, sendAs: sendAsInputPeer, quickReplyShortcut: nil, effect: nil, allowPaidStars: allowPaidStars), tag: dependencyTag)
                     |> map(NetworkRequestResult.result)
                 case let .forward(sourceInfo):
                     var topMsgId: Int32?
@@ -447,7 +459,7 @@ private func sendUploadedMessageContent(
                     }
                 
                     if let forwardSourceInfoAttribute = forwardSourceInfoAttribute, let sourcePeer = transaction.getPeer(forwardSourceInfoAttribute.messageId.peerId), let sourceInputPeer = apiInputPeer(sourcePeer) {
-                        sendMessageRequest = network.request(Api.functions.messages.forwardMessages(flags: flags, fromPeer: sourceInputPeer, id: [sourceInfo.messageId.id], randomId: [uniqueId], toPeer: inputPeer, topMsgId: topMsgId, scheduleDate: scheduleTime, sendAs: sendAsInputPeer, quickReplyShortcut: nil, videoTimestamp: videoTimestamp, allowPaidStars: nil), tag: dependencyTag)
+                        sendMessageRequest = network.request(Api.functions.messages.forwardMessages(flags: flags, fromPeer: sourceInputPeer, id: [sourceInfo.messageId.id], randomId: [uniqueId], toPeer: inputPeer, topMsgId: topMsgId, scheduleDate: scheduleTime, sendAs: sendAsInputPeer, quickReplyShortcut: nil, videoTimestamp: videoTimestamp, allowPaidStars: allowPaidStars), tag: dependencyTag)
                         |> map(NetworkRequestResult.result)
                     } else {
                         sendMessageRequest = .fail(MTRpcError(errorCode: 400, errorDescription: "internal"))
@@ -473,7 +485,7 @@ private func sendUploadedMessageContent(
                         }
                     }
                 
-                    sendMessageRequest = network.request(Api.functions.messages.sendInlineBotResult(flags: flags, peer: inputPeer, replyTo: replyTo, randomId: uniqueId, queryId: chatContextResult.queryId, id: chatContextResult.id, scheduleDate: scheduleTime, sendAs: sendAsInputPeer, quickReplyShortcut: nil, allowPaidStars: nil))
+                    sendMessageRequest = network.request(Api.functions.messages.sendInlineBotResult(flags: flags, peer: inputPeer, replyTo: replyTo, randomId: uniqueId, queryId: chatContextResult.queryId, id: chatContextResult.id, scheduleDate: scheduleTime, sendAs: sendAsInputPeer, quickReplyShortcut: nil, allowPaidStars: allowPaidStars))
                     |> map(NetworkRequestResult.result)
                 case .messageScreenshot:
                     let replyTo: Api.InputReplyTo
@@ -585,6 +597,7 @@ private func sendMessageContent(account: Account, peerId: PeerId, attributes: [M
             var replyToStoryId: StoryId?
             var scheduleTime: Int32?
             var sendAsPeerId: PeerId?
+            var allowPaidStars: Int64?
             
             var flags: Int32 = 0
             flags |= (1 << 7)
@@ -609,6 +622,8 @@ private func sendMessageContent(account: Account, peerId: PeerId, attributes: [M
                     scheduleTime = attribute.scheduleTime
                 } else if let attribute = attribute as? SendAsMessageAttribute {
                     sendAsPeerId = attribute.peerId
+                } else if let attribute = attribute as? PaidStarsMessageAttribute {
+                    allowPaidStars = attribute.stars.value
                 }
             }
             
@@ -622,6 +637,11 @@ private func sendMessageContent(account: Account, peerId: PeerId, attributes: [M
                 flags |= (1 << 13)
             }
             
+            if let _ = allowPaidStars {
+                flags |= 1 << 21
+            }
+            
+            
             let sendMessageRequest: Signal<Api.Updates, NoError>
             switch content {
                 case let .text(text):
@@ -641,7 +661,7 @@ private func sendMessageContent(account: Account, peerId: PeerId, attributes: [M
                         replyTo = .inputReplyToMessage(flags: flags, replyToMsgId: threadId, topMsgId: threadId, replyToPeerId: nil, quoteText: nil, quoteEntities: nil, quoteOffset: nil)
                     }
                 
-                sendMessageRequest = account.network.request(Api.functions.messages.sendMessage(flags: flags, peer: inputPeer, replyTo: replyTo, message: text, randomId: uniqueId, replyMarkup: nil, entities: messageEntities, scheduleDate: scheduleTime, sendAs: sendAsInputPeer, quickReplyShortcut: nil, effect: nil, allowPaidStars: nil))
+                sendMessageRequest = account.network.request(Api.functions.messages.sendMessage(flags: flags, peer: inputPeer, replyTo: replyTo, message: text, randomId: uniqueId, replyMarkup: nil, entities: messageEntities, scheduleDate: scheduleTime, sendAs: sendAsInputPeer, quickReplyShortcut: nil, effect: nil, allowPaidStars: allowPaidStars))
                     |> `catch` { _ -> Signal<Api.Updates, NoError> in
                         return .complete()
                     }
@@ -662,7 +682,7 @@ private func sendMessageContent(account: Account, peerId: PeerId, attributes: [M
                         replyTo = .inputReplyToMessage(flags: flags, replyToMsgId: threadId, topMsgId: threadId, replyToPeerId: nil, quoteText: nil, quoteEntities: nil, quoteOffset: nil)
                     }
                 
-                    sendMessageRequest = account.network.request(Api.functions.messages.sendMedia(flags: flags, peer: inputPeer, replyTo: replyTo, media: inputMedia, message: text, randomId: uniqueId, replyMarkup: nil, entities: messageEntities, scheduleDate: scheduleTime, sendAs: sendAsInputPeer, quickReplyShortcut: nil, effect: nil, allowPaidStars: nil))
+                    sendMessageRequest = account.network.request(Api.functions.messages.sendMedia(flags: flags, peer: inputPeer, replyTo: replyTo, media: inputMedia, message: text, randomId: uniqueId, replyMarkup: nil, entities: messageEntities, scheduleDate: scheduleTime, sendAs: sendAsInputPeer, quickReplyShortcut: nil, effect: nil, allowPaidStars: allowPaidStars))
                     |> `catch` { _ -> Signal<Api.Updates, NoError> in
                         return .complete()
                     }
diff --git a/submodules/TelegramCore/Sources/SyncCore/SyncCore_CachedChannelData.swift b/submodules/TelegramCore/Sources/SyncCore/SyncCore_CachedChannelData.swift
index 45408d889e..89e671f7f9 100644
--- a/submodules/TelegramCore/Sources/SyncCore/SyncCore_CachedChannelData.swift
+++ b/submodules/TelegramCore/Sources/SyncCore/SyncCore_CachedChannelData.swift
@@ -25,6 +25,7 @@ public struct CachedChannelFlags: OptionSet {
     public static let paidMediaAllowed = CachedChannelFlags(rawValue: 1 << 11)
     public static let canViewStarsRevenue = CachedChannelFlags(rawValue: 1 << 12)
     public static let starGiftsAvailable = CachedChannelFlags(rawValue: 1 << 13)
+    public static let paidMessagesAvailable = CachedChannelFlags(rawValue: 1 << 14)
 }
 
 public struct CachedChannelParticipantsSummary: PostboxCoding, Equatable {
diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Data/PeersData.swift b/submodules/TelegramCore/Sources/TelegramEngine/Data/PeersData.swift
index 71ed10b3ac..5242e9432f 100644
--- a/submodules/TelegramCore/Sources/TelegramEngine/Data/PeersData.swift
+++ b/submodules/TelegramCore/Sources/TelegramEngine/Data/PeersData.swift
@@ -375,22 +375,18 @@ public extension TelegramEngine.EngineData.Item {
             }
 
             var key: PostboxViewKey {
-                return .cachedPeerData(peerId: self.id)
+                return .peer(peerId: self.id, components: [.cachedData])
             }
 
             func extract(view: PostboxView) -> Result {
-                guard let view = view as? CachedPeerDataView else {
+                guard let view = view as? PeerView else {
                     preconditionFailure()
                 }
-                guard let cachedPeerData = view.cachedPeerData else {
-                    return nil
-                }
-                switch cachedPeerData {
-                case let user as CachedUserData:
-                    return user.sendPaidMessageStars
-                case let channel as CachedChannelData:
+                if let cachedPeerData = view.cachedData as? CachedUserData {
+                    return cachedPeerData.sendPaidMessageStars
+                } else if let channel = peerViewMainPeer(view) as? TelegramChannel {
                     return channel.sendPaidMessageStars
-                default:
+                } else {
                     return nil
                 }
             }
diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Messages/OutgoingMessageWithChatContextResult.swift b/submodules/TelegramCore/Sources/TelegramEngine/Messages/OutgoingMessageWithChatContextResult.swift
index c93f33e990..3302c7fafd 100644
--- a/submodules/TelegramCore/Sources/TelegramEngine/Messages/OutgoingMessageWithChatContextResult.swift
+++ b/submodules/TelegramCore/Sources/TelegramEngine/Messages/OutgoingMessageWithChatContextResult.swift
@@ -2,15 +2,15 @@ import Foundation
 import Postbox
 import SwiftSignalKit
 
-func _internal_enqueueOutgoingMessageWithChatContextResult(account: Account, to peerId: PeerId, threadId: Int64?, botId: PeerId, result: ChatContextResult, replyToMessageId: EngineMessageReplySubject?, replyToStoryId: StoryId?, hideVia: Bool, silentPosting: Bool, scheduleTime: Int32?, correlationId: Int64?) -> Bool {
-    guard let message = _internal_outgoingMessageWithChatContextResult(to: peerId, threadId: threadId, botId: botId, result: result, replyToMessageId: replyToMessageId, replyToStoryId: replyToStoryId, hideVia: hideVia, silentPosting: silentPosting, scheduleTime: scheduleTime, correlationId: correlationId) else {
+func _internal_enqueueOutgoingMessageWithChatContextResult(account: Account, to peerId: PeerId, threadId: Int64?, botId: PeerId, result: ChatContextResult, replyToMessageId: EngineMessageReplySubject?, replyToStoryId: StoryId?, hideVia: Bool, silentPosting: Bool, scheduleTime: Int32?, sendPaidMessageStars: StarsAmount?, postpone: Bool, correlationId: Int64?) -> Bool {
+    guard let message = _internal_outgoingMessageWithChatContextResult(to: peerId, threadId: threadId, botId: botId, result: result, replyToMessageId: replyToMessageId, replyToStoryId: replyToStoryId, hideVia: hideVia, silentPosting: silentPosting, scheduleTime: scheduleTime, sendPaidMessageStars: sendPaidMessageStars, postpone: postpone, correlationId: correlationId) else {
         return false
     }
     let _ = enqueueMessages(account: account, peerId: peerId, messages: [message]).start()
     return true
 }
 
-func _internal_outgoingMessageWithChatContextResult(to peerId: PeerId, threadId: Int64?, botId: PeerId, result: ChatContextResult, replyToMessageId: EngineMessageReplySubject?, replyToStoryId: StoryId?, hideVia: Bool, silentPosting: Bool, scheduleTime: Int32?, correlationId: Int64?) -> EnqueueMessage? {
+func _internal_outgoingMessageWithChatContextResult(to peerId: PeerId, threadId: Int64?, botId: PeerId, result: ChatContextResult, replyToMessageId: EngineMessageReplySubject?, replyToStoryId: StoryId?, hideVia: Bool, silentPosting: Bool, scheduleTime: Int32?, sendPaidMessageStars: StarsAmount?, postpone: Bool, correlationId: Int64?) -> EnqueueMessage? {
     var replyToMessageId = replyToMessageId
     if replyToMessageId == nil, let threadId = threadId {
         replyToMessageId = EngineMessageReplySubject(messageId: MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: MessageId.Id(clamping: threadId)), quote: nil)
@@ -32,6 +32,9 @@ func _internal_outgoingMessageWithChatContextResult(to peerId: PeerId, threadId:
     if silentPosting {
         attributes.append(NotificationInfoMessageAttribute(flags: .muted))
     }
+    if let sendPaidMessageStars {
+        attributes.append(PaidStarsMessageAttribute(stars: sendPaidMessageStars, postponeSending: postpone))
+    }
     switch result.message {
     case let .auto(caption, entities, replyMarkup):
         if let entities = entities {
diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Messages/TelegramEngineMessages.swift b/submodules/TelegramCore/Sources/TelegramEngine/Messages/TelegramEngineMessages.swift
index cda12a4577..2ae4018184 100644
--- a/submodules/TelegramCore/Sources/TelegramEngine/Messages/TelegramEngineMessages.swift
+++ b/submodules/TelegramCore/Sources/TelegramEngine/Messages/TelegramEngineMessages.swift
@@ -247,13 +247,14 @@ public extension TelegramEngine {
             storyId: StoryId? = nil,
             content: EngineOutgoingMessageContent,
             silentPosting: Bool = false,
-            scheduleTime: Int32? = nil
+            scheduleTime: Int32? = nil,
+            sendPaidMessageStars: StarsAmount? = nil
         ) -> Signal<[MessageId?], NoError> {
             var message: EnqueueMessage?
             if case let .preparedInlineMessage(preparedInlineMessage) = content {
-                message = self.outgoingMessageWithChatContextResult(to: peerId, threadId: nil, botId: preparedInlineMessage.botId, result: preparedInlineMessage.result, replyToMessageId: replyToMessageId, replyToStoryId: storyId, hideVia: true, silentPosting: silentPosting, scheduleTime: scheduleTime, correlationId: nil)
+                message = self.outgoingMessageWithChatContextResult(to: peerId, threadId: nil, botId: preparedInlineMessage.botId, result: preparedInlineMessage.result, replyToMessageId: replyToMessageId, replyToStoryId: storyId, hideVia: true, silentPosting: silentPosting, scheduleTime: scheduleTime, sendPaidMessageStars: sendPaidMessageStars, postpone: false, correlationId: nil)
             } else if case let .contextResult(results, result) = content {
-                message = self.outgoingMessageWithChatContextResult(to: peerId, threadId: nil, botId: results.botId, result: result, replyToMessageId: replyToMessageId, replyToStoryId: storyId, hideVia: true, silentPosting: silentPosting, scheduleTime: scheduleTime, correlationId: nil)
+                message = self.outgoingMessageWithChatContextResult(to: peerId, threadId: nil, botId: results.botId, result: result, replyToMessageId: replyToMessageId, replyToStoryId: storyId, hideVia: true, silentPosting: silentPosting, scheduleTime: scheduleTime, sendPaidMessageStars: sendPaidMessageStars, postpone: false, correlationId: nil)
             } else {
                 var attributes: [MessageAttribute] = []
                 if silentPosting {
@@ -262,6 +263,9 @@ public extension TelegramEngine {
                 if let scheduleTime = scheduleTime {
                      attributes.append(OutgoingScheduleInfoMessageAttribute(scheduleTime: scheduleTime))
                 }
+                if let sendPaidMessageStars {
+                    attributes.append(PaidStarsMessageAttribute(stars: sendPaidMessageStars, postponeSending: false))
+                }
                 
                 var text: String = ""
                 var mediaReference: AnyMediaReference?
@@ -301,12 +305,12 @@ public extension TelegramEngine {
             )
         }
 
-        public func enqueueOutgoingMessageWithChatContextResult(to peerId: PeerId, threadId: Int64?, botId: PeerId, result: ChatContextResult, replyToMessageId: EngineMessageReplySubject? = nil, replyToStoryId: StoryId? = nil, hideVia: Bool = false, silentPosting: Bool = false, scheduleTime: Int32? = nil, correlationId: Int64? = nil) -> Bool {
-            return _internal_enqueueOutgoingMessageWithChatContextResult(account: self.account, to: peerId, threadId: threadId, botId: botId, result: result, replyToMessageId: replyToMessageId, replyToStoryId: replyToStoryId, hideVia: hideVia, silentPosting: silentPosting, scheduleTime: scheduleTime, correlationId: correlationId)
+        public func enqueueOutgoingMessageWithChatContextResult(to peerId: PeerId, threadId: Int64?, botId: PeerId, result: ChatContextResult, replyToMessageId: EngineMessageReplySubject? = nil, replyToStoryId: StoryId? = nil, hideVia: Bool = false, silentPosting: Bool = false, scheduleTime: Int32? = nil, sendPaidMessageStars: StarsAmount?, postpone: Bool = false, correlationId: Int64? = nil) -> Bool {
+            return _internal_enqueueOutgoingMessageWithChatContextResult(account: self.account, to: peerId, threadId: threadId, botId: botId, result: result, replyToMessageId: replyToMessageId, replyToStoryId: replyToStoryId, hideVia: hideVia, silentPosting: silentPosting, scheduleTime: scheduleTime, sendPaidMessageStars: sendPaidMessageStars, postpone: postpone, correlationId: correlationId)
         }
         
-        public func outgoingMessageWithChatContextResult(to peerId: PeerId, threadId: Int64?, botId: PeerId, result: ChatContextResult, replyToMessageId: EngineMessageReplySubject?, replyToStoryId: StoryId?, hideVia: Bool, silentPosting: Bool, scheduleTime: Int32?, correlationId: Int64?) -> EnqueueMessage? {
-            return _internal_outgoingMessageWithChatContextResult(to: peerId, threadId: threadId, botId: botId, result: result, replyToMessageId: replyToMessageId, replyToStoryId: replyToStoryId, hideVia: hideVia, silentPosting: silentPosting, scheduleTime: scheduleTime, correlationId: correlationId)
+        public func outgoingMessageWithChatContextResult(to peerId: PeerId, threadId: Int64?, botId: PeerId, result: ChatContextResult, replyToMessageId: EngineMessageReplySubject?, replyToStoryId: StoryId?, hideVia: Bool, silentPosting: Bool, scheduleTime: Int32?, sendPaidMessageStars: StarsAmount?, postpone: Bool, correlationId: Int64?) -> EnqueueMessage? {
+            return _internal_outgoingMessageWithChatContextResult(to: peerId, threadId: threadId, botId: botId, result: result, replyToMessageId: replyToMessageId, replyToStoryId: replyToStoryId, hideVia: hideVia, silentPosting: silentPosting, scheduleTime: scheduleTime, sendPaidMessageStars: sendPaidMessageStars, postpone: postpone, correlationId: correlationId)
         }
         
         public func setMessageReactions(
diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Payments/StarGifts.swift b/submodules/TelegramCore/Sources/TelegramEngine/Payments/StarGifts.swift
index 4f4c241a45..653c79d8f4 100644
--- a/submodules/TelegramCore/Sources/TelegramEngine/Payments/StarGifts.swift
+++ b/submodules/TelegramCore/Sources/TelegramEngine/Payments/StarGifts.swift
@@ -1064,7 +1064,8 @@ private final class ProfileGiftsContextImpl {
                     }
                     return postbox.transaction { transaction -> ([ProfileGiftsContext.State.StarGift], Int32, String?, Bool?) in
                         switch result {
-                        case let .savedStarGifts(_, count, apiNotificationsEnabled, apiGifts, nextOffset, chats, users):
+                        case let .savedStarGifts(_, count, apiNotificationsEnabled, pinnedToTop, apiGifts, nextOffset, chats, users):
+                            let _ = pinnedToTop
                             let parsedPeers = AccumulatedPeers(transaction: transaction, chats: chats, users: users)
                             updatePeers(transaction: transaction, accountPeerId: accountPeerId, peers: parsedPeers)
                             
diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Peers/AddPeerMember.swift b/submodules/TelegramCore/Sources/TelegramEngine/Peers/AddPeerMember.swift
index 27ad703429..d303743a59 100644
--- a/submodules/TelegramCore/Sources/TelegramEngine/Peers/AddPeerMember.swift
+++ b/submodules/TelegramCore/Sources/TelegramEngine/Peers/AddPeerMember.swift
@@ -99,8 +99,8 @@ func _internal_addGroupMember(account: Account, peerId: PeerId, memberId: PeerId
                                 }
                             })
                         }
-                        
-                        return TelegramInvitePeersResult(forbiddenPeers: missingInviteesValue.compactMap { invitee -> TelegramForbiddenInvitePeer? in
+                                                
+                        let result = TelegramInvitePeersResult(forbiddenPeers: missingInviteesValue.compactMap { invitee -> TelegramForbiddenInvitePeer? in
                             switch invitee {
                             case let .missingInvitee(flags, userId):
                                 guard let peer = transaction.getPeer(PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId))) else {
@@ -113,6 +113,10 @@ func _internal_addGroupMember(account: Account, peerId: PeerId, memberId: PeerId
                                 )
                             }
                         })
+                        
+                        let _ = _internal_updateIsPremiumRequiredToContact(account: account, peerIds: result.forbiddenPeers.map { $0.peer.id }).startStandalone()
+                        
+                        return result
                     }
                     |> mapError { _ -> AddGroupMemberError in }
                     |> mapToSignal { result -> Signal<Void, AddGroupMemberError> in
@@ -186,6 +190,8 @@ func _internal_addChannelMember(account: Account, peerId: PeerId, memberId: Peer
                         switch result {
                         case let .invitedUsers(updates, missingInvitees):
                             if case let .missingInvitee(flags, _) = missingInvitees.first {
+                                let _ = _internal_updateIsPremiumRequiredToContact(account: account, peerIds: [memberPeer.id]).startStandalone()
+                                
                                 return .fail(.restricted(TelegramForbiddenInvitePeer(
                                     peer: EnginePeer(memberPeer),
                                     canInviteWithPremium: (flags & (1 << 0)) != 0,
@@ -302,7 +308,7 @@ func _internal_addChannelMembers(account: Account, peerId: PeerId, memberIds: [P
                 account.viewTracker.forceUpdateCachedPeerData(peerId: peerId)
                 
                 return account.postbox.transaction { transaction -> TelegramInvitePeersResult in
-                    return TelegramInvitePeersResult(forbiddenPeers: missingInviteesValue.compactMap { invitee -> TelegramForbiddenInvitePeer? in
+                    let result = TelegramInvitePeersResult(forbiddenPeers: missingInviteesValue.compactMap { invitee -> TelegramForbiddenInvitePeer? in
                         switch invitee {
                         case let .missingInvitee(flags, userId):
                             guard let peer = transaction.getPeer(PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId))) else {
@@ -315,6 +321,8 @@ func _internal_addChannelMembers(account: Account, peerId: PeerId, memberIds: [P
                             )
                         }
                     })
+                    let _ = _internal_updateIsPremiumRequiredToContact(account: account, peerIds: result.forbiddenPeers.map { $0.peer.id }).startStandalone()
+                    return result
                 }
                 |> castError(AddChannelMemberError.self)
             }
diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Peers/UpdateCachedPeerData.swift b/submodules/TelegramCore/Sources/TelegramEngine/Peers/UpdateCachedPeerData.swift
index c21d258bb2..9c68e06e69 100644
--- a/submodules/TelegramCore/Sources/TelegramEngine/Peers/UpdateCachedPeerData.swift
+++ b/submodules/TelegramCore/Sources/TelegramEngine/Peers/UpdateCachedPeerData.swift
@@ -620,6 +620,10 @@ func _internal_fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPee
                                             if (flags2 & Int32(1 << 19)) != 0 {
                                                 channelFlags.insert(.starGiftsAvailable)
                                             }
+                                            if (flags2 & Int32(1 << 20)) != 0 {
+                                                channelFlags.insert(.paidMessagesAvailable)
+                                            }
+                                        
                                             let sendAsPeerId = defaultSendAs?.peerId
                                             
                                             let linkedDiscussionPeerId: PeerId?
diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageBubbleItemNode/Sources/ChatMessageBubbleItemNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageBubbleItemNode/Sources/ChatMessageBubbleItemNode.swift
index 67f242a7ef..11c5a8cc1b 100644
--- a/submodules/TelegramUI/Components/Chat/ChatMessageBubbleItemNode/Sources/ChatMessageBubbleItemNode.swift
+++ b/submodules/TelegramUI/Components/Chat/ChatMessageBubbleItemNode/Sources/ChatMessageBubbleItemNode.swift
@@ -2877,7 +2877,7 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
                             bottomBubbleAttributes = contentPropertiesAndLayouts[i + 1].3
                         }
 
-                        if i == 0 {
+                        if i == 0 || (i == 1 && contentPropertiesAndLayouts[0].1.isDetached) {
                             topPosition = firstNodeTopPosition
                         } else {
                             topPosition = .Neighbour(topBubbleAttributes.isAttachment, topBubbleAttributes.neighborType, topBubbleAttributes.neighborSpacing)
@@ -3002,11 +3002,7 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
                 }
                 
                 let (size, apply) = finalize(maxContentWidth)
-                var containerFrame = CGRect(origin: CGPoint(x: 0.0, y: contentNodeOriginY), size: size)
-                if size.height == 33.0 && detachedContentNodesHeight > 0.0 {
-                    //TODO:unmock
-                    containerFrame = containerFrame.offsetBy(dx: 0.0, dy: 2.0)
-                }
+                let containerFrame = CGRect(origin: CGPoint(x: 0.0, y: contentNodeOriginY), size: size)
                 contentNodeFramesPropertiesAndApply.append((containerFrame, properties, contentGroupId == nil, apply))
                 
                 if contentProperties.neighborType == .media && unlockButtonPosition == nil {
diff --git a/submodules/TelegramUI/Components/Chat/ChatMessagePaymentAlertController/Sources/ChatMessagePaymentAlertController.swift b/submodules/TelegramUI/Components/Chat/ChatMessagePaymentAlertController/Sources/ChatMessagePaymentAlertController.swift
index 26dd0e00ff..ec77b0a7c1 100644
--- a/submodules/TelegramUI/Components/Chat/ChatMessagePaymentAlertController/Sources/ChatMessagePaymentAlertController.swift
+++ b/submodules/TelegramUI/Components/Chat/ChatMessagePaymentAlertController/Sources/ChatMessagePaymentAlertController.swift
@@ -328,23 +328,34 @@ private class ChatMessagePaymentAlertController: AlertController {
         self.context = context
         self.presentationData = presentationData
         self.parentNavigationController = navigationController
-        
+    
         super.init(theme: AlertControllerTheme(presentationData: presentationData), contentNode: contentNode)
+        
+        self.willDismiss = { [weak self] in
+            guard let self else {
+                return
+            }
+            self.animateOut()
+        }
     }
         
     required public init(coder aDecoder: NSCoder) {
         preconditionFailure()
     }
     
-    override func dismissAnimated() {
-        super.dismissAnimated()
-        
+    private func animateOut() {
         if let view = self.balance.view {
             view.layer.animateScale(from: 1.0, to: 0.8, duration: 0.4, removeOnCompletion: false)
             view.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, removeOnCompletion: false)
         }
     }
     
+    override func dismissAnimated() {
+        super.dismissAnimated()
+        
+        self.animateOut()
+    }
+    
     override func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
         super.containerLayoutUpdated(layout, transition: transition)
         
diff --git a/submodules/TelegramUI/Components/Chat/ChatUserInfoItem/Sources/ChatUserInfoItem.swift b/submodules/TelegramUI/Components/Chat/ChatUserInfoItem/Sources/ChatUserInfoItem.swift
index 3de9d47c32..ef8946b103 100644
--- a/submodules/TelegramUI/Components/Chat/ChatUserInfoItem/Sources/ChatUserInfoItem.swift
+++ b/submodules/TelegramUI/Components/Chat/ChatUserInfoItem/Sources/ChatUserInfoItem.swift
@@ -251,6 +251,9 @@ public final class ChatUserInfoItemNode: ListViewItemNode {
             
             let infoConstrainedSize = CGSize(width: constrainedWidth * 0.7, height: CGFloat.greatestFiniteMagnitude)
             
+            var maxTitleWidth: CGFloat = 0.0
+            var maxValueWidth: CGFloat = 0.0
+            
             var registrationDateText: String?
             let registrationDateTitleLayoutAndApply: (TextNodeLayout, () -> TextNode)?
             let registrationDateValueLayoutAndApply: (TextNodeLayout, () -> TextNode)?
@@ -272,7 +275,8 @@ public final class ChatUserInfoItemNode: ListViewItemNode {
                 backgroundSize.height += verticalSpacing
                 backgroundSize.height += registrationDateValueLayoutAndApply?.0.size.height ?? 0
                 
-                backgroundSize.width = max(backgroundSize.width, horizontalContentInset * 2.0 + (registrationDateTitleLayoutAndApply?.0.size.width ?? 0) + attributeSpacing + (registrationDateValueLayoutAndApply?.0.size.width ?? 0))
+                maxTitleWidth = max(maxTitleWidth, (registrationDateTitleLayoutAndApply?.0.size.width ?? 0))
+                maxValueWidth = max(maxValueWidth, (registrationDateValueLayoutAndApply?.0.size.width ?? 0))
             } else {
                 registrationDateTitleLayoutAndApply = nil
                 registrationDateValueLayoutAndApply = nil
@@ -297,7 +301,8 @@ public final class ChatUserInfoItemNode: ListViewItemNode {
                 backgroundSize.height += verticalSpacing
                 backgroundSize.height += phoneCountryValueLayoutAndApply?.0.size.height ?? 0
                 
-                backgroundSize.width = max(backgroundSize.width, horizontalContentInset * 2.0 + (phoneCountryTitleLayoutAndApply?.0.size.width ?? 0) + attributeSpacing + (phoneCountryValueLayoutAndApply?.0.size.width ?? 0))
+                maxTitleWidth = max(maxTitleWidth, (phoneCountryTitleLayoutAndApply?.0.size.width ?? 0))
+                maxValueWidth = max(maxValueWidth, (phoneCountryValueLayoutAndApply?.0.size.width ?? 0))
             } else {
                 phoneCountryTitleLayoutAndApply = nil
                 phoneCountryValueLayoutAndApply = nil
@@ -322,12 +327,15 @@ public final class ChatUserInfoItemNode: ListViewItemNode {
                 backgroundSize.height += verticalSpacing
                 backgroundSize.height += locationCountryValueLayoutAndApply?.0.size.height ?? 0
                 
-                backgroundSize.width = max(backgroundSize.width, horizontalContentInset * 2.0 + (locationCountryTitleLayoutAndApply?.0.size.width ?? 0) + attributeSpacing + (locationCountryValueLayoutAndApply?.0.size.width ?? 0))
+                maxTitleWidth = max(maxTitleWidth, (locationCountryTitleLayoutAndApply?.0.size.width ?? 0))
+                maxValueWidth = max(maxValueWidth, (locationCountryValueLayoutAndApply?.0.size.width ?? 0))
             } else {
                 locationCountryTitleLayoutAndApply = nil
                 locationCountryValueLayoutAndApply = nil
             }
             
+            backgroundSize.width = horizontalContentInset * 3.0 + maxTitleWidth + attributeSpacing + maxValueWidth
+            
             let (groupsLayout, groupsApply) = makeGroupsLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: "No groups in common", font: Font.regular(13.0), textColor: subtitleColor), backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: constrainedWidth, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
             backgroundSize.height += verticalSpacing * 2.0 + paragraphSpacing
             backgroundSize.height += groupsLayout.size.height
diff --git a/submodules/TelegramUI/Components/Gifts/GiftOptionsScreen/Sources/GiftOptionsScreen.swift b/submodules/TelegramUI/Components/Gifts/GiftOptionsScreen/Sources/GiftOptionsScreen.swift
index ee6a362431..d45f5fc0b9 100644
--- a/submodules/TelegramUI/Components/Gifts/GiftOptionsScreen/Sources/GiftOptionsScreen.swift
+++ b/submodules/TelegramUI/Components/Gifts/GiftOptionsScreen/Sources/GiftOptionsScreen.swift
@@ -502,9 +502,7 @@ final class GiftOptionsScreenComponent: Component {
                 return
             }
             
-            //TODO:unmock
             let context = component.context
-            
             let alertController = giftTransferAlertController(
                 context: context,
                 gift: transferGift,
@@ -517,36 +515,53 @@ final class GiftOptionsScreenComponent: Component {
                     guard let controller, let navigationController = controller.navigationController as? NavigationController else {
                         return
                     }
-                    var controllers = navigationController.viewControllers
-                    controllers = controllers.filter { !($0 is ContactSelectionController) && !($0 is GiftOptionsScreen) }
+                     
                     if peer.id.namespace == Namespaces.Peer.CloudChannel {
-                        if let controller = context.sharedContext.makePeerInfoController(
-                            context: context,
-                            updatedPresentationData: nil,
-                            peer: peer._asPeer(),
-                            mode: .gifts,
-                            avatarInitiallyExpanded: false,
-                            fromChat: false,
-                            requestsContext: nil
-                        ) {
-                            controllers.append(controller)
-                        }
-                    } else {
+                        var controllers = navigationController.viewControllers
+                        controllers = controllers.filter { !($0 is GiftSetupScreen) && !($0 is GiftOptionsScreenProtocol) }
                         var foundController = false
                         for controller in controllers.reversed() {
-                            if let chatController = controller as? ChatController, case .peer(id: peer.id) = chatController.chatLocation {
+                            if let controller = controller as? PeerInfoScreen, controller.peerId == component.peerId {
+                                foundController = true
+                                break
+                            }
+                        }
+                        if !foundController {
+                            if let controller = context.sharedContext.makePeerInfoController(
+                                context: context,
+                                updatedPresentationData: nil,
+                                peer: peer._asPeer(),
+                                mode: .gifts,
+                                avatarInitiallyExpanded: false,
+                                fromChat: false,
+                                requestsContext: nil
+                            ) {
+                                controllers.append(controller)
+                            }
+                        }
+                        navigationController.setViewControllers(controllers, animated: true)
+                    } else {
+                        var controllers = navigationController.viewControllers
+                        controllers = controllers.filter { !($0 is GiftSetupScreen) && !($0 is GiftOptionsScreenProtocol) && !($0 is PeerInfoScreen) && !($0 is ContactSelectionController) }
+                        var foundController = false
+                        for controller in controllers.reversed() {
+                            if let chatController = controller as? ChatController, case .peer(id: component.peerId) = chatController.chatLocation {
                                 chatController.hintPlayNextOutgoingGift()
                                 foundController = true
                                 break
                             }
                         }
                         if !foundController {
-                            let chatController = context.sharedContext.makeChatController(context: context, chatLocation: .peer(id: peer.id), subject: nil, botStart: nil, mode: .standard(.default), params: nil)
+                            let chatController = component.context.sharedContext.makeChatController(context: component.context, chatLocation: .peer(id: component.peerId), subject: nil, botStart: nil, mode: .standard(.default), params: nil)
                             chatController.hintPlayNextOutgoingGift()
                             controllers.append(chatController)
                         }
+                        navigationController.setViewControllers(controllers, animated: true)
+                    }
+                
+                    if let completion = component.completion {
+                        completion()
                     }
-                    navigationController.setViewControllers(controllers, animated: true)
                 }
             )
             controller.present(alertController, in: .window(.root))
diff --git a/submodules/TelegramUI/Components/LegacyCamera/Sources/LegacyCamera.swift b/submodules/TelegramUI/Components/LegacyCamera/Sources/LegacyCamera.swift
index 7d8aa898ee..be2b344db3 100644
--- a/submodules/TelegramUI/Components/LegacyCamera/Sources/LegacyCamera.swift
+++ b/submodules/TelegramUI/Components/LegacyCamera/Sources/LegacyCamera.swift
@@ -253,7 +253,7 @@ public func presentedLegacyShortcutCamera(context: AccountContext, saveCapturedM
                 nativeGenerator(_1, _2, _3, nil)
             })
             if let parentController = parentController {
-                parentController.present(ShareController(context: context, subject: .fromExternal({ peerIds, _, text, account, silently in
+                parentController.present(ShareController(context: context, subject: .fromExternal(1, { peerIds, _, _, text, account, silently in
                     guard let account = account as? ShareControllerAppAccountContext else {
                         return .single(.done)
                     }
diff --git a/submodules/TelegramUI/Components/LegacyMessageInputPanel/Sources/LegacyMessageInputPanel.swift b/submodules/TelegramUI/Components/LegacyMessageInputPanel/Sources/LegacyMessageInputPanel.swift
index 79423fca6d..a0a6034849 100644
--- a/submodules/TelegramUI/Components/LegacyMessageInputPanel/Sources/LegacyMessageInputPanel.swift
+++ b/submodules/TelegramUI/Components/LegacyMessageInputPanel/Sources/LegacyMessageInputPanel.swift
@@ -214,6 +214,7 @@ public class LegacyMessageInputPanelNode: ASDisplayNode, TGCaptionPanelView {
                     strings: presentationData.strings,
                     style: .media,
                     placeholder: .plain(presentationData.strings.MediaPicker_AddCaption),
+                    sendPaidMessageStars: nil,
                     maxLength: Int(self.context.userLimits.maxCaptionLength),
                     queryTypes: [.mention, .hashtag],
                     alwaysDarkWhenHasText: false,
diff --git a/submodules/TelegramUI/Components/MediaEditorScreen/Sources/MediaEditorScreen.swift b/submodules/TelegramUI/Components/MediaEditorScreen/Sources/MediaEditorScreen.swift
index 15b3ca4613..86ed3d9a89 100644
--- a/submodules/TelegramUI/Components/MediaEditorScreen/Sources/MediaEditorScreen.swift
+++ b/submodules/TelegramUI/Components/MediaEditorScreen/Sources/MediaEditorScreen.swift
@@ -1365,6 +1365,7 @@ final class MediaEditorScreenComponent: Component {
                         strings: environment.strings,
                         style: .editor,
                         placeholder: .plain(environment.strings.Story_Editor_InputPlaceholderAddCaption),
+                        sendPaidMessageStars: nil,
                         maxLength: Int(component.context.userLimits.maxStoryCaptionLength),
                         queryTypes: [.mention, .hashtag],
                         alwaysDarkWhenHasText: false,
diff --git a/submodules/TelegramUI/Components/MediaEditorScreen/Sources/StoryPreviewComponent.swift b/submodules/TelegramUI/Components/MediaEditorScreen/Sources/StoryPreviewComponent.swift
index 569e8f4273..900b4f8ba0 100644
--- a/submodules/TelegramUI/Components/MediaEditorScreen/Sources/StoryPreviewComponent.swift
+++ b/submodules/TelegramUI/Components/MediaEditorScreen/Sources/StoryPreviewComponent.swift
@@ -251,6 +251,7 @@ final class StoryPreviewComponent: Component {
                     strings: presentationData.strings,
                     style: .story,
                     placeholder: .plain(presentationData.strings.Story_InputPlaceholderReplyPrivately),
+                    sendPaidMessageStars: nil,
                     maxLength: nil,
                     queryTypes: [],
                     alwaysDarkWhenHasText: false,
diff --git a/submodules/TelegramUI/Components/MessageInputPanelComponent/Sources/MessageInputPanelComponent.swift b/submodules/TelegramUI/Components/MessageInputPanelComponent/Sources/MessageInputPanelComponent.swift
index 41b5f840ab..85a47443dd 100644
--- a/submodules/TelegramUI/Components/MessageInputPanelComponent/Sources/MessageInputPanelComponent.swift
+++ b/submodules/TelegramUI/Components/MessageInputPanelComponent/Sources/MessageInputPanelComponent.swift
@@ -160,6 +160,7 @@ public final class MessageInputPanelComponent: Component {
     public let strings: PresentationStrings
     public let style: Style
     public let placeholder: Placeholder
+    public let sendPaidMessageStars: StarsAmount?
     public let maxLength: Int?
     public let queryTypes: ContextQueryTypes
     public let alwaysDarkWhenHasText: Bool
@@ -218,6 +219,7 @@ public final class MessageInputPanelComponent: Component {
         strings: PresentationStrings,
         style: Style,
         placeholder: Placeholder,
+        sendPaidMessageStars: StarsAmount?,
         maxLength: Int?,
         queryTypes: ContextQueryTypes,
         alwaysDarkWhenHasText: Bool,
@@ -276,6 +278,7 @@ public final class MessageInputPanelComponent: Component {
         self.style = style
         self.nextInputMode = nextInputMode
         self.placeholder = placeholder
+        self.sendPaidMessageStars = sendPaidMessageStars
         self.maxLength = maxLength
         self.queryTypes = queryTypes
         self.alwaysDarkWhenHasText = alwaysDarkWhenHasText
@@ -346,6 +349,9 @@ public final class MessageInputPanelComponent: Component {
         if lhs.placeholder != rhs.placeholder {
             return false
         }
+        if lhs.sendPaidMessageStars != rhs.sendPaidMessageStars {
+            return false
+        }
         if lhs.maxLength != rhs.maxLength {
             return false
         }
@@ -849,43 +855,75 @@ public final class MessageInputPanelComponent: Component {
             )
             let isEditing = self.textFieldExternalState.isEditing || component.forceIsEditing
             
-            var placeholderItems: [AnimatedTextComponent.Item] = []
-            switch component.placeholder {
-            case let .plain(string):
-                placeholderItems.append(AnimatedTextComponent.Item(id: AnyHashable(0 as Int), content: .text(string)))
-            case let .counter(items):
-                for item in items {
-                    switch item.content {
-                    case let .text(string):
-                        placeholderItems.append(AnimatedTextComponent.Item(id: AnyHashable(item.id), content: .text(string)))
-                    case let .number(value, minDigits):
-                        placeholderItems.append(AnimatedTextComponent.Item(id: AnyHashable(item.id), content: .number(value, minDigits: minDigits)))
+            let placeholderTransition: ComponentTransition = (previousPlaceholder != nil && previousPlaceholder != component.placeholder) ? ComponentTransition(animation: .curve(duration: 0.3, curve: .spring)) : .immediate
+            let placeholderSize: CGSize
+            if case let .plain(string) = component.placeholder, string.contains("#") {
+                let attributedPlaceholder = NSMutableAttributedString(string: string, font:Font.regular(17.0), textColor: UIColor(rgb: 0xffffff, alpha: 0.3))
+                if let range = attributedPlaceholder.string.range(of: "#") {
+                    attributedPlaceholder.addAttribute(.attachment, value: PresentationResourcesChat.chatPlaceholderStarIcon(component.theme)!, range: NSRange(range, in: attributedPlaceholder.string))
+                    attributedPlaceholder.addAttribute(.foregroundColor, value: UIColor(rgb: 0xffffff, alpha: 0.3), range: NSRange(range, in: attributedPlaceholder.string))
+                    attributedPlaceholder.addAttribute(.baselineOffset, value: 1.0, range: NSRange(range, in: attributedPlaceholder.string))
+                }
+                
+                placeholderSize = self.placeholder.update(
+                    transition: placeholderTransition,
+                    component: AnyComponent(MultilineTextComponent(text: .plain(attributedPlaceholder))),
+                    environment: {},
+                    containerSize: availableTextFieldSize
+                )
+                
+                let vibrancyAttributedPlaceholder = NSMutableAttributedString(string: string, font:Font.regular(17.0), textColor: UIColor.black)
+                if let range = vibrancyAttributedPlaceholder.string.range(of: "#") {
+                    vibrancyAttributedPlaceholder.addAttribute(.attachment, value: PresentationResourcesChat.chatPlaceholderStarIcon(component.theme)!, range: NSRange(range, in: vibrancyAttributedPlaceholder.string))
+                    vibrancyAttributedPlaceholder.addAttribute(.foregroundColor, value: UIColor.black, range: NSRange(range, in: vibrancyAttributedPlaceholder.string))
+                    vibrancyAttributedPlaceholder.addAttribute(.baselineOffset, value: 1.0, range: NSRange(range, in: vibrancyAttributedPlaceholder.string))
+                }
+                
+                let _ = self.vibrancyPlaceholder.update(
+                    transition: placeholderTransition,
+                    component: AnyComponent(MultilineTextComponent(text: .plain(attributedPlaceholder))),
+                    environment: {},
+                    containerSize: availableTextFieldSize
+                )
+            } else {
+                var placeholderItems: [AnimatedTextComponent.Item] = []
+                switch component.placeholder {
+                case let .plain(string):
+                    placeholderItems.append(AnimatedTextComponent.Item(id: AnyHashable(0 as Int), content: .text(string)))
+                case let .counter(items):
+                    for item in items {
+                        switch item.content {
+                        case let .text(string):
+                            placeholderItems.append(AnimatedTextComponent.Item(id: AnyHashable(item.id), content: .text(string)))
+                        case let .number(value, minDigits):
+                            placeholderItems.append(AnimatedTextComponent.Item(id: AnyHashable(item.id), content: .number(value, minDigits: minDigits)))
+                        }
                     }
                 }
+                
+                placeholderSize = self.placeholder.update(
+                    transition: placeholderTransition,
+                    component: AnyComponent(AnimatedTextComponent(
+                        font: Font.regular(17.0),
+                        color: UIColor(rgb: 0xffffff, alpha: 0.3),
+                        items: placeholderItems
+                    )),
+                    environment: {},
+                    containerSize: availableTextFieldSize
+                )
+                
+                let _ = self.vibrancyPlaceholder.update(
+                    transition: placeholderTransition,
+                    component: AnyComponent(AnimatedTextComponent(
+                        font: Font.regular(17.0),
+                        color: .black,
+                        items: placeholderItems
+                    )),
+                    environment: {},
+                    containerSize: availableTextFieldSize
+                )
             }
             
-            let placeholderTransition: ComponentTransition = (previousPlaceholder != nil && previousPlaceholder != component.placeholder) ? ComponentTransition(animation: .curve(duration: 0.3, curve: .spring)) : .immediate
-            let placeholderSize = self.placeholder.update(
-                transition: placeholderTransition,
-                component: AnyComponent(AnimatedTextComponent(
-                    font: Font.regular(17.0),
-                    color: UIColor(rgb: 0xffffff, alpha: 0.3),
-                    items: placeholderItems
-                )),
-                environment: {},
-                containerSize: availableTextFieldSize
-            )
-            
-            let _ = self.vibrancyPlaceholder.update(
-                transition: placeholderTransition,
-                component: AnyComponent(AnimatedTextComponent(
-                    font: Font.regular(17.0),
-                    color: .black,
-                    items: placeholderItems
-                )),
-                environment: {},
-                containerSize: availableTextFieldSize
-            )
             if !isEditing && component.setMediaRecordingActive == nil {
                 insets.right = defaultInsets.left
             }
diff --git a/submodules/TelegramUI/Components/SendInviteLinkScreen/BUILD b/submodules/TelegramUI/Components/SendInviteLinkScreen/BUILD
index 0c0e555fad..e95817f52a 100644
--- a/submodules/TelegramUI/Components/SendInviteLinkScreen/BUILD
+++ b/submodules/TelegramUI/Components/SendInviteLinkScreen/BUILD
@@ -31,6 +31,7 @@ swift_library(
         "//submodules/PeerPresenceStatusManager",
         "//submodules/UndoUI",
         "//submodules/AnimatedAvatarSetNode",
+        "//submodules/TelegramUI/Components/Chat/ChatMessagePaymentAlertController",
     ],
     visibility = [
         "//visibility:public",
diff --git a/submodules/TelegramUI/Components/SendInviteLinkScreen/Sources/SendInviteLinkScreen.swift b/submodules/TelegramUI/Components/SendInviteLinkScreen/Sources/SendInviteLinkScreen.swift
index 158d1accb0..3dfb23c301 100644
--- a/submodules/TelegramUI/Components/SendInviteLinkScreen/Sources/SendInviteLinkScreen.swift
+++ b/submodules/TelegramUI/Components/SendInviteLinkScreen/Sources/SendInviteLinkScreen.swift
@@ -17,6 +17,7 @@ import UndoUI
 import AnimatedAvatarSetNode
 import AvatarNode
 import TelegramStringFormatting
+import ChatMessagePaymentAlertController
 
 private final class SendInviteLinkScreenComponent: Component {
     typealias EnvironmentType = ViewControllerComponentContainer.Environment
@@ -26,19 +27,22 @@ private final class SendInviteLinkScreenComponent: Component {
     let link: String?
     let peers: [TelegramForbiddenInvitePeer]
     let peerPresences: [EnginePeer.Id: EnginePeer.Presence]
+    let sendPaidMessageStars: [EnginePeer.Id: StarsAmount]
     
     init(
         context: AccountContext,
         peer: EnginePeer,
         link: String?,
         peers: [TelegramForbiddenInvitePeer],
-        peerPresences: [EnginePeer.Id: EnginePeer.Presence]
+        peerPresences: [EnginePeer.Id: EnginePeer.Presence],
+        sendPaidMessageStars: [EnginePeer.Id: StarsAmount]
     ) {
         self.context = context
         self.peer = peer
         self.link = link
         self.peers = peers
         self.peerPresences = peerPresences
+        self.sendPaidMessageStars = sendPaidMessageStars
     }
     
     static func ==(lhs: SendInviteLinkScreenComponent, rhs: SendInviteLinkScreenComponent) -> Bool {
@@ -54,6 +58,9 @@ private final class SendInviteLinkScreenComponent: Component {
         if lhs.peerPresences != rhs.peerPresences {
             return false
         }
+        if lhs.sendPaidMessageStars != rhs.sendPaidMessageStars {
+            return false
+        }
         return true
     }
     
@@ -266,6 +273,38 @@ private final class SendInviteLinkScreenComponent: Component {
             }
         }
         
+        private func presentPaidMessageAlertIfNeeded(peers: [EnginePeer], requiresStars: [EnginePeer.Id: StarsAmount], completion: @escaping () -> Void) {
+            guard let component = self.component else {
+                completion()
+                return
+            }
+            var totalAmount: StarsAmount = .zero
+            for peer in peers {
+                if let amount = requiresStars[peer.id] {
+                    totalAmount = totalAmount + amount
+                }
+            }
+            if totalAmount.value > 0 {
+                let controller = chatMessagePaymentAlertController(
+                    context: component.context,
+                    presentationData: component.context.sharedContext.currentPresentationData.with { $0 },
+                    updatedPresentationData: nil,
+                    peers: peers,
+                    count: 1,
+                    amount: totalAmount,
+                    totalAmount: totalAmount,
+                    hasCheck: false,
+                    navigationController: self.environment?.controller()?.navigationController as? NavigationController,
+                    completion: { _ in
+                        completion()
+                    }
+                )
+                self.environment?.controller()?.present(controller, in: .window(.root))
+            } else {
+                completion()
+            }
+        }
+        
         func update(component: SendInviteLinkScreenComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment<ViewControllerComponentContainer.Environment>, transition: ComponentTransition) -> CGSize {
             let environment = environment[ViewControllerComponentContainer.Environment.self].value
             let themeUpdated = self.environment?.theme !== environment.theme
@@ -851,20 +890,37 @@ private final class SendInviteLinkScreenComponent: Component {
                             } else if let link = component.link {
                                 let selectedPeers = component.peers.filter { self.selectedItems.contains($0.peer.id) }
                                 
-                                let _ = enqueueMessagesToMultiplePeers(account: component.context.account, peerIds: Array(self.selectedItems), threadIds: [:], messages: [.message(text: link, attributes: [], inlineStickers: [:], mediaReference: nil, threadId: nil, replyToMessageId: nil, replyToStoryId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])]).start()
-                                let text: String
-                                if selectedPeers.count == 1 {
-                                    text = environment.strings.Conversation_ShareLinkTooltip_Chat_One(selectedPeers[0].peer.displayTitle(strings: environment.strings, displayOrder: .firstLast).replacingOccurrences(of: "*", with: "")).string
-                                } else if selectedPeers.count == 2 {
-                                    text = environment.strings.Conversation_ShareLinkTooltip_TwoChats_One(selectedPeers[0].peer.displayTitle(strings: environment.strings, displayOrder: .firstLast).replacingOccurrences(of: "*", with: ""), selectedPeers[1].peer.displayTitle(strings: environment.strings, displayOrder: .firstLast).replacingOccurrences(of: "*", with: "")).string
-                                } else {
-                                    text = environment.strings.Conversation_ShareLinkTooltip_ManyChats_One(selectedPeers[0].peer.displayTitle(strings: environment.strings, displayOrder: .firstLast).replacingOccurrences(of: "*", with: ""), "\(selectedPeers.count - 1)").string
-                                }
-                                
-                                let presentationData = component.context.sharedContext.currentPresentationData.with { $0 }
-                                controller.present(UndoOverlayController(presentationData: presentationData, content: .forward(savedMessages: false, text: text), elevatedLayout: false, action: { _ in return false }), in: .window(.root))
-                                
-                                controller.dismiss()
+                                self.presentPaidMessageAlertIfNeeded(
+                                    peers: selectedPeers.map { $0.peer },
+                                    requiresStars: component.sendPaidMessageStars,
+                                    completion: { [weak self] in
+                                        guard let self, let component = self.component, let controller = self.environment?.controller() else {
+                                            return
+                                        }
+                                        
+                                        for peerId in Array(self.selectedItems) {
+                                            var messageAttributes: [EngineMessage.Attribute] = []
+                                            if let sendPaidMessageStars = component.sendPaidMessageStars[peerId] {
+                                                messageAttributes.append(PaidStarsMessageAttribute(stars: sendPaidMessageStars, postponeSending: false))
+                                            }
+                                            let _ = enqueueMessages(account: component.context.account, peerId: peerId, messages: [.message(text: link, attributes: messageAttributes, inlineStickers: [:], mediaReference: nil, threadId: nil, replyToMessageId: nil, replyToStoryId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])]).startStandalone()
+                                        }
+                                        
+                                        let text: String
+                                        if selectedPeers.count == 1 {
+                                            text = environment.strings.Conversation_ShareLinkTooltip_Chat_One(selectedPeers[0].peer.displayTitle(strings: environment.strings, displayOrder: .firstLast).replacingOccurrences(of: "*", with: "")).string
+                                        } else if selectedPeers.count == 2 {
+                                            text = environment.strings.Conversation_ShareLinkTooltip_TwoChats_One(selectedPeers[0].peer.displayTitle(strings: environment.strings, displayOrder: .firstLast).replacingOccurrences(of: "*", with: ""), selectedPeers[1].peer.displayTitle(strings: environment.strings, displayOrder: .firstLast).replacingOccurrences(of: "*", with: "")).string
+                                        } else {
+                                            text = environment.strings.Conversation_ShareLinkTooltip_ManyChats_One(selectedPeers[0].peer.displayTitle(strings: environment.strings, displayOrder: .firstLast).replacingOccurrences(of: "*", with: ""), "\(selectedPeers.count - 1)").string
+                                        }
+                                        
+                                        let presentationData = component.context.sharedContext.currentPresentationData.with { $0 }
+                                        controller.present(UndoOverlayController(presentationData: presentationData, content: .forward(savedMessages: false, text: text), elevatedLayout: false, action: { _ in return false }), in: .window(.root))
+                                        
+                                        controller.dismiss()
+                                    }
+                                )
                             } else {
                                 controller.dismiss()
                             }
@@ -1083,16 +1139,21 @@ public class SendInviteLinkScreen: ViewControllerComponentContainer {
         self.link = link
         self.peers = peers
         
-        super.init(context: context, component: SendInviteLinkScreenComponent(context: context, peer: peer, link: link, peers: peers, peerPresences: [:]), navigationBarAppearance: .none)
+        super.init(context: context, component: SendInviteLinkScreenComponent(context: context, peer: peer, link: link, peers: peers, peerPresences: [:], sendPaidMessageStars: [:]), navigationBarAppearance: .none)
         
         self.statusBar.statusBarStyle = .Ignore
         self.navigationPresentation = .flatModal
         self.blocksBackgroundWhenInOverlay = true
         
-        self.presenceDisposable = (context.engine.data.subscribe(EngineDataMap(
-            peers.map(\.peer.id).map(TelegramEngine.EngineData.Item.Peer.Presence.init(id:))
-        ))
-        |> deliverOnMainQueue).start(next: { [weak self] presences in
+        self.presenceDisposable = (context.engine.data.subscribe(
+            EngineDataMap(
+                peers.map(\.peer.id).map(TelegramEngine.EngineData.Item.Peer.Presence.init(id:))
+            ),
+            EngineDataMap(
+                peers.map(\.peer.id).map(TelegramEngine.EngineData.Item.Peer.SendPaidMessageStars.init(id:))
+            )
+        )
+        |> deliverOnMainQueue).start(next: { [weak self] presences, sendPaidMessageStars in
             guard let self else {
                 return
             }
@@ -1102,7 +1163,13 @@ public class SendInviteLinkScreen: ViewControllerComponentContainer {
                     parsedPresences[id] = presence
                 }
             }
-            self.updateComponent(component: AnyComponent(SendInviteLinkScreenComponent(context: context, peer: peer, link: link, peers: peers, peerPresences: parsedPresences)), transition: .immediate)
+            var parsedSendPaidMessageStars: [EnginePeer.Id: StarsAmount] = [:]
+            for (id, sendPaidMessageStars) in sendPaidMessageStars {
+                if let sendPaidMessageStars {
+                    parsedSendPaidMessageStars[id] = sendPaidMessageStars
+                }
+            }
+            self.updateComponent(component: AnyComponent(SendInviteLinkScreenComponent(context: context, peer: peer, link: link, peers: peers, peerPresences: parsedPresences, sendPaidMessageStars: parsedSendPaidMessageStars)), transition: .immediate)
         })
     }
     
diff --git a/submodules/TelegramUI/Components/ShareExtensionContext/Sources/ShareExtensionContext.swift b/submodules/TelegramUI/Components/ShareExtensionContext/Sources/ShareExtensionContext.swift
index f33b368637..a02526928e 100644
--- a/submodules/TelegramUI/Components/ShareExtensionContext/Sources/ShareExtensionContext.swift
+++ b/submodules/TelegramUI/Components/ShareExtensionContext/Sources/ShareExtensionContext.swift
@@ -525,8 +525,8 @@ public class ShareRootControllerImpl {
                             } |> runOn(Queue.mainQueue())
                         }
                         
-                        let sentItems: ([PeerId], [PeerId: Int64], [PreparedShareItemContent], ShareControllerAccountContext, Bool, String) -> Signal<ShareControllerExternalStatus, NoError> = { peerIds, threadIds, contents, account, silently, additionalText in
-                            let sentItems = sentShareItems(accountPeerId: account.accountPeerId, postbox: account.stateManager.postbox, network: account.stateManager.network, stateManager: account.stateManager, auxiliaryMethods: makeTelegramAccountAuxiliaryMethods(uploadInBackground: nil), to: peerIds, threadIds: threadIds, items: contents, silently: silently, additionalText: additionalText)
+                        let sentItems: ([PeerId], [PeerId: Int64], [PeerId: StarsAmount], [PreparedShareItemContent], ShareControllerAccountContext, Bool, String) -> Signal<ShareControllerExternalStatus, NoError> = { peerIds, threadIds, requireStars, contents, account, silently, additionalText in
+                            let sentItems = sentShareItems(accountPeerId: account.accountPeerId, postbox: account.stateManager.postbox, network: account.stateManager.network, stateManager: account.stateManager, auxiliaryMethods: makeTelegramAccountAuxiliaryMethods(uploadInBackground: nil), to: peerIds, threadIds: threadIds, requireStars: requireStars, items: contents, silently: silently, additionalText: additionalText)
                             |> `catch` { _ -> Signal<
                                 Float, NoError> in
                                 return .complete()
@@ -537,8 +537,20 @@ public class ShareRootControllerImpl {
                             }
                             |> then(.single(.done))
                         }
-                                            
-                        let shareController = ShareController(environment: environment, currentContext: context, subject: .fromExternal({ peerIds, threadIds, additionalText, account, silently in
+                         
+                        var itemCount = 1
+                        
+                        if let extensionItems = self?.getExtensionContext()?.inputItems as? [NSExtensionItem] {
+                            for item in extensionItems {
+                                if let attachments = item.attachments {
+                                    itemCount = 0
+                                    for _ in attachments {
+                                        itemCount += 1
+                                    }
+                                }
+                            }
+                        }
+                        let shareController = ShareController(environment: environment, currentContext: context, subject: .fromExternal(itemCount, { peerIds, threadIds, requireStars, additionalText, account, silently in
                             if let strongSelf = self, let inputItems = strongSelf.getExtensionContext()?.inputItems, !inputItems.isEmpty, !peerIds.isEmpty {
                                 let rawSignals = TGItemProviderSignals.itemSignals(forInputItems: inputItems)!
                                 return preparedShareItems(postbox: account.stateManager.postbox, network: account.stateManager.network, to: peerIds[0], dataItems: rawSignals)
@@ -564,11 +576,11 @@ public class ShareRootControllerImpl {
                                         return requestUserInteraction(value)
                                         |> castError(ShareControllerError.self)
                                         |> mapToSignal { contents -> Signal<ShareControllerExternalStatus, ShareControllerError> in
-                                            return sentItems(peerIds, threadIds, contents, account, silently, additionalText)
+                                            return sentItems(peerIds, threadIds, requireStars, contents, account, silently, additionalText)
                                             |> castError(ShareControllerError.self)
                                         }
                                     case let .done(contents):
-                                        return sentItems(peerIds, threadIds, contents, account, silently, additionalText)
+                                        return sentItems(peerIds, threadIds, requireStars, contents, account, silently, additionalText)
                                         |> castError(ShareControllerError.self)
                                     }
                                 }
diff --git a/submodules/TelegramUI/Components/Stars/StarsWithdrawalScreen/Sources/StarsWithdrawalScreen.swift b/submodules/TelegramUI/Components/Stars/StarsWithdrawalScreen/Sources/StarsWithdrawalScreen.swift
index 921272ce37..190070b927 100644
--- a/submodules/TelegramUI/Components/Stars/StarsWithdrawalScreen/Sources/StarsWithdrawalScreen.swift
+++ b/submodules/TelegramUI/Components/Stars/StarsWithdrawalScreen/Sources/StarsWithdrawalScreen.swift
@@ -124,9 +124,9 @@ private final class SheetContent: CombinedComponent {
                 minAmount = StarsAmount(value: 1, nanos: 0)
                 maxAmount = configuration.maxPaidMediaAmount.flatMap { StarsAmount(value: $0, nanos: 0) }
                 
-                var usdRate = 0.012
+                
                 if let usdWithdrawRate = configuration.usdWithdrawRate, let amount = state.amount, amount > StarsAmount.zero {
-                    usdRate = Double(usdWithdrawRate) / 1000.0 / 100.0
+                    let usdRate = Double(usdWithdrawRate) / 1000.0 / 100.0
                     amountLabel = "≈\(formatTonUsdValue(amount.value, divide: false, rate: usdRate, dateTimeFormat: environment.dateTimeFormat))"
                 } else {
                     amountLabel = nil
diff --git a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/BUILD b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/BUILD
index c923c845a9..540e1b1bc4 100644
--- a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/BUILD
+++ b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/BUILD
@@ -98,6 +98,7 @@ swift_library(
         "//submodules/TelegramUI/Components/SliderContextItem",
         "//submodules/TelegramUI/Components/InteractiveTextComponent",
         "//submodules/TelegramUI/Components/SaveProgressScreen",
+        "//submodules/TelegramUI/Components/Chat/ChatMessagePaymentAlertController",
     ],
     visibility = [
         "//visibility:public",
diff --git a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryChatContent.swift b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryChatContent.swift
index dabc123237..3c41e12feb 100644
--- a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryChatContent.swift
+++ b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryChatContent.swift
@@ -219,7 +219,8 @@ public final class StoryContentContextImpl: StoryContentContext {
                             isPremiumRequiredForMessaging: isPremiumRequiredForMessaging,
                             preferHighQualityStories: preferHighQualityStories,
                             boostsToUnrestrict: nil,
-                            appliedBoosts: nil
+                            appliedBoosts: nil,
+                            sendPaidMessageStars: cachedUserData.sendPaidMessageStars
                         )
                     } else if let cachedChannelData = cachedPeerDataView.cachedPeerData as? CachedChannelData {
                         additionalPeerData = StoryContentContextState.AdditionalPeerData(
@@ -230,7 +231,8 @@ public final class StoryContentContextImpl: StoryContentContext {
                             isPremiumRequiredForMessaging: isPremiumRequiredForMessaging,
                             preferHighQualityStories: preferHighQualityStories,
                             boostsToUnrestrict: cachedChannelData.boostsToUnrestrict,
-                            appliedBoosts: cachedChannelData.appliedBoosts
+                            appliedBoosts: cachedChannelData.appliedBoosts,
+                            sendPaidMessageStars: cachedChannelData.sendPaidMessageStars
                         )
                     } else {
                         additionalPeerData = StoryContentContextState.AdditionalPeerData(
@@ -241,7 +243,8 @@ public final class StoryContentContextImpl: StoryContentContext {
                             isPremiumRequiredForMessaging: isPremiumRequiredForMessaging,
                             preferHighQualityStories: preferHighQualityStories,
                             boostsToUnrestrict: nil,
-                            appliedBoosts: nil
+                            appliedBoosts: nil,
+                            sendPaidMessageStars: nil
                         )
                     }
                 } else {
@@ -253,7 +256,8 @@ public final class StoryContentContextImpl: StoryContentContext {
                         isPremiumRequiredForMessaging: isPremiumRequiredForMessaging,
                         preferHighQualityStories: preferHighQualityStories,
                         boostsToUnrestrict: nil,
-                        appliedBoosts: nil
+                        appliedBoosts: nil,
+                        sendPaidMessageStars: nil
                     )
                 }
                 let state = stateView.value?.get(Stories.PeerState.self)
@@ -1182,7 +1186,8 @@ public final class SingleStoryContentContextImpl: StoryContentContext {
                 TelegramEngine.EngineData.Item.NotificationSettings.Global(),
                 TelegramEngine.EngineData.Item.Peer.IsPremiumRequiredForMessaging(id: storyId.peerId),
                 TelegramEngine.EngineData.Item.Peer.BoostsToUnrestrict(id: storyId.peerId),
-                TelegramEngine.EngineData.Item.Peer.AppliedBoosts(id: storyId.peerId)
+                TelegramEngine.EngineData.Item.Peer.AppliedBoosts(id: storyId.peerId),
+                TelegramEngine.EngineData.Item.Peer.SendPaidMessageStars(id: storyId.peerId)
             ),
             item |> mapToSignal { item -> Signal<(Stories.StoredItem?, [PeerId: Peer], [MediaId: TelegramMediaFile], [StoryId: EngineStoryItem?]), NoError> in
                 return context.account.postbox.transaction { transaction -> (Stories.StoredItem?, [PeerId: Peer], [MediaId: TelegramMediaFile], [StoryId: EngineStoryItem?]) in
@@ -1253,7 +1258,7 @@ public final class SingleStoryContentContextImpl: StoryContentContext {
                 return
             }
             
-            let (peer, presence, areVoiceMessagesAvailable, canViewStats, notificationSettings, globalNotificationSettings, isPremiumRequiredForMessaging, boostsToUnrestrict, appliedBoosts) = data
+            let (peer, presence, areVoiceMessagesAvailable, canViewStats, notificationSettings, globalNotificationSettings, isPremiumRequiredForMessaging, boostsToUnrestrict, appliedBoosts, sendPaidMessageStars) = data
             let (item, peers, allEntityFiles, forwardInfoStories) = itemAndPeers
             
             guard let peer else {
@@ -1270,7 +1275,8 @@ public final class SingleStoryContentContextImpl: StoryContentContext {
                 isPremiumRequiredForMessaging: isPremiumRequiredForMessaging,
                 preferHighQualityStories: preferHighQualityStories,
                 boostsToUnrestrict: boostsToUnrestrict,
-                appliedBoosts: appliedBoosts
+                appliedBoosts: appliedBoosts,
+                sendPaidMessageStars: sendPaidMessageStars
             )
             
             for (storyId, story) in forwardInfoStories {
@@ -1436,9 +1442,11 @@ public final class PeerStoryListContentContextImpl: StoryContentContext {
             TelegramEngine.EngineData.Item.NotificationSettings.Global.Result,
             TelegramEngine.EngineData.Item.Peer.IsPremiumRequiredForMessaging.Result,
             TelegramEngine.EngineData.Item.Peer.BoostsToUnrestrict.Result,
-            TelegramEngine.EngineData.Item.Peer.AppliedBoosts.Result)
+            TelegramEngine.EngineData.Item.Peer.AppliedBoosts.Result,
+            TelegramEngine.EngineData.Item.Peer.SendPaidMessageStars.Result
+        )
         
-        init(data: (TelegramEngine.EngineData.Item.Peer.Peer.Result, TelegramEngine.EngineData.Item.Peer.Presence.Result, TelegramEngine.EngineData.Item.Peer.AreVoiceMessagesAvailable.Result, TelegramEngine.EngineData.Item.Peer.CanViewStats.Result, TelegramEngine.EngineData.Item.Peer.NotificationSettings.Result, TelegramEngine.EngineData.Item.NotificationSettings.Global.Result, TelegramEngine.EngineData.Item.Peer.IsPremiumRequiredForMessaging.Result, TelegramEngine.EngineData.Item.Peer.BoostsToUnrestrict.Result, TelegramEngine.EngineData.Item.Peer.AppliedBoosts.Result)) {
+        init(data: (TelegramEngine.EngineData.Item.Peer.Peer.Result, TelegramEngine.EngineData.Item.Peer.Presence.Result, TelegramEngine.EngineData.Item.Peer.AreVoiceMessagesAvailable.Result, TelegramEngine.EngineData.Item.Peer.CanViewStats.Result, TelegramEngine.EngineData.Item.Peer.NotificationSettings.Result, TelegramEngine.EngineData.Item.NotificationSettings.Global.Result, TelegramEngine.EngineData.Item.Peer.IsPremiumRequiredForMessaging.Result, TelegramEngine.EngineData.Item.Peer.BoostsToUnrestrict.Result, TelegramEngine.EngineData.Item.Peer.AppliedBoosts.Result, TelegramEngine.EngineData.Item.Peer.SendPaidMessageStars.Result)) {
             self.data = data
         }
     }
@@ -1544,7 +1552,8 @@ public final class PeerStoryListContentContextImpl: StoryContentContext {
                         TelegramEngine.EngineData.Item.NotificationSettings.Global(),
                         TelegramEngine.EngineData.Item.Peer.IsPremiumRequiredForMessaging(id: peerId),
                         TelegramEngine.EngineData.Item.Peer.BoostsToUnrestrict(id: peerId),
-                        TelegramEngine.EngineData.Item.Peer.AppliedBoosts(id: peerId)
+                        TelegramEngine.EngineData.Item.Peer.AppliedBoosts(id: peerId),
+                        TelegramEngine.EngineData.Item.Peer.SendPaidMessageStars(id: peerId)
                     ) |> map { PeerData(data: $0) })
                     self.currentPeerData = currentPeerData
                     
@@ -1563,7 +1572,7 @@ public final class PeerStoryListContentContextImpl: StoryContentContext {
                 self.listState = state
                 
                 let stateValue: StoryContentContextState
-                if let focusedIndex, let (peer, presence, areVoiceMessagesAvailable, canViewStats, notificationSettings, globalNotificationSettings, isPremiumRequiredForMessaging, boostsToUnrestrict, appliedBoosts) = data?.data, let peer {
+                if let focusedIndex, let (peer, presence, areVoiceMessagesAvailable, canViewStats, notificationSettings, globalNotificationSettings, isPremiumRequiredForMessaging, boostsToUnrestrict, appliedBoosts, sendPaidMessageStars) = data?.data, let peer {
                     let isMuted = resolvedAreStoriesMuted(globalSettings: globalNotificationSettings._asGlobalNotificationSettings(), peer: peer._asPeer(), peerSettings: notificationSettings._asNotificationSettings(), topSearchPeers: [])
                     let additionalPeerData = StoryContentContextState.AdditionalPeerData(
                         isMuted: isMuted,
@@ -1573,7 +1582,8 @@ public final class PeerStoryListContentContextImpl: StoryContentContext {
                         isPremiumRequiredForMessaging: isPremiumRequiredForMessaging,
                         preferHighQualityStories: preferHighQualityStories,
                         boostsToUnrestrict: boostsToUnrestrict,
-                        appliedBoosts: appliedBoosts
+                        appliedBoosts: appliedBoosts,
+                        sendPaidMessageStars: sendPaidMessageStars
                     )
                     
                     let item = state.items[focusedIndex]
@@ -2462,7 +2472,8 @@ public final class RepostStoriesContentContextImpl: StoryContentContext {
                             isPremiumRequiredForMessaging: isPremiumRequiredForMessaging,
                             preferHighQualityStories: preferHighQualityStories,
                             boostsToUnrestrict: nil,
-                            appliedBoosts: nil
+                            appliedBoosts: nil,
+                            sendPaidMessageStars: cachedUserData.sendPaidMessageStars
                         )
                     } else if let cachedChannelData = cachedPeerDataView.cachedPeerData as? CachedChannelData {
                         additionalPeerData = StoryContentContextState.AdditionalPeerData(
@@ -2473,7 +2484,8 @@ public final class RepostStoriesContentContextImpl: StoryContentContext {
                             isPremiumRequiredForMessaging: isPremiumRequiredForMessaging,
                             preferHighQualityStories: preferHighQualityStories,
                             boostsToUnrestrict: cachedChannelData.boostsToUnrestrict,
-                            appliedBoosts: cachedChannelData.appliedBoosts
+                            appliedBoosts: cachedChannelData.appliedBoosts,
+                            sendPaidMessageStars: cachedChannelData.sendPaidMessageStars
                         )
                     } else {
                         additionalPeerData = StoryContentContextState.AdditionalPeerData(
@@ -2484,7 +2496,8 @@ public final class RepostStoriesContentContextImpl: StoryContentContext {
                             isPremiumRequiredForMessaging: isPremiumRequiredForMessaging,
                             preferHighQualityStories: preferHighQualityStories,
                             boostsToUnrestrict: nil,
-                            appliedBoosts: nil
+                            appliedBoosts: nil,
+                            sendPaidMessageStars: nil
                         )
                     }
                 }
@@ -2497,7 +2510,8 @@ public final class RepostStoriesContentContextImpl: StoryContentContext {
                         isPremiumRequiredForMessaging: isPremiumRequiredForMessaging,
                         preferHighQualityStories: preferHighQualityStories,
                         boostsToUnrestrict: nil,
-                        appliedBoosts: nil
+                        appliedBoosts: nil,
+                        sendPaidMessageStars: nil
                     )
                 }
                 
diff --git a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContent.swift b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContent.swift
index 90479b4c0e..b4e4c11784 100644
--- a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContent.swift
+++ b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContent.swift
@@ -161,6 +161,7 @@ public final class StoryContentContextState {
         public let preferHighQualityStories: Bool
         public let boostsToUnrestrict: Int32?
         public let appliedBoosts: Int32?
+        public let sendPaidMessageStars: StarsAmount?
         
         public init(
             isMuted: Bool,
@@ -170,7 +171,8 @@ public final class StoryContentContextState {
             isPremiumRequiredForMessaging: Bool,
             preferHighQualityStories: Bool,
             boostsToUnrestrict: Int32?,
-            appliedBoosts: Int32?
+            appliedBoosts: Int32?,
+            sendPaidMessageStars: StarsAmount?
         ) {
             self.isMuted = isMuted
             self.areVoiceMessagesAvailable = areVoiceMessagesAvailable
@@ -180,6 +182,7 @@ public final class StoryContentContextState {
             self.preferHighQualityStories = preferHighQualityStories
             self.boostsToUnrestrict = boostsToUnrestrict
             self.appliedBoosts = appliedBoosts
+            self.sendPaidMessageStars = sendPaidMessageStars
         }
         
         public static func == (lhs: StoryContentContextState.AdditionalPeerData, rhs: StoryContentContextState.AdditionalPeerData) -> Bool {
@@ -207,6 +210,9 @@ public final class StoryContentContextState {
             if lhs.appliedBoosts != rhs.appliedBoosts {
                 return false
             }
+            if lhs.sendPaidMessageStars != rhs.sendPaidMessageStars {
+                return false
+            }
             return true
         }
     }
diff --git a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift
index 97f1f3c842..2f0f3c2f74 100644
--- a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift
+++ b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift
@@ -2823,7 +2823,12 @@ public final class StoryItemSetContainerComponent: Component {
                 
                 inputPlaceholder = .counter(items)
             } else {
-                inputPlaceholder = .plain(isGroup ? component.strings.Story_InputPlaceholderReplyInGroup : component.strings.Story_InputPlaceholderReplyPrivately)
+                if let sendPaidMessageStars = component.slice.additionalPeerData.sendPaidMessageStars {
+                    let dateTimeFormat = component.context.sharedContext.currentPresentationData.with { $0 }.dateTimeFormat
+                    inputPlaceholder = .plain(component.strings.Chat_InputTextPaidMessagePlaceholder(" # \(presentationStringsFormattedNumber(Int32(sendPaidMessageStars.value), dateTimeFormat.groupingSeparator))").string)
+                } else {
+                    inputPlaceholder = .plain(isGroup ? component.strings.Story_InputPlaceholderReplyInGroup : component.strings.Story_InputPlaceholderReplyPrivately)
+                }
             }
             
             let startTime22 = CFAbsoluteTimeGetCurrent()
@@ -2867,6 +2872,7 @@ public final class StoryItemSetContainerComponent: Component {
                         strings: component.strings,
                         style: .story,
                         placeholder: inputPlaceholder,
+                        sendPaidMessageStars: component.slice.additionalPeerData.sendPaidMessageStars,
                         maxLength: 4096,
                         queryTypes: [.mention, .hashtag, .emoji],
                         alwaysDarkWhenHasText: component.metrics.widthClass == .regular,
@@ -4647,6 +4653,10 @@ public final class StoryItemSetContainerComponent: Component {
                                     case .stars:
                                         break
                                     }
+                                    
+                                    if let sendPaidMessageStars = component.slice.additionalPeerData.sendPaidMessageStars {
+                                        messageAttributes.append(PaidStarsMessageAttribute(stars: sendPaidMessageStars, postponeSending: false))
+                                    }
 
                                     let message: EnqueueMessage = .message(
                                         text: text,
@@ -4693,7 +4703,6 @@ public final class StoryItemSetContainerComponent: Component {
                                 })
                             }
                         }
-                        
                         if self.displayLikeReactions {
                             if component.slice.item.storyItem.myReaction == updateReaction.reaction {
                                 action()
@@ -4704,7 +4713,9 @@ public final class StoryItemSetContainerComponent: Component {
                             }
                         } else {
                             self.sendMessageContext.performWithPossibleStealthModeConfirmation(view: self, action: {
-                                action()
+                                self.sendMessageContext.presentPaidMessageAlertIfNeeded(view: self, completion: {
+                                    action()
+                                })
                             })
                         }
                     }
diff --git a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerViewSendMessage.swift b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerViewSendMessage.swift
index 0677c3dd74..7140300641 100644
--- a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerViewSendMessage.swift
+++ b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerViewSendMessage.swift
@@ -50,6 +50,7 @@ import LocationUI
 import ReactionSelectionNode
 import StoryQualityUpgradeSheetScreen
 import AudioWaveform
+import ChatMessagePaymentAlertController
 
 private var ObjCKey_DeinitWatcher: Int?
 
@@ -491,6 +492,30 @@ final class StoryItemSetContainerSendMessage {
         view.updateIsProgressPaused()
     }
     
+    func presentPaidMessageAlertIfNeeded(view: StoryItemSetContainerComponent.View, completion: @escaping () -> Void) {
+        guard let component = view.component, let sendPaidMessageStars = component.slice.additionalPeerData.sendPaidMessageStars else {
+            completion()
+            return
+        }
+        let presentationData = component.context.sharedContext.currentPresentationData.with({ $0 }).withUpdated(theme: defaultDarkColorPresentationTheme)
+        
+        let controller = chatMessagePaymentAlertController(
+            context: component.context,
+            presentationData: presentationData,
+            updatedPresentationData: nil,
+            peers: [component.slice.effectivePeer],
+            count: 1,
+            amount: sendPaidMessageStars,
+            totalAmount: nil,
+            hasCheck: false,
+            navigationController: component.controller()?.navigationController as? NavigationController,
+            completion: { _ in
+                completion()
+            }
+        )
+        component.controller()?.present(controller, in: .window(.root))
+    }
+    
     func performWithPossibleStealthModeConfirmation(view: StoryItemSetContainerComponent.View, action: @escaping () -> Void) {
         guard let component = view.component, component.stealthModeTimeout != nil else {
             action()
@@ -512,7 +537,6 @@ final class StoryItemSetContainerSendMessage {
             
             let timestamp = Int32(Date().timeIntervalSince1970)
             if noticeCount < 1, let activeUntilTimestamp = config.stealthModeState.actualizedNow().activeUntilTimestamp, activeUntilTimestamp > timestamp {
-                
                 let theme = component.theme
                 let updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>) = (component.context.sharedContext.currentPresentationData.with({ $0 }).withUpdated(theme: theme), component.context.sharedContext.presentationData |> map { $0.withUpdated(theme: theme) })
                 
@@ -575,53 +599,64 @@ final class StoryItemSetContainerSendMessage {
             
             let controller = component.controller() as? StoryContainerScreen
             
-            if let recordedAudioPreview = self.recordedAudioPreview, case let .audio(audio) = recordedAudioPreview {
-                self.recordedAudioPreview = nil
-                
-                let waveformBuffer = audio.waveform.makeBitstream()
-                
-                let messages: [EnqueueMessage] = [.message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: TelegramMediaFile(fileId: EngineMedia.Id(namespace: Namespaces.Media.LocalFile, id: Int64.random(in: Int64.min ... Int64.max)), partialReference: nil, resource: audio.resource, previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "audio/ogg", size: Int64(audio.fileSize), attributes: [.Audio(isVoice: true, duration: Int(audio.duration), title: nil, performer: nil, waveform: waveformBuffer)], alternativeRepresentations: [])), threadId: nil, replyToMessageId: nil, replyToStoryId: focusedStoryId, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])]
-                
-                let _ = enqueueMessages(account: component.context.account, peerId: peerId, messages: messages).start()
-                
-                view.state?.updated(transition: ComponentTransition(animation: .curve(duration: 0.3, curve: .spring)))
-            } else if self.hasRecordedVideoPreview, let videoRecorderValue = self.videoRecorderValue {
-                videoRecorderValue.send()
-                self.hasRecordedVideoPreview = false
-                self.videoRecorder.set(.single(nil))
-                view.state?.updated(transition: ComponentTransition(animation: .curve(duration: 0.3, curve: .spring)))
-            } else {
-                switch inputPanelView.getSendMessageInput() {
-                case let .text(text):
-                    if !text.string.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
-                        let entities = generateChatInputTextEntities(text)
-                        let _ = (component.context.engine.messages.enqueueOutgoingMessage(
-                            to: peerId,
-                            replyTo: nil,
-                            storyId: focusedStoryId,
-                            content: .text(text.string, entities),
-                            silentPosting: silentPosting,
-                            scheduleTime: scheduleTime
-                        ) |> deliverOnMainQueue).start(next: { [weak self, weak view] messageIds in
-                            Queue.mainQueue().after(0.3) {
-                                if let self, let view {
-                                    self.presentMessageSentTooltip(view: view, peer: peer, messageId: messageIds.first.flatMap { $0 }, isScheduled: scheduleTime != nil)
+            self.presentPaidMessageAlertIfNeeded(view: view, completion: { [weak self, weak view] in
+                guard let self, let view else {
+                    return
+                }
+                if let recordedAudioPreview = self.recordedAudioPreview, case let .audio(audio) = recordedAudioPreview {
+                    self.recordedAudioPreview = nil
+                    
+                    let waveformBuffer = audio.waveform.makeBitstream()
+                    
+                    var messageAttributes: [MessageAttribute] = []
+                    if let sendPaidMessageStars = component.slice.additionalPeerData.sendPaidMessageStars {
+                        messageAttributes.append(PaidStarsMessageAttribute(stars: sendPaidMessageStars, postponeSending: false))
+                    }
+                    
+                    let messages: [EnqueueMessage] = [.message(text: "", attributes: messageAttributes, inlineStickers: [:], mediaReference: .standalone(media: TelegramMediaFile(fileId: EngineMedia.Id(namespace: Namespaces.Media.LocalFile, id: Int64.random(in: Int64.min ... Int64.max)), partialReference: nil, resource: audio.resource, previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "audio/ogg", size: Int64(audio.fileSize), attributes: [.Audio(isVoice: true, duration: Int(audio.duration), title: nil, performer: nil, waveform: waveformBuffer)], alternativeRepresentations: [])), threadId: nil, replyToMessageId: nil, replyToStoryId: focusedStoryId, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])]
+                    
+                    let _ = enqueueMessages(account: component.context.account, peerId: peerId, messages: messages).start()
+                    
+                    view.state?.updated(transition: ComponentTransition(animation: .curve(duration: 0.3, curve: .spring)))
+                } else if self.hasRecordedVideoPreview, let videoRecorderValue = self.videoRecorderValue {
+                    videoRecorderValue.send()
+                    self.hasRecordedVideoPreview = false
+                    self.videoRecorder.set(.single(nil))
+                    view.state?.updated(transition: ComponentTransition(animation: .curve(duration: 0.3, curve: .spring)))
+                } else {
+                    switch inputPanelView.getSendMessageInput() {
+                    case let .text(text):
+                        if !text.string.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
+                            let entities = generateChatInputTextEntities(text)
+                            let _ = (component.context.engine.messages.enqueueOutgoingMessage(
+                                to: peerId,
+                                replyTo: nil,
+                                storyId: focusedStoryId,
+                                content: .text(text.string, entities),
+                                silentPosting: silentPosting,
+                                scheduleTime: scheduleTime,
+                                sendPaidMessageStars: component.slice.additionalPeerData.sendPaidMessageStars
+                            ) |> deliverOnMainQueue).start(next: { [weak self, weak view] messageIds in
+                                Queue.mainQueue().after(0.3) {
+                                    if let self, let view {
+                                        self.presentMessageSentTooltip(view: view, peer: peer, messageId: messageIds.first.flatMap { $0 }, isScheduled: scheduleTime != nil)
+                                    }
                                 }
+                            })
+                            component.storyItemSharedState.replyDrafts.removeValue(forKey: StoryId(peerId: peerId, id: focusedItem.storyItem.id))
+                            inputPanelView.clearSendMessageInput(updateState: true)
+                            
+                            self.currentInputMode = .text
+                            if hasFirstResponder(view) {
+                                view.endEditing(true)
+                            } else {
+                                view.state?.updated(transition: .spring(duration: 0.3))
                             }
-                        })
-                        component.storyItemSharedState.replyDrafts.removeValue(forKey: StoryId(peerId: peerId, id: focusedItem.storyItem.id))
-                        inputPanelView.clearSendMessageInput(updateState: true)
-                        
-                        self.currentInputMode = .text
-                        if hasFirstResponder(view) {
-                            view.endEditing(true)
-                        } else {
-                            view.state?.updated(transition: .spring(duration: 0.3))
+                            controller?.requestLayout(forceUpdate: true, transition: .animated(duration: 0.3, curve: .spring))
                         }
-                        controller?.requestLayout(forceUpdate: true, transition: .animated(duration: 0.3, curve: .spring))
                     }
                 }
-            }
+            })
         })
     }
     
@@ -660,26 +695,32 @@ final class StoryItemSetContainerSendMessage {
                 })
             }
             
-            let _ = (component.context.engine.messages.enqueueOutgoingMessage(
-                to: peerId,
-                replyTo: nil,
-                storyId: focusedStoryId,
-                content: .file(fileReference)
-            ) |> deliverOnMainQueue).start(next: { [weak self, weak view] messageIds in
-                Queue.mainQueue().after(0.3) {
-                    if let self, let view {
-                        self.presentMessageSentTooltip(view: view, peer: peer, messageId: messageIds.first.flatMap { $0 })
-                    }
+            self.presentPaidMessageAlertIfNeeded(view: view, completion: { [weak self, weak view] in
+                guard let self, let view else {
+                    return
                 }
+                let _ = (component.context.engine.messages.enqueueOutgoingMessage(
+                    to: peerId,
+                    replyTo: nil,
+                    storyId: focusedStoryId,
+                    content: .file(fileReference),
+                    sendPaidMessageStars: component.slice.additionalPeerData.sendPaidMessageStars
+                ) |> deliverOnMainQueue).start(next: { [weak self, weak view] messageIds in
+                    Queue.mainQueue().after(0.3) {
+                        if let self, let view {
+                            self.presentMessageSentTooltip(view: view, peer: peer, messageId: messageIds.first.flatMap { $0 })
+                        }
+                    }
+                })
+                
+                self.currentInputMode = .text
+                if hasFirstResponder(view) {
+                    view.endEditing(true)
+                } else {
+                    view.state?.updated(transition: .spring(duration: 0.3))
+                }
+                controller?.requestLayout(forceUpdate: true, transition: .animated(duration: 0.3, curve: .spring))
             })
-            
-            self.currentInputMode = .text
-            if hasFirstResponder(view) {
-                view.endEditing(true)
-            } else {
-                view.state?.updated(transition: .spring(duration: 0.3))
-            }
-            controller?.requestLayout(forceUpdate: true, transition: .animated(duration: 0.3, curve: .spring))
         })
     }
     
@@ -714,37 +755,48 @@ final class StoryItemSetContainerSendMessage {
             })
         }
         
-        let _ = (component.context.engine.messages.enqueueOutgoingMessage(
-            to: peerId,
-            replyTo: nil,
-            storyId: focusedStoryId,
-            content: .contextResult(results, result)
-        ) |> deliverOnMainQueue).start(next: { [weak self, weak view] messageIds in
-            Queue.mainQueue().after(0.3) {
-                if let self, let view {
-                    self.presentMessageSentTooltip(view: view, peer: peer, messageId: messageIds.first.flatMap { $0 })
-                }
+        self.presentPaidMessageAlertIfNeeded(view: view, completion: { [weak self, weak view] in
+            guard let self, let view else {
+                return
             }
+            let _ = (component.context.engine.messages.enqueueOutgoingMessage(
+                to: peerId,
+                replyTo: nil,
+                storyId: focusedStoryId,
+                content: .contextResult(results, result),
+                sendPaidMessageStars: component.slice.additionalPeerData.sendPaidMessageStars
+            ) |> deliverOnMainQueue).start(next: { [weak self, weak view] messageIds in
+                Queue.mainQueue().after(0.3) {
+                    if let self, let view {
+                        self.presentMessageSentTooltip(view: view, peer: peer, messageId: messageIds.first.flatMap { $0 })
+                    }
+                }
+            })
+            
+            self.currentInputMode = .text
+            if hasFirstResponder(view) {
+                view.endEditing(true)
+            } else {
+                view.state?.updated(transition: .spring(duration: 0.3))
+            }
+            controller?.requestLayout(forceUpdate: true, transition: .animated(duration: 0.3, curve: .spring))
         })
-        
-        self.currentInputMode = .text
-        if hasFirstResponder(view) {
-            view.endEditing(true)
-        } else {
-            view.state?.updated(transition: .spring(duration: 0.3))
-        }
-        controller?.requestLayout(forceUpdate: true, transition: .animated(duration: 0.3, curve: .spring))
     }
     
     func enqueueGifData(view: StoryItemSetContainerComponent.View, data: Data) {
         guard let component = view.component else {
             return
         }
-        let peer = component.slice.effectivePeer
-        let _ = (legacyEnqueueGifMessage(account: component.context.account, data: data) |> deliverOnMainQueue).start(next: { [weak self, weak view] message in
-            if let self, let view {
-                self.sendMessages(view: view, peer: peer, messages: [message])
+        self.presentPaidMessageAlertIfNeeded(view: view, completion: { [weak self] in
+            guard let self else {
+                return
             }
+            let peer = component.slice.effectivePeer
+            let _ = (legacyEnqueueGifMessage(account: component.context.account, data: data) |> deliverOnMainQueue).start(next: { [weak self, weak view] message in
+                if let self, let view {
+                    self.sendMessages(view: view, peer: peer, messages: [message])
+                }
+            })
         })
     }
     
@@ -794,7 +846,12 @@ final class StoryItemSetContainerSendMessage {
                 let media = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: Int64.random(in: Int64.min ... Int64.max)), partialReference: nil, resource: resource, previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "image/webp", size: Int64(data.count), attributes: fileAttributes, alternativeRepresentations: [])
                 let message = EnqueueMessage.message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: media), threadId: nil, replyToMessageId: nil, replyToStoryId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])
                 
-                self.sendMessages(view: view, peer: peer, messages: [message], silentPosting: false)
+                self.presentPaidMessageAlertIfNeeded(view: view, completion: { [weak self] in
+                    guard let self else {
+                        return
+                    }
+                    self.sendMessages(view: view, peer: peer, messages: [message], silentPosting: false)
+                })
             }
         })
     }
@@ -846,7 +903,12 @@ final class StoryItemSetContainerSendMessage {
                                     guard let self, let view else {
                                         return
                                     }
-                                    self.sendMessages(view: view, peer: peer, messages: [updatedMessage])
+                                    self.presentPaidMessageAlertIfNeeded(view: view, completion: { [weak self, weak view] in
+                                        guard let self, let view else {
+                                            return
+                                        }
+                                        self.sendMessages(view: view, peer: peer, messages: [updatedMessage])
+                                    })
                                 })
                             }, displaySlowmodeTooltip: { [weak self] view, rect in
                                 //self?.interfaceInteraction?.displaySlowmodeTooltip(view, rect)
@@ -896,9 +958,14 @@ final class StoryItemSetContainerSendMessage {
                                 guard let self, let view else {
                                     return
                                 }
-                                self.sendMessages(view: view, peer: peer, messages: [.message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: TelegramMediaFile(fileId: EngineMedia.Id(namespace: Namespaces.Media.LocalFile, id: randomId), partialReference: nil, resource: resource, previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "audio/ogg", size: Int64(data.compressedData.count), attributes: [.Audio(isVoice: true, duration: Int(data.duration), title: nil, performer: nil, waveform: waveformBuffer)], alternativeRepresentations: [])), threadId: nil, replyToMessageId: nil, replyToStoryId: focusedStoryId, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])])
-                                
-                                HapticFeedback().tap()
+                                self.presentPaidMessageAlertIfNeeded(view: view, completion: { [weak self, weak view] in
+                                    guard let self, let view else {
+                                        return
+                                    }
+                                    self.sendMessages(view: view, peer: peer, messages: [.message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: TelegramMediaFile(fileId: EngineMedia.Id(namespace: Namespaces.Media.LocalFile, id: randomId), partialReference: nil, resource: resource, previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "audio/ogg", size: Int64(data.compressedData.count), attributes: [.Audio(isVoice: true, duration: Int(data.duration), title: nil, performer: nil, waveform: waveformBuffer)], alternativeRepresentations: [])), threadId: nil, replyToMessageId: nil, replyToStoryId: focusedStoryId, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])])
+                                    
+                                    HapticFeedback().tap()
+                                })
                             })
                         }
                     })
@@ -1593,7 +1660,11 @@ final class StoryItemSetContainerSendMessage {
                             guard let view, let component = view.component else {
                                 return
                             }
-                            let message: EnqueueMessage = .message(text: "", attributes: [], inlineStickers: [:], mediaReference: mediaReference, threadId: nil, replyToMessageId: nil, replyToStoryId: focusedStoryId, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])
+                            var messageAttributes: [MessageAttribute] = []
+                            if let sendPaidMessageStars = component.slice.additionalPeerData.sendPaidMessageStars {
+                                messageAttributes.append(PaidStarsMessageAttribute(stars: sendPaidMessageStars, postponeSending: false))
+                            }
+                            let message: EnqueueMessage = .message(text: "", attributes: messageAttributes, inlineStickers: [:], mediaReference: mediaReference, threadId: nil, replyToMessageId: nil, replyToStoryId: focusedStoryId, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])
                             let _ = (enqueueMessages(account: component.context.account, peerId: peer.id, messages: [message.withUpdatedReplyToMessageId(nil)])
                             |> deliverOnMainQueue).start(next: { [weak self, weak view] messageIds in
                                 if let self, let view {
@@ -1636,7 +1707,12 @@ final class StoryItemSetContainerSendMessage {
                                     return
                                 }
                                 let message: EnqueueMessage = .message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: location), threadId: nil, replyToMessageId: nil, replyToStoryId: focusedStoryId, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])
-                                self.sendMessages(view: view, peer: peer, messages: [message])
+                                self.presentPaidMessageAlertIfNeeded(view: view, completion: { [weak self] in
+                                    guard let self else {
+                                        return
+                                    }
+                                    self.sendMessages(view: view, peer: peer, messages: [message])
+                                })
                             })
                             completion(controller, controller.mediaPickerContext)
                             
@@ -1705,7 +1781,12 @@ final class StoryItemSetContainerSendMessage {
                                     }
                                 }
                                 
-                                self.sendMessages(view: view, peer: peer, messages: enqueueMessages, silentPosting: silent, scheduleTime: scheduleTime)
+                                self.presentPaidMessageAlertIfNeeded(view: view, completion: { [weak self] in
+                                    guard let self else {
+                                        return
+                                    }
+                                    self.sendMessages(view: view, peer: peer, messages: enqueueMessages, silentPosting: silent, scheduleTime: scheduleTime)
+                                })
                             } else if let peer = peers.first {
                                 let dataSignal: Signal<(EnginePeer?, DeviceContactExtendedData?), NoError>
                                 switch peer {
@@ -1760,7 +1841,12 @@ final class StoryItemSetContainerSendMessage {
                                         }
                                         enqueueMessages.append(.message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: media), threadId: nil, replyToMessageId: nil, replyToStoryId: focusedStoryId, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: []))
                                         
-                                        self.sendMessages(view: view, peer: targetPeer, messages: enqueueMessages, silentPosting: silent, scheduleTime: scheduleTime)
+                                        self.presentPaidMessageAlertIfNeeded(view: view, completion: { [weak self] in
+                                            guard let self else {
+                                                return
+                                            }
+                                            self.sendMessages(view: view, peer: targetPeer, messages: enqueueMessages, silentPosting: silent, scheduleTime: scheduleTime)
+                                        })
                                     } else {
                                         let contactController = component.context.sharedContext.makeDeviceContactInfoController(context: ShareControllerAppAccountContext(context: component.context), environment: ShareControllerAppEnvironment(sharedContext: component.context.sharedContext), subject: .filter(peer: peerAndContactData.0?._asPeer(), contactId: nil, contactData: contactData, completion: { [weak self, weak view] peer, contactData in
                                             guard let self, let view else {
@@ -1779,7 +1865,12 @@ final class StoryItemSetContainerSendMessage {
                                                 }
                                                 enqueueMessages.append(.message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: media), threadId: nil, replyToMessageId: nil, replyToStoryId: focusedStoryId, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: []))
                                                 
-                                                self.sendMessages(view: view, peer: targetPeer, messages: enqueueMessages, silentPosting: silent, scheduleTime: scheduleTime)
+                                                self.presentPaidMessageAlertIfNeeded(view: view, completion: { [weak self] in
+                                                    guard let self else {
+                                                        return
+                                                    }
+                                                    self.sendMessages(view: view, peer: targetPeer, messages: enqueueMessages, silentPosting: silent, scheduleTime: scheduleTime)
+                                                })
                                             }
                                         }), completed: nil, cancelled: nil)
                                         component.controller()?.push(contactController)
@@ -2187,7 +2278,12 @@ final class StoryItemSetContainerSendMessage {
                             }
                             
                             if !messages.isEmpty {
-                                strongSelf.sendMessages(view: view, peer: peer, messages: messages)
+                                strongSelf.presentPaidMessageAlertIfNeeded(view: view, completion: { [weak self] in
+                                    guard let strongSelf = self else {
+                                        return
+                                    }
+                                    strongSelf.sendMessages(view: view, peer: peer, messages: messages)
+                                })
                             }
                         }
                     }))
@@ -2248,7 +2344,12 @@ final class StoryItemSetContainerSendMessage {
                             if !inputText.string.isEmpty {
                                 self.clearInputText(view: view)
                             }
-                            self.enqueueMediaMessages(view: view, peer: peer, replyToMessageId: nil, replyToStoryId: focusedStoryId, signals: signals, silentPosting: silentPosting, scheduleTime: scheduleTime, parameters: parameters, getAnimatedTransitionSource: getAnimatedTransitionSource, completion: completion)
+                            self.presentPaidMessageAlertIfNeeded(view: view, completion: { [weak self] in
+                                guard let self else {
+                                    return
+                                }
+                                self.enqueueMediaMessages(view: view, peer: peer, replyToMessageId: nil, replyToStoryId: focusedStoryId, signals: signals, silentPosting: silentPosting, scheduleTime: scheduleTime, parameters: parameters, getAnimatedTransitionSource: getAnimatedTransitionSource, completion: completion)
+                            })
                         }
                     )
                 }
@@ -2268,7 +2369,19 @@ final class StoryItemSetContainerSendMessage {
             guard let self, let view, let component = view.component else {
                 return
             }
-            if component.context.engine.messages.enqueueOutgoingMessageWithChatContextResult(to: peer.id, threadId: nil, botId: results.botId, result: result, replyToMessageId: replyMessageId.flatMap { EngineMessageReplySubject(messageId: $0, quote: nil) }, replyToStoryId: storyId, hideVia: hideVia, silentPosting: silentPosting, scheduleTime: scheduleTime) {
+            if component.context.engine.messages.enqueueOutgoingMessageWithChatContextResult(
+                to: peer.id,
+                threadId: nil,
+                botId: results.botId,
+                result: result,
+                replyToMessageId: replyMessageId.flatMap { EngineMessageReplySubject(messageId: $0, quote: nil) },
+                replyToStoryId: storyId,
+                hideVia: hideVia,
+                silentPosting: silentPosting,
+                scheduleTime: scheduleTime,
+                sendPaidMessageStars: component.slice.additionalPeerData.sendPaidMessageStars,
+                postpone: false
+            ) {
             }
             
             if let attachmentController = self.attachmentController {
@@ -2416,10 +2529,15 @@ final class StoryItemSetContainerSendMessage {
                 guard let self, let view else {
                     return
                 }
-                self.enqueueMediaMessages(view: view, peer: peer, replyToMessageId: replyToMessageId, replyToStoryId: replyToStoryId, signals: signals, silentPosting: silentPosting, scheduleTime: scheduleTime > 0 ? scheduleTime : nil, parameters: parameters)
-                if !inputText.string.isEmpty {
-                    self.clearInputText(view: view)
-                }
+                self.presentPaidMessageAlertIfNeeded(view: view, completion: { [weak self, weak view] in
+                    guard let self, let view else {
+                        return
+                    }
+                    self.enqueueMediaMessages(view: view, peer: peer, replyToMessageId: replyToMessageId, replyToStoryId: replyToStoryId, signals: signals, silentPosting: silentPosting, scheduleTime: scheduleTime > 0 ? scheduleTime : nil, parameters: parameters)
+                    if !inputText.string.isEmpty {
+                        self.clearInputText(view: view)
+                    }
+                })
             }, recognizedQRCode: { _ in
             }, presentSchedulePicker: { [weak self, weak view] _, done in
                 guard let self, let view else {
@@ -2545,6 +2663,10 @@ final class StoryItemSetContainerSendMessage {
                          attributes.append(OutgoingScheduleInfoMessageAttribute(scheduleTime: scheduleTime))
                     }
                 }
+                var messageAttributes: [MessageAttribute] = []
+                if let component = view.component, let sendPaidMessageStars = component.slice.additionalPeerData.sendPaidMessageStars {
+                    messageAttributes.append(PaidStarsMessageAttribute(stars: sendPaidMessageStars, postponeSending: false))
+                }
                 return attributes
             }
         }
diff --git a/submodules/TelegramUI/Sources/Chat/ChatControllerLoadDisplayNode.swift b/submodules/TelegramUI/Sources/Chat/ChatControllerLoadDisplayNode.swift
index 32a4f083db..a8b2117736 100644
--- a/submodules/TelegramUI/Sources/Chat/ChatControllerLoadDisplayNode.swift
+++ b/submodules/TelegramUI/Sources/Chat/ChatControllerLoadDisplayNode.swift
@@ -2604,8 +2604,12 @@ extension ChatControllerImpl {
                 strongSelf.interfaceInteraction?.displaySlowmodeTooltip(node.view, rect)
                 return false
             }
-            
-            strongSelf.enqueueChatContextResult(results, result)
+            strongSelf.presentPaidMessageAlertIfNeeded(completion: { [weak self] postpone in
+                guard let strongSelf = self else {
+                    return
+                }
+                strongSelf.enqueueChatContextResult(results, result, postpone: postpone)
+            })
             return true
         }, sendBotCommand: { [weak self] botPeer, command in
             if let strongSelf = self, canSendMessagesToChat(strongSelf.presentationInterfaceState) {
diff --git a/submodules/TelegramUI/Sources/Chat/ChatControllerMediaRecording.swift b/submodules/TelegramUI/Sources/Chat/ChatControllerMediaRecording.swift
index 37fd817a05..455ea29bdf 100644
--- a/submodules/TelegramUI/Sources/Chat/ChatControllerMediaRecording.swift
+++ b/submodules/TelegramUI/Sources/Chat/ChatControllerMediaRecording.swift
@@ -250,10 +250,8 @@ extension ChatControllerImpl {
         }
         
         var sendImmediately = false
-        if let _ = self.presentationInterfaceState.sendPaidMessageStars {
-            if case .send = action {
-                updatedAction = .preview
-            }
+        if let _ = self.presentationInterfaceState.sendPaidMessageStars, case .send = action {
+            updatedAction = .preview
             sendImmediately = true
         }
         
diff --git a/submodules/TelegramUI/Sources/Chat/ChatControllerPaidMessage.swift b/submodules/TelegramUI/Sources/Chat/ChatControllerPaidMessage.swift
index 259e63a313..0e1b9de5e6 100644
--- a/submodules/TelegramUI/Sources/Chat/ChatControllerPaidMessage.swift
+++ b/submodules/TelegramUI/Sources/Chat/ChatControllerPaidMessage.swift
@@ -23,10 +23,10 @@ extension ChatControllerImpl {
         if let sendPaidMessageStars = self.presentationInterfaceState.sendPaidMessageStars {
             let _ = (ApplicationSpecificNotice.dismissedPaidMessageWarningNamespace(accountManager: self.context.sharedContext.accountManager, peerId: peer.id)
             |> deliverOnMainQueue).start(next: { [weak self] dismissedAmount in
-                guard let self else {
+                guard let self, let starsContext = self.context.starsContext else {
                     return
                 }
-                if let dismissedAmount, dismissedAmount == sendPaidMessageStars.value {
+                if let dismissedAmount, dismissedAmount == sendPaidMessageStars.value, let currentState = starsContext.currentState, currentState.balance > sendPaidMessageStars {
                     completion(true)
                     self.displayPaidMessageUndo(count: count, amount: sendPaidMessageStars)
                 } else {
@@ -37,14 +37,14 @@ extension ChatControllerImpl {
                     let controller = chatMessagePaymentAlertController(
                         context: self.context,
                         presentationData: presentationData,
-                        updatedPresentationData: nil,//self.updatedPresentationData,
+                        updatedPresentationData: nil,
                         peers: [peer],
                         count: count,
                         amount: sendPaidMessageStars,
                         totalAmount: nil,
                         navigationController: self.navigationController as? NavigationController,
                         completion: { [weak self] dontAskAgain in
-                            guard let self, let starsContext = self.context.starsContext else {
+                            guard let self else {
                                 return
                             }
                             
diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift
index 3026a94e4f..430f87c869 100644
--- a/submodules/TelegramUI/Sources/ChatController.swift
+++ b/submodules/TelegramUI/Sources/ChatController.swift
@@ -9515,7 +9515,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
         }))
     }
 
-    func enqueueChatContextResult(_ results: ChatContextResultCollection, _ result: ChatContextResult, hideVia: Bool = false, closeMediaInput: Bool = false, silentPosting: Bool = false, resetTextInputState: Bool = true) {
+    func enqueueChatContextResult(_ results: ChatContextResultCollection, _ result: ChatContextResult, hideVia: Bool = false, closeMediaInput: Bool = false, silentPosting: Bool = false, resetTextInputState: Bool = true, postpone: Bool = false) {
         if !canSendMessagesToChat(self.presentationInterfaceState) {
             return
         }
@@ -9534,7 +9534,9 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
                 return
             }
             let replyMessageSubject = self.presentationInterfaceState.interfaceState.replyMessageSubject
-            if self.context.engine.messages.enqueueOutgoingMessageWithChatContextResult(to: peerId, threadId: self.chatLocation.threadId, botId: results.botId, result: result, replyToMessageId: replyMessageSubject?.subjectModel, hideVia: hideVia, silentPosting: silentPosting, scheduleTime: scheduleTime) {
+            
+            let sendPaidMessageStars = self.presentationInterfaceState.sendPaidMessageStars
+            if self.context.engine.messages.enqueueOutgoingMessageWithChatContextResult(to: peerId, threadId: self.chatLocation.threadId, botId: results.botId, result: result, replyToMessageId: replyMessageSubject?.subjectModel, hideVia: hideVia, silentPosting: silentPosting, scheduleTime: scheduleTime, sendPaidMessageStars: sendPaidMessageStars, postpone: postpone) {
                 self.chatDisplayNode.setupSendActionOnViewUpdate({ [weak self] in
                     if let strongSelf = self {
                         strongSelf.chatDisplayNode.collapseInput()
diff --git a/submodules/TelegramUI/Sources/ChatControllerForwardMessages.swift b/submodules/TelegramUI/Sources/ChatControllerForwardMessages.swift
index 401c692bec..e36b0510f5 100644
--- a/submodules/TelegramUI/Sources/ChatControllerForwardMessages.swift
+++ b/submodules/TelegramUI/Sources/ChatControllerForwardMessages.swift
@@ -13,8 +13,9 @@ import ChatInterfaceState
 import PremiumUI
 import ReactionSelectionNode
 import TopMessageReactions
+import ChatMessagePaymentAlertController
 
-extension ChatControllerImpl {    
+extension ChatControllerImpl {
     func forwardMessages(messageIds: [MessageId], options: ChatInterfaceForwardOptionsState? = nil, resetCurrent: Bool = false) {
         let _ = (self.context.engine.data.get(EngineDataMap(
             messageIds.map(TelegramEngine.EngineData.Item.Messages.Message.init)
@@ -94,190 +95,246 @@ extension ChatControllerImpl {
                 }
             }
             controller.multiplePeersSelected = { [weak self, weak controller] peers, peerMap, messageText, mode, forwardOptions, _ in
-                guard let strongSelf = self, let strongController = controller else {
-                    return
-                }
-                strongController.dismiss()
+                let peerIds = peers.map { $0.id }
                 
-                var result: [EnqueueMessage] = []
-                if messageText.string.count > 0 {
-                    let inputText = convertMarkdownToAttributes(messageText)
-                    for text in breakChatInputText(trimChatInputText(inputText)) {
-                        if text.length != 0 {
-                            var attributes: [MessageAttribute] = []
-                            let entities = generateTextEntities(text.string, enabledTypes: .all, currentEntities: generateChatInputTextEntities(text))
-                            if !entities.isEmpty {
-                                attributes.append(TextEntitiesMessageAttribute(entities: entities))
-                            }
-                            result.append(.message(text: text.string, attributes: attributes, inlineStickers: [:], mediaReference: nil, threadId: strongSelf.chatLocation.threadId, replyToMessageId: nil, replyToStoryId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: []))
-                        }
-                    }
-                }
-                
-                var attributes: [MessageAttribute] = []
-                attributes.append(ForwardOptionsMessageAttribute(hideNames: forwardOptions?.hideNames == true, hideCaptions: forwardOptions?.hideCaptions == true))
-                
-                result.append(contentsOf: messages.map { message -> EnqueueMessage in
-                    return .forward(source: message.id, threadId: nil, grouping: .auto, attributes: attributes, correlationId: nil)
-                })
-                
-                let commit: ([EnqueueMessage]) -> Void = { result in
+                let _ = (context.engine.data.get(
+                    EngineDataMap(
+                        peerIds.map(TelegramEngine.EngineData.Item.Peer.SendPaidMessageStars.init(id:))
+                    )
+                )
+                |> deliverOnMainQueue).start(next: { [weak self, weak controller] sendPaidMessageStars in
                     guard let strongSelf = self else {
                         return
                     }
-                    var result = result
-                    
-                    strongSelf.updateChatPresentationInterfaceState(animated: false, interactive: true, { $0.updatedInterfaceState({ $0.withoutSelectionState() }).updatedSearch(nil) })
-                    
-                    var correlationIds: [Int64] = []
-                    for i in 0 ..< result.count {
-                        let correlationId = Int64.random(in: Int64.min ... Int64.max)
-                        correlationIds.append(correlationId)
-                        result[i] = result[i].withUpdatedCorrelationId(correlationId)
+                    var count: Int32 = Int32(messages.count)
+                    if messageText.string.count > 0 {
+                        count += 1
                     }
-                    
-                    let targetPeersShouldDivertSignals: [Signal<(EnginePeer, Bool), NoError>] = peers.map { peer -> Signal<(EnginePeer, Bool), NoError> in
-                        return strongSelf.shouldDivertMessagesToScheduled(targetPeer: peer, messages: result)
-                        |> map { shouldDivert -> (EnginePeer, Bool) in
-                            return (peer, shouldDivert)
+                    var totalAmount: StarsAmount = .zero
+                    for peer in peers {
+                        if let maybeAmount = sendPaidMessageStars[peer.id], let amount = maybeAmount {
+                            totalAmount = totalAmount + amount
                         }
                     }
-                    let targetPeersShouldDivert: Signal<[(EnginePeer, Bool)], NoError> = combineLatest(targetPeersShouldDivertSignals)
-                    let _ = (targetPeersShouldDivert
-                    |> deliverOnMainQueue).startStandalone(next: { targetPeersShouldDivert in
-                        guard let strongSelf = self else {
+                                        
+                    let proceed = { [weak self, weak controller] in
+                        guard let strongSelf = self, let strongController = controller else {
                             return
                         }
                         
-                        var displayConvertingTooltip = false
+                        strongController.dismiss()
                         
-                        var displayPeers: [EnginePeer] = []
-                        for (peer, shouldDivert) in targetPeersShouldDivert {
-                            var peerMessages = result
-                            if shouldDivert {
-                                displayConvertingTooltip = true
-                                peerMessages = peerMessages.map { message -> EnqueueMessage in
-                                    return message.withUpdatedAttributes { attributes in
-                                        var attributes = attributes
-                                        attributes.removeAll(where: { $0 is OutgoingScheduleInfoMessageAttribute })
-                                        attributes.append(OutgoingScheduleInfoMessageAttribute(scheduleTime: Int32(Date().timeIntervalSince1970) + 10 * 24 * 60 * 60))
-                                        return attributes
+                        var result: [EnqueueMessage] = []
+                        if messageText.string.count > 0 {
+                            let inputText = convertMarkdownToAttributes(messageText)
+                            for text in breakChatInputText(trimChatInputText(inputText)) {
+                                if text.length != 0 {
+                                    var attributes: [MessageAttribute] = []
+                                    let entities = generateTextEntities(text.string, enabledTypes: .all, currentEntities: generateChatInputTextEntities(text))
+                                    if !entities.isEmpty {
+                                        attributes.append(TextEntitiesMessageAttribute(entities: entities))
                                     }
+                                    result.append(.message(text: text.string, attributes: attributes, inlineStickers: [:], mediaReference: nil, threadId: strongSelf.chatLocation.threadId, replyToMessageId: nil, replyToStoryId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: []))
                                 }
                             }
-                            
-                            let _ = (enqueueMessages(account: strongSelf.context.account, peerId: peer.id, messages: peerMessages)
-                            |> deliverOnMainQueue).startStandalone(next: { messageIds in
-                                if let strongSelf = self {
-                                    let signals: [Signal<Bool, NoError>] = messageIds.compactMap({ id -> Signal<Bool, NoError>? in
-                                        guard let id = id else {
-                                            return nil
-                                        }
-                                        return strongSelf.context.account.pendingMessageManager.pendingMessageStatus(id)
-                                        |> mapToSignal { status, _ -> Signal<Bool, NoError> in
-                                            if status != nil {
-                                                return .never()
-                                            } else {
-                                                return .single(true)
-                                            }
-                                        }
-                                        |> take(1)
-                                    })
-                                    if strongSelf.shareStatusDisposable == nil {
-                                        strongSelf.shareStatusDisposable = MetaDisposable()
-                                    }
-                                    strongSelf.shareStatusDisposable?.set((combineLatest(signals)
-                                    |> deliverOnMainQueue).startStrict())
-                                }
-                            })
-                            
-                            if case let .secretChat(secretPeer) = peer {
-                                if let peer = peerMap[secretPeer.regularPeerId] {
-                                    displayPeers.append(peer)
-                                }
-                            } else {
-                                displayPeers.append(peer)
-                            }
-                        }
-                            
-                        let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 }
-                        let text: String
-                        var savedMessages = false
-                        if displayPeers.count == 1, let peerId = displayPeers.first?.id, peerId == strongSelf.context.account.peerId {
-                            text = messages.count == 1 ? presentationData.strings.Conversation_ForwardTooltip_SavedMessages_One : presentationData.strings.Conversation_ForwardTooltip_SavedMessages_Many
-                            savedMessages = true
-                        } else {
-                            if displayPeers.count == 1, let peer = displayPeers.first {
-                                var peerName = peer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
-                                peerName = peerName.replacingOccurrences(of: "**", with: "")
-                                text = messages.count == 1 ? presentationData.strings.Conversation_ForwardTooltip_Chat_One(peerName).string : presentationData.strings.Conversation_ForwardTooltip_Chat_Many(peerName).string
-                            } else if displayPeers.count == 2, let firstPeer = displayPeers.first, let secondPeer = displayPeers.last {
-                                var firstPeerName = firstPeer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : firstPeer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
-                                firstPeerName = firstPeerName.replacingOccurrences(of: "**", with: "")
-                                var secondPeerName = secondPeer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : secondPeer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
-                                secondPeerName = secondPeerName.replacingOccurrences(of: "**", with: "")
-                                text = messages.count == 1 ? presentationData.strings.Conversation_ForwardTooltip_TwoChats_One(firstPeerName, secondPeerName).string : presentationData.strings.Conversation_ForwardTooltip_TwoChats_Many(firstPeerName, secondPeerName).string
-                            } else if let peer = displayPeers.first {
-                                var peerName = peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
-                                peerName = peerName.replacingOccurrences(of: "**", with: "")
-                                text = messages.count == 1 ? presentationData.strings.Conversation_ForwardTooltip_ManyChats_One(peerName, "\(displayPeers.count - 1)").string : presentationData.strings.Conversation_ForwardTooltip_ManyChats_Many(peerName, "\(displayPeers.count - 1)").string
-                            } else {
-                                text = ""
-                            }
                         }
                         
-                        let reactionItems: Signal<[ReactionItem], NoError>
-                        if savedMessages && messages.count > 0 {
-                            reactionItems = tagMessageReactions(context: strongSelf.context, subPeerId: nil)
-                        } else {
-                            reactionItems = .single([])
-                        }
+                        var attributes: [MessageAttribute] = []
+                        attributes.append(ForwardOptionsMessageAttribute(hideNames: forwardOptions?.hideNames == true, hideCaptions: forwardOptions?.hideCaptions == true))
                         
-                        let _ = (reactionItems
-                        |> deliverOnMainQueue).startStandalone(next: { [weak strongSelf] reactionItems in
-                            guard let strongSelf else {
-                                return
-                            }
-                            
-                            strongSelf.present(UndoOverlayController(presentationData: presentationData, content: .forward(savedMessages: savedMessages, text: text), elevatedLayout: false, position: savedMessages && messages.count > 0 ? .top : .bottom, animateInAsReplacement: true, action: { action in
-                                if savedMessages, let self, action == .info {
-                                    let _ = (self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: self.context.account.peerId))
-                                             |> deliverOnMainQueue).start(next: { [weak self] peer in
-                                        guard let self, let peer else {
-                                            return
-                                        }
-                                        guard let navigationController = self.navigationController as? NavigationController else {
-                                            return
-                                        }
-                                        self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: .peer(peer), forceOpenChat: true))
-                                    })
-                                }
-                                return false
-                            }, additionalView: (savedMessages && messages.count > 0) ? chatShareToSavedMessagesAdditionalView(strongSelf, reactionItems: reactionItems, correlationIds: correlationIds) : nil), in: .current)
+                        result.append(contentsOf: messages.map { message -> EnqueueMessage in
+                            return .forward(source: message.id, threadId: nil, grouping: .auto, attributes: attributes, correlationId: nil)
                         })
                         
-                        if displayConvertingTooltip {
+                        let commit: ([EnqueueMessage]) -> Void = { result in
+                            guard let strongSelf = self else {
+                                return
+                            }
+                            var result = result
+                            
+                            strongSelf.updateChatPresentationInterfaceState(animated: false, interactive: true, { $0.updatedInterfaceState({ $0.withoutSelectionState() }).updatedSearch(nil) })
+                            
+                            var correlationIds: [Int64] = []
+                            for i in 0 ..< result.count {
+                                let correlationId = Int64.random(in: Int64.min ... Int64.max)
+                                correlationIds.append(correlationId)
+                                result[i] = result[i].withUpdatedCorrelationId(correlationId)
+                            }
+                            
+                            let targetPeersShouldDivertSignals: [Signal<(EnginePeer, Bool), NoError>] = peers.map { peer -> Signal<(EnginePeer, Bool), NoError> in
+                                return strongSelf.shouldDivertMessagesToScheduled(targetPeer: peer, messages: result)
+                                |> map { shouldDivert -> (EnginePeer, Bool) in
+                                    return (peer, shouldDivert)
+                                }
+                            }
+                            let targetPeersShouldDivert: Signal<[(EnginePeer, Bool)], NoError> = combineLatest(targetPeersShouldDivertSignals)
+                            let _ = (targetPeersShouldDivert
+                            |> deliverOnMainQueue).startStandalone(next: { targetPeersShouldDivert in
+                                guard let strongSelf = self else {
+                                    return
+                                }
+                                
+                                var displayConvertingTooltip = false
+                                
+                                var displayPeers: [EnginePeer] = []
+                                for (peer, shouldDivert) in targetPeersShouldDivert {
+                                    var peerMessages = result
+                                    if shouldDivert {
+                                        displayConvertingTooltip = true
+                                        peerMessages = peerMessages.map { message -> EnqueueMessage in
+                                            return message.withUpdatedAttributes { attributes in
+                                                var attributes = attributes
+                                                attributes.removeAll(where: { $0 is OutgoingScheduleInfoMessageAttribute })
+                                                attributes.append(OutgoingScheduleInfoMessageAttribute(scheduleTime: Int32(Date().timeIntervalSince1970) + 10 * 24 * 60 * 60))
+                                                return attributes
+                                            }
+                                        }
+                                    }
+                                    
+                                    if let maybeAmount = sendPaidMessageStars[peer.id], let amount = maybeAmount {
+                                        peerMessages = peerMessages.map { message -> EnqueueMessage in
+                                            return message.withUpdatedAttributes { attributes in
+                                                var attributes = attributes
+                                                attributes.append(PaidStarsMessageAttribute(stars: amount, postponeSending: false))
+                                                return attributes
+                                            }
+                                        }
+                                    }
+                                    
+                                    let _ = (enqueueMessages(account: strongSelf.context.account, peerId: peer.id, messages: peerMessages)
+                                    |> deliverOnMainQueue).startStandalone(next: { messageIds in
+                                        if let strongSelf = self {
+                                            let signals: [Signal<Bool, NoError>] = messageIds.compactMap({ id -> Signal<Bool, NoError>? in
+                                                guard let id = id else {
+                                                    return nil
+                                                }
+                                                return strongSelf.context.account.pendingMessageManager.pendingMessageStatus(id)
+                                                |> mapToSignal { status, _ -> Signal<Bool, NoError> in
+                                                    if status != nil {
+                                                        return .never()
+                                                    } else {
+                                                        return .single(true)
+                                                    }
+                                                }
+                                                |> take(1)
+                                            })
+                                            if strongSelf.shareStatusDisposable == nil {
+                                                strongSelf.shareStatusDisposable = MetaDisposable()
+                                            }
+                                            strongSelf.shareStatusDisposable?.set((combineLatest(signals)
+                                            |> deliverOnMainQueue).startStrict())
+                                        }
+                                    })
+                                    
+                                    if case let .secretChat(secretPeer) = peer {
+                                        if let peer = peerMap[secretPeer.regularPeerId] {
+                                            displayPeers.append(peer)
+                                        }
+                                    } else {
+                                        displayPeers.append(peer)
+                                    }
+                                }
+                                
+                                let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 }
+                                let text: String
+                                var savedMessages = false
+                                if displayPeers.count == 1, let peerId = displayPeers.first?.id, peerId == strongSelf.context.account.peerId {
+                                    text = messages.count == 1 ? presentationData.strings.Conversation_ForwardTooltip_SavedMessages_One : presentationData.strings.Conversation_ForwardTooltip_SavedMessages_Many
+                                    savedMessages = true
+                                } else {
+                                    if displayPeers.count == 1, let peer = displayPeers.first {
+                                        var peerName = peer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
+                                        peerName = peerName.replacingOccurrences(of: "**", with: "")
+                                        text = messages.count == 1 ? presentationData.strings.Conversation_ForwardTooltip_Chat_One(peerName).string : presentationData.strings.Conversation_ForwardTooltip_Chat_Many(peerName).string
+                                    } else if displayPeers.count == 2, let firstPeer = displayPeers.first, let secondPeer = displayPeers.last {
+                                        var firstPeerName = firstPeer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : firstPeer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
+                                        firstPeerName = firstPeerName.replacingOccurrences(of: "**", with: "")
+                                        var secondPeerName = secondPeer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : secondPeer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
+                                        secondPeerName = secondPeerName.replacingOccurrences(of: "**", with: "")
+                                        text = messages.count == 1 ? presentationData.strings.Conversation_ForwardTooltip_TwoChats_One(firstPeerName, secondPeerName).string : presentationData.strings.Conversation_ForwardTooltip_TwoChats_Many(firstPeerName, secondPeerName).string
+                                    } else if let peer = displayPeers.first {
+                                        var peerName = peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
+                                        peerName = peerName.replacingOccurrences(of: "**", with: "")
+                                        text = messages.count == 1 ? presentationData.strings.Conversation_ForwardTooltip_ManyChats_One(peerName, "\(displayPeers.count - 1)").string : presentationData.strings.Conversation_ForwardTooltip_ManyChats_Many(peerName, "\(displayPeers.count - 1)").string
+                                    } else {
+                                        text = ""
+                                    }
+                                }
+                                
+                                let reactionItems: Signal<[ReactionItem], NoError>
+                                if savedMessages && messages.count > 0 {
+                                    reactionItems = tagMessageReactions(context: strongSelf.context, subPeerId: nil)
+                                } else {
+                                    reactionItems = .single([])
+                                }
+                                
+                                let _ = (reactionItems
+                                |> deliverOnMainQueue).startStandalone(next: { [weak strongSelf] reactionItems in
+                                    guard let strongSelf else {
+                                        return
+                                    }
+                                    
+                                    strongSelf.present(UndoOverlayController(presentationData: presentationData, content: .forward(savedMessages: savedMessages, text: text), elevatedLayout: false, position: savedMessages && messages.count > 0 ? .top : .bottom, animateInAsReplacement: true, action: { action in
+                                        if savedMessages, let self, action == .info {
+                                            let _ = (self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: self.context.account.peerId))
+                                                     |> deliverOnMainQueue).start(next: { [weak self] peer in
+                                                guard let self, let peer else {
+                                                    return
+                                                }
+                                                guard let navigationController = self.navigationController as? NavigationController else {
+                                                    return
+                                                }
+                                                self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: .peer(peer), forceOpenChat: true))
+                                            })
+                                        }
+                                        return false
+                                    }, additionalView: (savedMessages && messages.count > 0) ? chatShareToSavedMessagesAdditionalView(strongSelf, reactionItems: reactionItems, correlationIds: correlationIds) : nil), in: .current)
+                                })
+                                
+                                if displayConvertingTooltip {
+                                }
+                            })
                         }
-                    })
-                }
-                
-                switch mode {
-                case .generic:
-                    commit(result)
-                case .silent:
-                    let transformedMessages = strongSelf.transformEnqueueMessages(result, silentPosting: true)
-                    commit(transformedMessages)
-                case .schedule:
-                    strongSelf.presentScheduleTimePicker(completion: { [weak self] scheduleTime in
-                        if let strongSelf = self {
-                            let transformedMessages = strongSelf.transformEnqueueMessages(result, silentPosting: false, scheduleTime: scheduleTime)
+                        
+                        switch mode {
+                        case .generic:
+                            commit(result)
+                        case .silent:
+                            let transformedMessages = strongSelf.transformEnqueueMessages(result, silentPosting: true)
+                            commit(transformedMessages)
+                        case .schedule:
+                            strongSelf.presentScheduleTimePicker(completion: { [weak self] scheduleTime in
+                                if let strongSelf = self {
+                                    let transformedMessages = strongSelf.transformEnqueueMessages(result, silentPosting: false, scheduleTime: scheduleTime)
+                                    commit(transformedMessages)
+                                }
+                            })
+                        case .whenOnline:
+                            let transformedMessages = strongSelf.transformEnqueueMessages(result, silentPosting: false, scheduleTime: scheduleWhenOnlineTimestamp)
                             commit(transformedMessages)
                         }
-                    })
-                case .whenOnline:
-                    let transformedMessages = strongSelf.transformEnqueueMessages(result, silentPosting: false, scheduleTime: scheduleWhenOnlineTimestamp)
-                    commit(transformedMessages)
-                }
+                    }
+                    
+                    if totalAmount.value > 0 {
+                        let controller = chatMessagePaymentAlertController(
+                            context: nil,
+                            presentationData: strongSelf.presentationData,
+                            updatedPresentationData: nil,
+                            peers: peers,
+                            count: count,
+                            amount: totalAmount,
+                            totalAmount: totalAmount,
+                            hasCheck: false,
+                            navigationController: strongSelf.navigationController as? NavigationController,
+                            completion: { _ in
+                                proceed()
+                            }
+                        )
+                        strongSelf.present(controller, in: .window(.root))
+                    } else {
+                        proceed()
+                    }
+                })
             }
             controller.peerSelected = { [weak self, weak controller] peer, threadId in
                 guard let strongSelf = self, let strongController = controller else {
diff --git a/submodules/TelegramUI/Sources/ChatTextInputPanelNode.swift b/submodules/TelegramUI/Sources/ChatTextInputPanelNode.swift
index e8175ac0a6..f44aa7f749 100644
--- a/submodules/TelegramUI/Sources/ChatTextInputPanelNode.swift
+++ b/submodules/TelegramUI/Sources/ChatTextInputPanelNode.swift
@@ -1927,8 +1927,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate, Ch
                                 }
                             } else {
                                 if let sendPaidMessageStars = interfaceState.sendPaidMessageStars {
-                                    //TODO:localize
-                                    placeholder = "Message for  # \(presentationStringsFormattedNumber(Int32(sendPaidMessageStars.value), interfaceState.dateTimeFormat.groupingSeparator))"
+                                    placeholder = interfaceState.strings.Chat_InputTextPaidMessagePlaceholder(" # \(presentationStringsFormattedNumber(Int32(sendPaidMessageStars.value), interfaceState.dateTimeFormat.groupingSeparator))").string
                                     placeholderHasStar = true
                                 } else {
                                     placeholder = interfaceState.strings.Conversation_InputTextPlaceholder