diff --git a/components/settings/delete-account-modal.tsx b/components/settings/delete-account-modal.tsx
new file mode 100644
index 00000000..232a3872
--- /dev/null
+++ b/components/settings/delete-account-modal.tsx
@@ -0,0 +1,553 @@
+'use client'
+
+import { useState, useEffect } from 'react'
+import { useRouter } from 'next/navigation'
+import { Button } from '@/components/ui/button'
+import { X, Loader2, AlertTriangle, Trash2, CheckCircle, XCircle } from 'lucide-react'
+import { motion, AnimatePresence } from 'framer-motion'
+import { useDeleteAccountModal } from '@/hooks/use-delete-account-modal'
+import { useAuth } from '@/contexts/auth-context'
+import { accountDeletionService, DeletionProgress } from '@/lib/services/account-deletion-service'
+
+/**
+ * Delete Account Modal
+ *
+ * Multi-step modal for permanent account deletion:
+ * 1. Warning - explain what will be deleted
+ * 2. Confirm - type "DELETE" to confirm
+ * 3. Progress - show deletion progress
+ * 4. Complete/Error - show result
+ */
+export function DeleteAccountModal() {
+ const router = useRouter()
+ const { user, logout } = useAuth()
+ const {
+ isOpen,
+ step,
+ progress,
+ result,
+ documentCounts,
+ isLoadingCounts,
+ setStep,
+ setProgress,
+ setResult,
+ setDocumentCounts,
+ setIsLoadingCounts,
+ reset
+ } = useDeleteAccountModal()
+
+ const [confirmText, setConfirmText] = useState('')
+ const [understood, setUnderstood] = useState(false)
+ const [isDeleting, setIsDeleting] = useState(false)
+
+ // Load document counts when modal opens
+ useEffect(() => {
+ const loadCounts = async () => {
+ if (!user?.identityId) return
+
+ setIsLoadingCounts(true)
+ try {
+ const counts = await accountDeletionService.countUserDocuments(user.identityId)
+ setDocumentCounts(counts)
+ } catch (error) {
+ console.error('Failed to load document counts:', error)
+ // Continue anyway - counts are just informational
+ setDocumentCounts({})
+ } finally {
+ setIsLoadingCounts(false)
+ }
+ }
+
+ if (isOpen && step === 'warning' && user?.identityId && documentCounts === null && !isLoadingCounts) {
+ void loadCounts()
+ }
+ }, [isOpen, step, user?.identityId, documentCounts, isLoadingCounts, setIsLoadingCounts, setDocumentCounts])
+
+ const handleClose = () => {
+ if (isDeleting) return // Prevent closing during deletion
+ setConfirmText('')
+ setUnderstood(false)
+ reset()
+ }
+
+ const handleStartDeletion = async () => {
+ if (!user?.identityId) return
+
+ setIsDeleting(true)
+ setStep('progress')
+
+ try {
+ const deletionResult = await accountDeletionService.deleteAccount(
+ user.identityId,
+ (progressUpdate: DeletionProgress) => {
+ setProgress(progressUpdate)
+ }
+ )
+
+ setResult(deletionResult)
+
+ if (deletionResult.success) {
+ setStep('complete')
+ } else if (deletionResult.partialFailure) {
+ setStep('error')
+ } else {
+ setStep('error')
+ }
+ } catch (error) {
+ console.error('Deletion failed:', error)
+ setResult({
+ success: false,
+ totalDeleted: 0,
+ totalFailed: 0,
+ errors: [{
+ contractId: 'unknown',
+ documentType: 'unknown',
+ documentId: 'unknown',
+ error: error instanceof Error ? error.message : 'Unknown error'
+ }],
+ partialFailure: false
+ })
+ setStep('error')
+ } finally {
+ setIsDeleting(false)
+ }
+ }
+
+ const handleCompleteLogout = async () => {
+ try {
+ await logout()
+ } catch (error) {
+ console.error('Failed to logout after account deletion:', error)
+ // Navigate to login even if logout fails
+ router.push('/login')
+ } finally {
+ handleClose()
+ }
+ }
+
+ const getTotalDocuments = () => {
+ if (!documentCounts) return 0
+ return Object.values(documentCounts).reduce((sum, count) => sum + count, 0)
+ }
+
+ const deletionSummary = accountDeletionService.getDeletionSummary()
+
+ // Render warning step
+ const renderWarningStep = () => (
+
+ {/* Icon */}
+
+
+
Delete Your Account
+
+
+ This will permanently delete all your data from Dash Platform.
+
+
+ {/* Document counts */}
+ {isLoadingCounts ? (
+
+
+
Counting your documents...
+
+ ) : documentCounts && getTotalDocuments() > 0 ? (
+
+
+ You have {getTotalDocuments()} documents to delete:
+
+
+ {Object.entries(documentCounts).map(([type, count]) => (
+
+ {type.replace(/([A-Z])/g, ' $1').trim()}
+ {count}
+
+ ))}
+
+
+ ) : null}
+
+ {/* What will be deleted */}
+
+
+
+ What will be deleted:
+
+
+ {deletionSummary.map((category) => (
+
+
{category.category}
+
+ {category.items.map((item, i) => (
+ {item}
+ ))}
+
+
+ ))}
+
+
+
+ {/* Third-party warning */}
+
+
+
+
+
+ Important Notice
+
+
+ While your data will be deleted from Dash Platform, third-party indexers or explorers may retain historical copies .
+ The blockchain itself doesn't keep document history, but external services that have indexed your data may still have copies.
+
+
+
+
+
+ {/* Consent checkbox */}
+
+ setUnderstood(e.target.checked)}
+ className="mt-1 h-4 w-4 text-red-600 focus:ring-red-500 border-gray-300 rounded"
+ />
+
+ I understand this action is permanent and cannot be undone
+
+
+
+
+
+ Cancel
+
+ setStep('confirm')}
+ >
+ Continue
+
+
+
+ )
+
+ // Render confirm step
+ const renderConfirmStep = () => (
+
+
+
+
Confirm Deletion
+
+
+ To confirm, type DELETE below
+
+
+
+ setConfirmText(e.target.value.toUpperCase())}
+ placeholder="Type DELETE to confirm"
+ className="w-full px-4 py-3 bg-gray-50 dark:bg-gray-950 border border-gray-200 dark:border-gray-800 rounded-lg text-center text-lg font-mono tracking-widest focus:outline-none focus:ring-2 focus:ring-red-500 focus:border-transparent transition-colors"
+ autoComplete="off"
+ autoCorrect="off"
+ autoCapitalize="characters"
+ />
+
+
+
+ {
+ setConfirmText('')
+ setStep('warning')
+ }}
+ >
+ Go Back
+
+
+ Delete My Account
+
+
+
+ )
+
+ // Render progress step
+ const renderProgressStep = () => {
+ const progressPercent = progress
+ ? Math.round((progress.processedDocuments / Math.max(progress.totalDocuments, 1)) * 100)
+ : 0
+
+ return (
+
+
+
+
Deleting Your Data
+
+
+ Please wait while we delete your documents...
+
+
+ {/* Progress bar */}
+
+
+
+ {progress?.processedDocuments || 0} / {progress?.totalDocuments || 0} documents processed
+
+
+
+ {/* Current operation */}
+ {progress && (
+
+
+ {progress.phase === 'counting' && 'Counting documents...'}
+ {progress.phase === 'deleting' && (
+ <>Deleting {progress.currentDocumentType} from {progress.currentContract}...>
+ )}
+ {progress.phase === 'cleanup' && 'Cleaning up local data...'}
+
+
+ )}
+
+ {/* Stats */}
+ {progress && progress.processedDocuments > 0 && (
+
+
+
{progress.deletedDocuments}
+
Deleted
+
+ {progress.failedDocuments > 0 && (
+
+
{progress.failedDocuments}
+
Failed
+
+ )}
+
+ )}
+
+
+ Do not close this window
+
+
+ )
+ }
+
+ // Render complete step
+ const renderCompleteStep = () => (
+
+
+
+
Account Deleted
+
+
+ Your account data has been successfully deleted from Dash Platform.
+
+
+ {result && (
+
+
+ {result.totalDeleted} documents deleted
+
+
+ )}
+
+
+ Return to Login
+
+
+ )
+
+ // Render error step
+ const renderErrorStep = () => (
+
+
+
+
+ {result?.partialFailure ? 'Partial Deletion' : 'Deletion Failed'}
+
+
+
+ {result?.partialFailure
+ ? 'Some documents could not be deleted. You may try again later.'
+ : 'We encountered an error while deleting your data.'}
+
+
+ {result && (
+
+ {result.totalDeleted > 0 && (
+
+
+ {result.totalDeleted} documents successfully deleted
+
+
+ )}
+
+ {result.totalFailed > 0 && (
+
+
+ {result.totalFailed} documents failed to delete
+
+ {result.errors.length > 0 && result.errors.length <= 5 && (
+
+ {result.errors.map((err, i) => (
+
+ {err.documentType}: {err.error}
+
+ ))}
+
+ )}
+
+ )}
+
+ )}
+
+
+ {result?.partialFailure ? (
+ <>
+
+ Continue Anyway
+
+ {
+ setConfirmText('')
+ setStep('warning')
+ }}
+ >
+ Try Again
+
+ >
+ ) : (
+ <>
+
+ Cancel
+
+ {
+ setConfirmText('')
+ setStep('warning')
+ }}
+ >
+ Try Again
+
+ >
+ )}
+
+
+ )
+
+ const renderStep = () => {
+ switch (step) {
+ case 'warning':
+ return renderWarningStep()
+ case 'confirm':
+ return renderConfirmStep()
+ case 'progress':
+ return renderProgressStep()
+ case 'complete':
+ return renderCompleteStep()
+ case 'error':
+ return renderErrorStep()
+ default:
+ return renderWarningStep()
+ }
+ }
+
+ return (
+
+ {isOpen && (
+ <>
+ {/* Backdrop */}
+
+
+ {/* Modal */}
+
+
+ {/* Close button - hidden during deletion */}
+ {!isDeleting && step !== 'progress' && (
+
+
+
+ )}
+
+ {renderStep()}
+
+
+ >
+ )}
+
+ )
+}
diff --git a/hooks/use-delete-account-modal.ts b/hooks/use-delete-account-modal.ts
new file mode 100644
index 00000000..60a1732c
--- /dev/null
+++ b/hooks/use-delete-account-modal.ts
@@ -0,0 +1,52 @@
+import { create } from 'zustand'
+import { DeletionProgress, DeletionResult, DocumentCounts } from '@/lib/services/account-deletion-service'
+
+export type DeleteAccountStep = 'warning' | 'confirm' | 'progress' | 'complete' | 'error'
+
+interface DeleteAccountModalStore {
+ isOpen: boolean
+ step: DeleteAccountStep
+ progress: DeletionProgress | null
+ result: DeletionResult | null
+ documentCounts: DocumentCounts | null
+ isLoadingCounts: boolean
+
+ // Actions
+ open: () => void
+ close: () => void
+ setStep: (step: DeleteAccountStep) => void
+ setProgress: (progress: DeletionProgress) => void
+ setResult: (result: DeletionResult) => void
+ setDocumentCounts: (counts: DocumentCounts) => void
+ setIsLoadingCounts: (loading: boolean) => void
+ reset: () => void
+}
+
+const initialState = {
+ isOpen: false,
+ step: 'warning' as DeleteAccountStep,
+ progress: null,
+ result: null,
+ documentCounts: null,
+ isLoadingCounts: false
+}
+
+export const useDeleteAccountModal = create
((set) => ({
+ ...initialState,
+
+ open: () => set({ isOpen: true, step: 'warning' }),
+
+ close: () => set({ isOpen: false }),
+
+ setStep: (step) => set({ step }),
+
+ setProgress: (progress) => set({ progress }),
+
+ setResult: (result) => set({ result }),
+
+ setDocumentCounts: (documentCounts) => set({ documentCounts }),
+
+ setIsLoadingCounts: (isLoadingCounts) => set({ isLoadingCounts }),
+
+ reset: () => set(initialState)
+}))
diff --git a/lib/services/account-deletion-service.ts b/lib/services/account-deletion-service.ts
new file mode 100644
index 00000000..bca07b04
--- /dev/null
+++ b/lib/services/account-deletion-service.ts
@@ -0,0 +1,484 @@
+import { getEvoSdk } from './evo-sdk-service'
+import { stateTransitionService } from './state-transition-service'
+import { queryDocuments, identifierToBase58 } from './sdk-helpers'
+import {
+ YAPPR_CONTRACT_ID,
+ YAPPR_PROFILE_CONTRACT_ID,
+ YAPPR_DM_CONTRACT_ID,
+ YAPPR_BLOCK_CONTRACT_ID,
+ ENCRYPTED_KEY_BACKUP_CONTRACT_ID,
+ HASHTAG_CONTRACT_ID
+} from '../constants'
+
+/**
+ * Registry entry for a contract and its deletable document types
+ */
+interface DeletionRegistry {
+ contractId: string
+ documentTypes: string[]
+ serviceName: string
+}
+
+/**
+ * Information about a document to be deleted
+ */
+interface DocumentInfo {
+ $id: string
+ $ownerId: string
+ documentType: string
+ contractId: string
+}
+
+/**
+ * Progress update during deletion
+ */
+export interface DeletionProgress {
+ phase: 'counting' | 'deleting' | 'cleanup' | 'complete' | 'failed'
+ currentContract: string
+ currentDocumentType: string
+ totalDocuments: number
+ processedDocuments: number
+ deletedDocuments: number
+ failedDocuments: number
+ errors: Array<{
+ contractId: string
+ documentType: string
+ documentId: string
+ error: string
+ }>
+}
+
+/**
+ * Result of account deletion
+ */
+export interface DeletionResult {
+ success: boolean
+ totalDeleted: number
+ totalFailed: number
+ errors: DeletionProgress['errors']
+ partialFailure: boolean
+}
+
+/**
+ * Document counts by type for display
+ */
+export interface DocumentCounts {
+ [documentType: string]: number
+}
+
+/**
+ * Account Deletion Service
+ *
+ * Handles comprehensive deletion of all user documents across all Yappr contracts.
+ * Uses a registry-based architecture for easy extensibility when new document types are added.
+ */
+class AccountDeletionService {
+ /**
+ * Registry of all contracts and document types that should be deleted.
+ *
+ * IMPORTANT: When adding new document types to Yappr, add them here to ensure
+ * they are deleted during account deletion.
+ */
+ private readonly registry: DeletionRegistry[] = [
+ // Main Yappr contract - social features
+ {
+ contractId: YAPPR_CONTRACT_ID,
+ documentTypes: [
+ 'post', // User's posts
+ 'like', // User's likes
+ 'repost', // User's reposts
+ 'follow', // Users this user follows
+ 'bookmark', // User's bookmarks
+ 'list', // User's custom lists
+ 'listMember', // Members in user's lists
+ 'notification', // User's notifications
+ 'profile', // User's profile (old contract)
+ 'avatar', // User's avatar
+ ],
+ serviceName: 'Main Social'
+ },
+ // Unified profile contract
+ {
+ contractId: YAPPR_PROFILE_CONTRACT_ID,
+ documentTypes: ['profile'],
+ serviceName: 'Profile'
+ },
+ // Direct messages contract
+ {
+ contractId: YAPPR_DM_CONTRACT_ID,
+ documentTypes: ['directMessage'],
+ serviceName: 'Direct Messages'
+ },
+ // Block/mute contract
+ {
+ contractId: YAPPR_BLOCK_CONTRACT_ID,
+ documentTypes: [
+ 'block', // Blocked users
+ 'blockFilter', // Bloom filter for blocks
+ 'blockFollow', // Block follows
+ 'mute', // Muted users
+ ],
+ serviceName: 'Block System'
+ },
+ // Encrypted key backup contract
+ {
+ contractId: ENCRYPTED_KEY_BACKUP_CONTRACT_ID,
+ documentTypes: ['encryptedKeyBackup'],
+ serviceName: 'Key Backup'
+ },
+ // Hashtag tracking contract
+ {
+ contractId: HASHTAG_CONTRACT_ID,
+ documentTypes: ['postHashtag'],
+ serviceName: 'Hashtags'
+ }
+ ]
+
+ /**
+ * Batch size for concurrent deletions within a document type
+ */
+ private readonly BATCH_SIZE = 3
+
+ /**
+ * Delay between batches to avoid rate limiting (ms)
+ */
+ private readonly BATCH_DELAY_MS = 500
+
+ /**
+ * Maximum documents to query per request (Platform limit)
+ */
+ private readonly QUERY_LIMIT = 100
+
+ /**
+ * Count all user documents across all contracts
+ */
+ async countUserDocuments(userId: string): Promise {
+ const counts: DocumentCounts = {}
+
+ for (const entry of this.registry) {
+ for (const documentType of entry.documentTypes) {
+ try {
+ const documents = await this.queryUserDocuments(
+ entry.contractId,
+ documentType,
+ userId
+ )
+ if (documents.length > 0) {
+ counts[documentType] = documents.length
+ }
+ } catch (error) {
+ // Log but continue - some document types may not exist for this user
+ console.warn(`Failed to count ${documentType}:`, error)
+ }
+ }
+ }
+
+ return counts
+ }
+
+ /**
+ * Query all documents owned by a user for a specific type
+ * Handles pagination for users with many documents
+ * Uses queryDocuments from sdk-helpers for proper error handling
+ */
+ private async queryUserDocuments(
+ contractId: string,
+ documentType: string,
+ userId: string
+ ): Promise {
+ const sdk = await getEvoSdk()
+ const allDocuments: DocumentInfo[] = []
+ let startAfter: string | undefined = undefined
+
+ // Paginate through all documents
+ while (true) {
+ try {
+ const documents = await queryDocuments(sdk, {
+ dataContractId: contractId,
+ documentTypeName: documentType,
+ where: [['$ownerId', '==', userId]],
+ orderBy: [['$createdAt', 'asc']],
+ limit: this.QUERY_LIMIT,
+ startAfter
+ })
+
+ if (documents.length === 0) {
+ break
+ }
+
+ // Add documents with metadata
+ for (const doc of documents) {
+ const docId = identifierToBase58(doc.$id) || (doc.$id as string) || (doc.id as string)
+ const ownerId = identifierToBase58(doc.$ownerId) || (doc.$ownerId as string) || (doc.ownerId as string) || userId
+
+ allDocuments.push({
+ $id: docId,
+ $ownerId: ownerId,
+ documentType,
+ contractId
+ })
+ }
+
+ // Check if we need to paginate
+ if (documents.length < this.QUERY_LIMIT) {
+ break
+ }
+
+ // Use last document ID for pagination
+ const lastDoc = documents[documents.length - 1]
+ startAfter = identifierToBase58(lastDoc.$id) || (lastDoc.$id as string) || (lastDoc.id as string)
+ } catch (error) {
+ // Some document types may fail to query (e.g., not registered)
+ console.warn(`Query failed for ${documentType} in contract ${contractId}:`, error)
+ break
+ }
+ }
+
+ return allDocuments
+ }
+
+ /**
+ * Delete all user documents with progress callback
+ */
+ async deleteAllUserDocuments(
+ userId: string,
+ onProgress: (progress: DeletionProgress) => void
+ ): Promise {
+ const progress: DeletionProgress = {
+ phase: 'counting',
+ currentContract: '',
+ currentDocumentType: '',
+ totalDocuments: 0,
+ processedDocuments: 0,
+ deletedDocuments: 0,
+ failedDocuments: 0,
+ errors: []
+ }
+
+ // First, collect all documents to delete
+ const allDocuments: DocumentInfo[] = []
+
+ for (const entry of this.registry) {
+ progress.currentContract = entry.serviceName
+
+ for (const documentType of entry.documentTypes) {
+ progress.currentDocumentType = documentType
+ onProgress({ ...progress })
+
+ try {
+ const documents = await this.queryUserDocuments(
+ entry.contractId,
+ documentType,
+ userId
+ )
+ allDocuments.push(...documents)
+ progress.totalDocuments = allDocuments.length
+ onProgress({ ...progress })
+ } catch (error) {
+ console.warn(`Failed to query ${documentType}:`, error)
+ }
+ }
+ }
+
+ // Now delete all documents
+ progress.phase = 'deleting'
+ onProgress({ ...progress })
+
+ // Process deletions in batches
+ for (let i = 0; i < allDocuments.length; i += this.BATCH_SIZE) {
+ const batch = allDocuments.slice(i, i + this.BATCH_SIZE)
+
+ // Update progress with current document type being processed
+ if (batch.length > 0) {
+ progress.currentDocumentType = batch[0].documentType
+ progress.currentContract = this.getServiceName(batch[0].contractId)
+ }
+ onProgress({ ...progress })
+
+ // Process batch concurrently
+ const results = await Promise.allSettled(
+ batch.map(doc => this.deleteDocument(doc))
+ )
+
+ // Update progress based on results
+ for (let j = 0; j < results.length; j++) {
+ progress.processedDocuments++
+ const result = results[j]
+
+ if (result.status === 'fulfilled' && result.value.success) {
+ progress.deletedDocuments++
+ } else {
+ progress.failedDocuments++
+ progress.errors.push({
+ contractId: batch[j].contractId,
+ documentType: batch[j].documentType,
+ documentId: batch[j].$id,
+ error: result.status === 'rejected'
+ ? result.reason?.message || 'Unknown error'
+ : (result.value as { error?: string }).error || 'Delete failed'
+ })
+ }
+
+ onProgress({ ...progress })
+ }
+
+ // Add delay between batches to avoid rate limiting
+ if (i + this.BATCH_SIZE < allDocuments.length) {
+ await this.delay(this.BATCH_DELAY_MS)
+ }
+ }
+
+ // Determine final status
+ const totalFailed = progress.failedDocuments
+ const totalDeleted = progress.deletedDocuments
+
+ progress.phase = totalFailed === 0 ? 'complete' : 'failed'
+ onProgress({ ...progress })
+
+ return {
+ success: totalFailed === 0,
+ totalDeleted,
+ totalFailed,
+ errors: progress.errors,
+ partialFailure: totalFailed > 0 && totalDeleted > 0
+ }
+ }
+
+ /**
+ * Delete a single document
+ */
+ private async deleteDocument(doc: DocumentInfo): Promise<{ success: boolean; error?: string }> {
+ try {
+ const result = await stateTransitionService.deleteDocument(
+ doc.contractId,
+ doc.documentType,
+ doc.$id,
+ doc.$ownerId
+ )
+ return { success: result.success, error: result.error }
+ } catch (error) {
+ return {
+ success: false,
+ error: error instanceof Error ? error.message : 'Unknown error'
+ }
+ }
+ }
+
+ /**
+ * Clear all local storage related to the user session
+ */
+ async clearLocalStorage(userId: string): Promise {
+ // Clear session storage items
+ if (typeof window !== 'undefined') {
+ localStorage.removeItem('yappr_session')
+ sessionStorage.removeItem('yappr_dpns_username')
+ sessionStorage.removeItem('yappr_skip_dpns')
+ sessionStorage.removeItem('yappr_backup_prompt_shown')
+
+ // Clear private key from secure storage
+ const { clearPrivateKey } = await import('../secure-storage')
+ clearPrivateKey(userId)
+
+ // Clear password-encrypted credentials for this user
+ const { removeStoredCredential } = await import('../password-encrypted-storage')
+ removeStoredCredential(userId)
+
+ // Clear block cache
+ const { invalidateBlockCache } = await import('../caches/block-cache')
+ invalidateBlockCache(userId)
+
+ // Clear DashPlatformClient identity
+ const { getDashPlatformClient } = await import('../dash-platform-client')
+ const dashClient = getDashPlatformClient()
+ dashClient.setIdentity('')
+ }
+ }
+
+ /**
+ * Full account deletion orchestration
+ */
+ async deleteAccount(
+ userId: string,
+ onProgress: (progress: DeletionProgress) => void
+ ): Promise {
+ // Delete all documents
+ const result = await this.deleteAllUserDocuments(userId, onProgress)
+
+ // If deletion was successful or partially successful, clear local storage
+ if (result.totalDeleted > 0 || result.totalFailed === 0) {
+ const progress: DeletionProgress = {
+ phase: 'cleanup',
+ currentContract: '',
+ currentDocumentType: 'Local Storage',
+ totalDocuments: result.totalDeleted + result.totalFailed,
+ processedDocuments: result.totalDeleted + result.totalFailed,
+ deletedDocuments: result.totalDeleted,
+ failedDocuments: result.totalFailed,
+ errors: result.errors
+ }
+ onProgress(progress)
+
+ await this.clearLocalStorage(userId)
+ }
+
+ return result
+ }
+
+ /**
+ * Get service name for a contract ID
+ */
+ private getServiceName(contractId: string): string {
+ const entry = this.registry.find(e => e.contractId === contractId)
+ return entry?.serviceName || 'Unknown'
+ }
+
+ /**
+ * Helper to delay execution
+ */
+ private delay(ms: number): Promise {
+ return new Promise(resolve => setTimeout(resolve, ms))
+ }
+
+ /**
+ * Get all document types that will be deleted
+ * Useful for displaying to the user what will be affected
+ */
+ getAffectedDocumentTypes(): string[] {
+ const types: string[] = []
+ for (const entry of this.registry) {
+ types.push(...entry.documentTypes)
+ }
+ return Array.from(new Set(types)) // Remove duplicates
+ }
+
+ /**
+ * Get human-readable descriptions of what will be deleted
+ */
+ getDeletionSummary(): Array<{ category: string; items: string[] }> {
+ return [
+ {
+ category: 'Social Content',
+ items: ['All your posts', 'All your replies', 'All your reposts/quotes']
+ },
+ {
+ category: 'Interactions',
+ items: ['All your likes', 'All your bookmarks', 'All users you follow']
+ },
+ {
+ category: 'Profile Data',
+ items: ['Your profile information', 'Your avatar', 'Your display name and bio']
+ },
+ {
+ category: 'Private Data',
+ items: ['All your direct messages', 'Your block and mute lists']
+ },
+ {
+ category: 'Other Data',
+ items: ['Your custom lists', 'Notification history', 'Encrypted key backups']
+ }
+ ]
+ }
+}
+
+// Export singleton instance
+export const accountDeletionService = new AccountDeletionService()