PRIV ProtocolPRIV Docs
Plugin

How It Works

Understanding the PRIV Chrome extension architecture and data flow.

How It Works

The PRIV extension uses Chrome's Manifest V3 architecture to collect, process, and monetize your browsing data while maintaining privacy.


Architecture Overview

The extension consists of three main components that work together.

graph TD
    subgraph "Chrome Extension"
        SW[Service Worker<br/>Background Script]
        CS[Content Scripts<br/>Data Collection]
        PU[Popup UI<br/>React App]
    end

    subgraph "Storage"
        LS[Local Storage<br/>chrome.storage]
    end

    subgraph "External"
        API[PRIV API]
        WL[Web3 Wallet]
    end

    CS -->|Page Data| SW
    SW -->|Settings| CS
    PU <-->|Messages| SW
    SW <-->|Data| LS
    SW -->|Batch Submit| API
    PU <-->|Connect| WL
    API -->|Earnings| SW

Manifest V3 Architecture

The extension uses Chrome's latest Manifest V3 standard for improved security and performance.

What is Manifest V3?

Manifest V3 is Chrome's extension platform that provides:

  • Service Workers: Background scripts that wake on demand
  • Declarative APIs: Better privacy controls
  • Reduced Permissions: More granular access
  • Improved Security: Stricter content security policies

Key Files

extensions/chrome/
  public/
    manifest.json          # Extension configuration
  src/
    background/
      service-worker.ts    # Background service worker
    content/
      content-script.ts    # Injected into pages
    popup/
      index.tsx           # Popup React app
      components/         # UI components
    lib/
      collector.ts        # Data collection utilities
      security.ts         # Security helpers
      wallet.ts           # Wallet integration
      sync.ts             # Data synchronization

Service Worker (Background Script)

The service worker is the brain of the extension. It runs in the background and coordinates all operations.

Responsibilities

TaskDescription
Message HandlingRoutes messages between components
Data ProcessingProcesses and batches collected data
API CommunicationSubmits data and fetches earnings
Alarm ManagementSchedules periodic tasks
Cache ManagementMaintains data cache for performance

Message Types

The service worker handles these message types:

type MessageType =
  | 'GET_SETTINGS'      // Retrieve current settings
  | 'UPDATE_SETTINGS'   // Update user settings
  | 'GET_EARNINGS'      // Fetch earnings data
  | 'GET_STATS'         // Fetch user statistics
  | 'GET_BALANCE'       // Fetch token balance
  | 'CONNECT_WALLET'    // Initiate wallet connection
  | 'DISCONNECT_WALLET' // Disconnect wallet
  | 'DATA_COLLECTED'    // New data from content script
  | 'PAGE_VISIT'        // Page visit event
  | 'SCROLL_DEPTH'      // Scroll tracking event
  | 'AD_IMPRESSION'     // Ad detection event
  | 'CLAIM_EARNINGS'    // Claim pending earnings
  | 'FLUSH_QUEUE'       // Force data submission
  | 'REQUEST_SYNC';     // Trigger sync with backend

Alarm System

The service worker uses Chrome alarms for scheduled tasks:

AlarmIntervalPurpose
batchSubmit5 minutesSubmit collected data
retryQueue1 minuteRetry failed submissions
refreshCache5 minutesUpdate cached data
privSync5 minutesSync with dashboard

Content Script

Content scripts run in the context of web pages and collect data based on user preferences.

Data Collection Flow

sequenceDiagram
    participant Page as Web Page
    participant CS as Content Script
    participant SW as Service Worker
    participant Storage as Local Storage

    Page->>CS: Page Load Event
    CS->>SW: Get Settings
    SW-->>CS: User Preferences

    alt Data Sharing Enabled
        CS->>CS: Collect Page Data
        CS->>CS: Anonymize URLs/Titles
        CS->>SW: Send PAGE_VISIT
        SW->>Storage: Store Entry
    end

    Page->>CS: Scroll Event
    CS->>SW: Send SCROLL_DEPTH

    Page->>CS: Page Unload
    CS->>SW: Send Exit Data

What Gets Collected

Based on enabled data types, the content script collects:

