UNPKG

@pump-fun/shared-contracts

Version:

Shared contracts for Pump.fun microservices.

228 lines (198 loc) 5.29 kB
/** * Core notification types for the Pump.fun notification system */ import type { PumpDeeplinks } from "./deep-links"; // ============================================ // CONSTANTS // ============================================ /** * Available FCM topics * * Current usage: * - GLOBAL: Currently used for all article/news notifications (temporary) * - NEWS: Reserved for future migration of article notifications * - TRENDING: Reserved for trending/popular content notifications */ export const TOPICS = { GLOBAL: "global" as const, NEWS: "news" as const, TRENDING: "trending" as const, } as const; /** * Notification type identifiers */ export const NOTIFICATION_TYPES = { ARTICLE_PUBLISHED: "ARTICLE_PUBLISHED" as const, PORTFOLIO_LIVESTREAM_STARTED: "PORTFOLIO_LIVESTREAM_STARTED" as const, PORTFOLIO_PNL_ALERT: "PORTFOLIO_PNL_ALERT" as const, } as const; /** * String union type of all notification types */ export type NotificationType = (typeof NOTIFICATION_TYPES)[keyof typeof NOTIFICATION_TYPES]; // ============================================ // NOTIFICATION CONTENT TYPES // ============================================ /** * Base structure for all notification content data */ export interface BaseNotificationData { notificationId: string; notificationType: NotificationType; deeplink: PumpDeeplinks; } /** * Livestream started notification content */ export interface LivestreamStartedData extends BaseNotificationData { notificationType: "PORTFOLIO_LIVESTREAM_STARTED"; livestreamId: string; creatorAddress: string; creatorUsername: string; mintId: string; tokenAmount: string; } /** * Article published notification content */ export interface ArticlePublishedData extends BaseNotificationData { notificationType: "ARTICLE_PUBLISHED"; articleId: string; documentId: string; mintId: string; timestamp: string; locale: string; } export interface PortfolioPnlData extends BaseNotificationData { notificationType: "PORTFOLIO_PNL_ALERT"; mintId: string; pnlPercent: number; tickerName: string; timestamp: string; } /** * Union of all notification content types */ export type NotificationData = LivestreamStartedData | ArticlePublishedData | PortfolioPnlData; // ============================================ // NOTIFICATION DELIVERY TYPES // ============================================ /** * Individual user targeting */ export interface IndividualTarget { type: "individual"; walletAddress: string; } /** * Topic-based broadcast targeting */ export interface TopicTarget { type: "topic"; topic: "global" | "news" | "announcements"; } /** * Union of all targeting types */ export type NotificationTarget = IndividualTarget | TopicTarget; // ============================================ // COMPLETE NOTIFICATION TYPE // ============================================ /** * A complete push notification ready to be sent */ export interface PushNotification { /** * Unique identifier for this notification instance */ id: string; /** * Display content */ title: string; body: string; /** * Structured data payload */ data: NotificationData; /** * Delivery target */ target: NotificationTarget; /** * Metadata */ timestamp: number; priority?: "normal" | "high"; ttl?: number; // Time to live in seconds } // ============================================ // FACTORY FUNCTIONS // ============================================ /** * Create an individual notification */ export function createIndividualNotification(params: { id: string; title: string; body: string; data: LivestreamStartedData | ArticlePublishedData; walletAddress: string; priority?: "normal" | "high"; ttl?: number; }): PushNotification { return { body: params.body, data: params.data, id: params.id, priority: params.priority, target: { type: "individual", walletAddress: params.walletAddress, }, timestamp: Date.now(), title: params.title, ttl: params.ttl, }; } /** * Create a topic broadcast notification */ export function createTopicNotification(params: { id: string; title: string; body: string; data: ArticlePublishedData; topic: TopicTarget["topic"]; priority?: "normal" | "high"; ttl?: number; }): PushNotification { return { body: params.body, data: params.data, id: params.id, priority: params.priority, target: { topic: params.topic, type: "topic", }, timestamp: Date.now(), title: params.title, ttl: params.ttl, }; } // ============================================ // TYPE GUARDS // ============================================ export function isIndividualTarget(target: NotificationTarget): target is IndividualTarget { return target.type === "individual"; } export function isTopicTarget(target: NotificationTarget): target is TopicTarget { return target.type === "topic"; } export function isLivestreamNotification(data: NotificationData): data is LivestreamStartedData { return data.notificationType === "PORTFOLIO_LIVESTREAM_STARTED"; } export function isArticleNotification(data: NotificationData): data is ArticlePublishedData { return data.notificationType === "ARTICLE_PUBLISHED"; }