diff --git a/Telegram/SourceFiles/boxes/sticker_set_box.cpp b/Telegram/SourceFiles/boxes/sticker_set_box.cpp
index d9d3b9a6f..275cf3f73 100644
--- a/Telegram/SourceFiles/boxes/sticker_set_box.cpp
+++ b/Telegram/SourceFiles/boxes/sticker_set_box.cpp
@@ -82,7 +82,8 @@ using TLStickerSet = MTPmessages_StickerSet;
 
 [[nodiscard]] std::optional<QColor> ComputeImageColor(
 		const style::icon &lockIcon,
-		const QImage &frame) {
+		const QImage &frame,
+		RectPart part) {
 	if (frame.isNull()
 		|| frame.format() != QImage::Format_ARGB32_Premultiplied) {
 		return {};
@@ -91,13 +92,29 @@ using TLStickerSet = MTPmessages_StickerSet;
 	auto sg = int64();
 	auto sb = int64();
 	auto sa = int64();
-	const auto factor = frame.devicePixelRatio();
+	const auto factor = style::DevicePixelRatio();
 	const auto size = lockIcon.size() * factor;
 	const auto width = std::min(frame.width(), size.width());
 	const auto height = std::min(frame.height(), size.height());
-	const auto skipx = (frame.width() - width) / 2;
 	const auto radius = st::roundRadiusSmall;
-	const auto skipy = std::max(frame.height() - height - radius, 0);
+	const auto skipx = (part == RectPart::TopLeft
+		|| part == RectPart::Left
+		|| part == RectPart::BottomLeft)
+		? 0
+		: (part == RectPart::Top
+			|| part == RectPart::Center
+			|| part == RectPart::Bottom)
+		? (frame.width() - width) / 2
+		: std::max(frame.width() - width - radius, 0);
+	const auto skipy = (part == RectPart::TopLeft
+		|| part == RectPart::Top
+		|| part == RectPart::TopRight)
+		? 0
+		: (part == RectPart::Left
+			|| part == RectPart::Center
+			|| part == RectPart::Right)
+		? (frame.height() - height) / 2
+		: std::max(frame.height() - height - radius, 0);
 	const auto perline = frame.bytesPerLine();
 	const auto addperline = perline - (width * 4);
 	auto bits = static_cast<const uchar*>(frame.bits())
@@ -121,17 +138,20 @@ using TLStickerSet = MTPmessages_StickerSet;
 
 [[nodiscard]] QColor ComputeLockColor(
 		const style::icon &lockIcon,
-		const QImage &frame) {
+		const QImage &frame,
+		RectPart part) {
 	return ComputeImageColor(
 		lockIcon,
-		frame
+		frame,
+		part
 	).value_or(st::windowSubTextFg->c);
 }
 
 void ValidatePremiumLockBg(
 		const style::icon &lockIcon,
 		QImage &image,
-		const QImage &frame) {
+		const QImage &frame,
+		RectPart part) {
 	if (!image.isNull()) {
 		return;
 	}
@@ -142,7 +162,7 @@ void ValidatePremiumLockBg(
 		QImage::Format_ARGB32_Premultiplied);
 	image.setDevicePixelRatio(factor);
 	auto p = QPainter(&image);
-	const auto color = ComputeLockColor(lockIcon, frame);
+	const auto color = ComputeLockColor(lockIcon, frame, part);
 	p.fillRect(
 		QRect(QPoint(), size),
 		anim::color(color, st::windowSubTextFg, kGrayLockOpacity));
@@ -195,8 +215,10 @@ void ValidatePremiumStarFg(const style::icon &lockIcon, QImage &image) {
 
 StickerPremiumMark::StickerPremiumMark(
 	not_null<Main::Session*> session,
-	const style::icon &lockIcon)
-: _lockIcon(lockIcon) {
+	const style::icon &lockIcon,
+	RectPart part)
+: _lockIcon(lockIcon)
+, _part(part) {
 	style::PaletteChanged(
 	) | rpl::start_with_next([=] {
 		_lockGray = QImage();
@@ -221,9 +243,13 @@ void StickerPremiumMark::paint(
 	const auto &bg = frame.isNull() ? _lockGray : backCache;
 	const auto factor = style::DevicePixelRatio();
 	const auto radius = st::roundRadiusSmall;
-	const auto point = position + QPoint(
-		(singleSize.width() - (bg.width() / factor) - radius),
-		singleSize.height() - (bg.height() / factor) - radius);
+	const auto shiftx = (_part == RectPart::Center)
+		? (singleSize.width() - (bg.width() / factor)) / 2
+		: (singleSize.width() - (bg.width() / factor) - radius);
+	const auto shifty = (_part == RectPart::Center)
+		? (singleSize.height() - (bg.height() / factor)) / 2
+		: (singleSize.height() - (bg.height() / factor) - radius);
+	const auto point = position + QPoint(shiftx, shifty);
 	p.drawImage(point, bg);
 	if (_premium) {
 		validateStar();
@@ -237,7 +263,7 @@ void StickerPremiumMark::validateLock(
 		const QImage &frame,
 		QImage &backCache) {
 	auto &image = frame.isNull() ? _lockGray : backCache;
-	ValidatePremiumLockBg(_lockIcon, image, frame);
+	ValidatePremiumLockBg(_lockIcon, image, frame, _part);
 }
 
 void StickerPremiumMark::validateStar() {
diff --git a/Telegram/SourceFiles/boxes/sticker_set_box.h b/Telegram/SourceFiles/boxes/sticker_set_box.h
index e718cc45e..07e0168e2 100644
--- a/Telegram/SourceFiles/boxes/sticker_set_box.h
+++ b/Telegram/SourceFiles/boxes/sticker_set_box.h
@@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 #include "ui/layers/box_content.h"
 #include "base/timer.h"
 #include "data/stickers/data_stickers.h"
+#include "ui/rect_part.h"
 
 namespace Window {
 class SessionController;
@@ -32,7 +33,8 @@ class StickerPremiumMark final {
 public:
 	StickerPremiumMark(
 		not_null<Main::Session*> session,
-		const style::icon &lockIcon);
+		const style::icon &lockIcon,
+		RectPart part = RectPart::Bottom);
 
 	void paint(
 		QPainter &p,
@@ -49,6 +51,7 @@ private:
 	const style::icon &_lockIcon;
 	QImage _lockGray;
 	QImage _star;
+	RectPart _part = RectPart::Bottom;
 	bool _premium = false;
 
 	rpl::lifetime _lifetime;
diff --git a/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_common.cpp b/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_common.cpp
index 565ee6c7a..dc236146a 100644
--- a/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_common.cpp
+++ b/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_common.cpp
@@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 */
 #include "info/peer_gifts/info_peer_gifts_common.h"
 
+#include "boxes/sticker_set_box.h"
 #include "chat_helpers/stickers_gift_box_pack.h"
 #include "chat_helpers/stickers_lottie.h"
 #include "core/ui_integration.h"
@@ -159,6 +160,8 @@ void GiftButton::resizeEvent(QResizeEvent *e) {
 
 void GiftButton::paintEvent(QPaintEvent *e) {
 	auto p = QPainter(this);
+	const auto hidden = v::is<GiftTypeStars>(_descriptor)
+		&& v::get<GiftTypeStars>(_descriptor).hidden;;
 	const auto position = QPoint(_extend.left(), _extend.top());
 	const auto background = _delegate->background();
 	const auto dpr = int(background.devicePixelRatio());
@@ -193,6 +196,7 @@ void GiftButton::paintEvent(QPaintEvent *e) {
 		p.drawImage(_extend.left() + skip, _extend.top() + skip, image);
 	}
 
+	auto frame = QImage();
 	if (_player && _player->ready()) {
 		const auto paused = !isOver();
 		auto info = _player->frame(
@@ -201,11 +205,12 @@ void GiftButton::paintEvent(QPaintEvent *e) {
 			false,
 			crl::now(),
 			paused);
+		frame = info.image;
 		const auto finished = (info.index + 1 == _player->framesCount());
 		if (!finished || !paused) {
 			_player->markFrameShown();
 		}
-		const auto size = info.image.size() / style::DevicePixelRatio();
+		const auto size = frame.size() / style::DevicePixelRatio();
 		p.drawImage(
 			QRect(
 				(width - size.width()) / 2,
@@ -214,7 +219,21 @@ void GiftButton::paintEvent(QPaintEvent *e) {
 					: st::giftBoxStickerTop),
 				size.width(),
 				size.height()),
-			info.image);
+			frame);
+	}
+	if (hidden) {
+		const auto topleft = QPoint(
+			(width - st::giftBoxStickerSize.width()) / 2,
+			(_text.isEmpty()
+				? st::giftBoxStickerStarTop
+				: st::giftBoxStickerTop));
+		_delegate->hiddenMark()->paint(
+			p,
+			frame,
+			_hiddenBgCache,
+			topleft,
+			st::giftBoxStickerSize,
+			width);
 	}
 
 	auto hq = PainterHighQualityEnabler(p);
@@ -290,9 +309,16 @@ void GiftButton::paintEvent(QPaintEvent *e) {
 }
 
 Delegate::Delegate(not_null<Window::SessionController*> window)
-: _window(window) {
+: _window(window)
+, _hiddenMark(std::make_unique<StickerPremiumMark>(
+	&window->session(),
+	st::giftBoxHiddenMark,
+	RectPart::Center)) {
 }
 
+Delegate::Delegate(Delegate &&other) = default;
+
+Delegate::~Delegate() = default;
 
 TextWithEntities Delegate::star() {
 	const auto owner = &_window->session().data();
@@ -385,4 +411,8 @@ DocumentData *Delegate::lookupSticker(const GiftDescriptor &descriptor) {
 	});
 }
 
+not_null<StickerPremiumMark*> Delegate::hiddenMark() {
+	return _hiddenMark.get();
+}
+
 } // namespace Info::PeerGifts
diff --git a/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_common.h b/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_common.h
index c53ce9503..b8188454d 100644
--- a/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_common.h
+++ b/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_common.h
@@ -10,6 +10,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 #include "ui/abstract_button.h"
 #include "ui/text/text.h"
 
+class StickerPremiumMark;
+
 namespace HistoryView {
 class StickerPlayer;
 } // namespace HistoryView
@@ -43,6 +45,7 @@ struct GiftTypeStars {
 	PeerData *from = nullptr;
 	int limitedCount = 0;
 	bool userpic = false;
+	bool hidden = false;
 	bool mine = false;
 
 	[[nodiscard]] friend inline bool operator==(
@@ -67,6 +70,7 @@ public:
 	[[nodiscard]] virtual QImage background() = 0;
 	[[nodiscard]] virtual DocumentData *lookupSticker(
 		const GiftDescriptor &descriptor) = 0;
+	[[nodiscard]] virtual not_null<StickerPremiumMark*> hiddenMark() = 0;
 };
 
 class GiftButton final : public Ui::AbstractButton {
@@ -85,6 +89,7 @@ private:
 	void unsubscribe();
 
 	const not_null<GiftButtonDelegate*> _delegate;
+	QImage _hiddenBgCache;
 	GiftDescriptor _descriptor;
 	Ui::Text::String _text;
 	Ui::Text::String _price;
@@ -102,6 +107,8 @@ private:
 class Delegate final : public GiftButtonDelegate {
 public:
 	explicit Delegate(not_null<Window::SessionController*> window);
+	Delegate(Delegate &&other);
+	~Delegate();
 
 	TextWithEntities star() override;
 	std::any textContext() override;
@@ -109,9 +116,11 @@ public:
 	QMargins buttonExtend() override;
 	QImage background() override;
 	DocumentData *lookupSticker(const GiftDescriptor &descriptor) override;
+	not_null<StickerPremiumMark*> hiddenMark() override;
 
 private:
 	const not_null<Window::SessionController*> _window;
+	std::unique_ptr<StickerPremiumMark> _hiddenMark;
 	QSize _single;
 	QImage _bg;
 
diff --git a/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_widget.cpp b/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_widget.cpp
index a10942055..a455dd3aa 100644
--- a/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_widget.cpp
+++ b/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_widget.cpp
@@ -40,6 +40,7 @@ constexpr auto kPerPage = 50;
 			: to->owner().peer(gift.fromId).get()),
 		.limitedCount = gift.gift.limitedCount,
 		.userpic = true,
+		.hidden = gift.hidden,
 		.mine = to->isSelf(),
 	};
 }
diff --git a/Telegram/SourceFiles/ui/effects/credits.style b/Telegram/SourceFiles/ui/effects/credits.style
index ff3d718b3..1209ba052 100644
--- a/Telegram/SourceFiles/ui/effects/credits.style
+++ b/Telegram/SourceFiles/ui/effects/credits.style
@@ -125,3 +125,4 @@ giftBoxTextField: InputField(defaultInputField) {
 	style: defaultTextStyle;
 }
 giftBoxTextPadding: margins(20px, 15px, 20px, 11px);
+giftBoxHiddenMark: icon{{ "menu/stealth", premiumButtonFg }};