interface PageVisitData {
  url: string;        // Anonymized URL (no query params)
  domain: string;     // Website domain
  title: string;      // Sanitized page title
  category: string;   // Detected category (social, shopping, etc.)
  enterTime: number;  // Timestamp when page opened
  exitTime?: number;  // Timestamp when page closed
  timeSpent?: number; // Seconds on page
  scrollDepth?: number; // Maximum scroll percentage
}

Excluded URLs

The content script automatically excludes:

  • Browser internal pages (chrome://, about:)
  • Extension pages (chrome-extension://)
  • Local files (file://)
  • Sensitive domains (banking, healthcare, email)

The popup provides a React-based user interface for managing the extension.

Component Structure

popup/
  App.tsx                    # Main app with routing
  components/
    Header.tsx              # Wallet status and balance
    Dashboard.tsx           # Main earnings view
    DataTypesPanel.tsx      # Data type toggles
    EarningsCard.tsx        # Current earnings display
    EarningsHistory.tsx     # Weekly earnings chart
    WalletConnect.tsx       # Wallet connection UI
    Settings.tsx            # Settings page
    DataToggle.tsx          # Individual data type toggle

State Management

The popup manages state through Chrome's messaging system:

// Fetch settings from background
const response = await chrome.runtime.sendMessage({
  type: 'GET_SETTINGS'
});

// Update settings
await chrome.runtime.sendMessage({
  type: 'UPDATE_SETTINGS',
  payload: { dataSharingEnabled: true }
});

Data Flow Diagram

Complete data flow from collection to earnings.

flowchart LR
    subgraph Collection
        A[Page Visit] --> B[Content Script]
        B --> C{Enabled?}
        C -->|Yes| D[Anonymize]
        C -->|No| E[Discard]
        D --> F[Local Storage]
    end

    subgraph Processing
        F --> G[Batch Queue]
        G -->|5 min| H[Deduplicate]
        H --> I[Submit Batch]
    end

    subgraph Backend
        I --> J[PRIV API]
        J --> K[Aggregation]
        K --> L[Marketplace]
    end

    subgraph Earnings
        L --> M[Sale Event]
        M --> N[Calculate Share]
        N --> O[Credit Balance]
        O --> P[Withdraw to Wallet]
    end

Security Model

The extension implements multiple security layers.

Message Validation

All messages are validated before processing:

function validateMessage(
  message: unknown,
  sender: chrome.runtime.MessageSender
): { isValid: boolean; error?: string } {
  // Validate sender is from our extension
  if (sender.id !== chrome.runtime.id) {
    return { isValid: false, error: 'Invalid sender' };
  }

  // Validate message structure
  if (!message || typeof message !== 'object') {
    return { isValid: false, error: 'Invalid format' };
  }

  // Check message type
  if (!isValidMessageType(message.type)) {
    return { isValid: false, error: 'Invalid type' };
  }

  return { isValid: true };
}

Rate Limiting

External messages are rate limited:

const externalMessageRateLimiter = new RateLimiter(
  10,     // max requests
  60000   // per minute
);

Content Security Policy

The extension enforces strict CSP:

{
  "content_security_policy": {
    "extension_pages": "script-src 'self'; object-src 'self'"
  }
}

Offline Support

The extension works offline and queues data for later submission.

Queue System

interface QueueEntry {
  id: string;              // Unique entry ID
  data: CollectedDataEntry;// The data to submit
  attempts: number;        // Retry count
  createdAt: number;       // When queued
  lastAttempt: number | null; // Last retry time
}

Retry Logic

  1. Data is collected and stored locally
  2. Every 5 minutes, batch submission is attempted
  3. If offline, data is added to retry queue
  4. Retry queue processes every 1 minute
  5. After 10 failed attempts, data is discarded

Privacy Guarantees

What Advertisers See

Aggregated, anonymized data:

{
  "segment": "DeFi Power Users",
  "count": 1247,
  "avgSessionsPerWeek": "5-10",
  "topCategories": ["finance", "productivity"],
  "avgTimeOnPage": "30-60 seconds"
}

What Advertisers Never See

  • Your wallet address
  • Specific URLs you visited
  • Page content or titles
  • Your browsing history timeline
  • Any personally identifiable information

Next Steps