C2PA Extension Implementation

YouSeddit C2PA Extension Implementation

The YouSeddit C2PA Verification Extension is built upon the open-source c2pa-extension-validator project, extending its capabilities to support text quote validation with blockchain integration.

Building on Existing C2PA Validation

The base c2pa-extension-validator provides:

  • Browser extension for validating C2PA digital assets (images, videos, audio)
  • Support for Edge, Chrome, and Firefox browsers
  • Automatic detection of C2PA-enabled media on webpages
  • Visual indicators of validation status

Our implementation maintains these core capabilities while adding:

  1. Text quote validation through C2PA assertions
  2. Blockchain verification integration
  3. Smart contract validation for domains

Technical Implementation

Extension Structure

youseddit-c2pa-extension/
├── src/
│   ├── background/
│   │   └── background.ts         # Background service worker
│   ├── content/
│   │   ├── content.ts            # Content script for webpage integration
│   │   ├── c2pa-detector.ts      # Identifies C2PA content
│   │   ├── text-detector.ts      # New: Detects text quotes with C2PA refs
│   │   └── ui/                   # UI components
│   ├── blockchain/
│   │   ├── ledger-api.ts         # New: Blockchain interaction
│   │   └── contract-validator.ts # New: Smart contract validation
│   ├── c2pa/
│   │   ├── validator.ts          # C2PA validation logic
│   │   └── manifest-parser.ts    # Extended for YouSeddit assertions
│   ├── popup/
│   │   └── popup.tsx             # Extension popup UI
│   └── utils/
│       └── crypto.ts             # Cryptographic utilities
├── public/
│   ├── manifest.json             # Extension manifest
│   └── icons/                    # Extension icons
└── tests/
    ├── unit/                     # Unit tests
    └── e2e/                      # End-to-end tests

Extending C2PA Manifest Parsing

Our extension extends the standard C2PA manifest parsing to recognize Youseddit-specific assertions:

// Extends the existing C2PA validator with YouSeddit functionality
export class YousedditManifestValidator extends C2PAValidator {
  /**
   * Check for YouSeddit blockchain assertions in the manifest
   */
  public async checkBlockchainAssertion(manifest: C2PAManifest): Promise<BlockchainVerificationResult> {
    const yousedditAssertion = manifest.assertions.find(
      assertion => assertion.label === 'youseddit.blockchain'
    );
    
    if (!yousedditAssertion) {
      return { hasBlockchainRef: false };
    }
    
    const blockchainId = yousedditAssertion.data.blockchainId;
    return this.verifyWithBlockchain(blockchainId);
  }
  
  /**
   * Verify content against blockchain entry
   */
  private async verifyWithBlockchain(blockchainId: string): Promise<BlockchainVerificationResult> {
    const blockchainApi = new YousedditLedgerAPI();
    return blockchainApi.verifyContent(blockchainId);
  }
}

Text Quote Detection

A new component detects and validates text quotes with C2PA references:

export class TextQuoteDetector {
  /**
   * Scan for potential text quotes with C2PA references
   */
  public scanForQuotes(document: Document): QuoteElement[] {
    const potentialQuotes: QuoteElement[] = [];
    
    // Look for blockquote elements
    const blockquotes = document.querySelectorAll('blockquote');
    for (const blockquote of blockquotes) {
      this.processQuoteElement(blockquote, potentialQuotes);
    }
    
    // Look for quoted text in paragraphs
    const paragraphs = document.querySelectorAll('p');
    for (const paragraph of paragraphs) {
      if (this.containsQuotes(paragraph.textContent)) {
        this.processQuoteElement(paragraph, potentialQuotes);
      }
    }
    
    return potentialQuotes;
  }
  
  /**
   * Check element for C2PA references
   */
  private processQuoteElement(element: Element, results: QuoteElement[]): void {
    // Check for data attributes with blockchain references
    const blockchainId = element.getAttribute('data-youseddit-id');
    if (blockchainId) {
      results.push({ 
        element, 
        text: element.textContent?.trim() || '',
        blockchainId 
      });
      return;
    }
    
    // Check for nearby C2PA indicators
    const nearbyReference = this.findNearbyReference(element);
    if (nearbyReference) {
      results.push({ 
        element, 
        text: element.textContent?.trim() || '',
        blockchainId: nearbyReference.blockchainId
      });
    }
  }
  
  // Additional helper methods...
}

Blockchain Integration

A new blockchain API layer handles verification against the YouSeddit ledger:

export class YousedditLedgerAPI {
  private readonly API_ENDPOINT = 'https://api.youseddit.com/v1';
  
  /**
   * Verify content against blockchain record
   */
  public async verifyContent(blockchainId: string): Promise<BlockchainVerificationResult> {
    try {
      const response = await fetch(`${this.API_ENDPOINT}/verify/blockchain/${blockchainId}`);
      
      if (!response.ok) {
        return { 
          hasBlockchainRef: true, 
          verified: false, 
          error: 'Failed to fetch blockchain data'
        };
      }
      
      const data = await response.json();
      
      return {
        hasBlockchainRef: true,
        verified: true,
        sourceInfo: data.sourceInfo,
        timestamp: new Date(data.timestampVerified),
        contentHash: data.contentHash
      };
    } catch (error) {
      console.error('Blockchain verification error:', error);
      return { 
        hasBlockchainRef: true, 
        verified: false, 
        error: error instanceof Error ? error.message : 'Unknown error'
      };
    }
  }
  
  /**
   * Verify domain has valid contract for content
   */
  public async verifyDomainContract(domain: string, blockchainId: string): Promise<ContractVerificationResult> {
    try {
      const response = await fetch(
        `${this.API_ENDPOINT}/contracts/validate?domain=${encodeURIComponent(domain)}&contentId=${blockchainId}`
      );
      
      if (!response.ok) {
        return { valid: false, error: 'Failed to fetch contract data' };
      }
      
      const data = await response.json();
      
      return {
        valid: data.valid,
        licenseType: data.licenseType,
        expirationDate: new Date(data.expires),
        paymentStatus: data.paymentStatus
      };
    } catch (error) {
      console.error('Contract validation error:', error);
      return { 
        valid: false, 
        error: error instanceof Error ? error.message : 'Unknown error' 
      };
    }
  }
}

Text Validation

To validate text against blockchain records:

export class TextValidator {
  /**
   * Compare text against authenticated blockchain version
   */
  public validateText(quoteText: string, authenticText: string): TextMatchResult {
    // Remove extra whitespace and normalize
    const normalizedQuote = this.normalizeText(quoteText);
    const normalizedAuth = this.normalizeText(authenticText);
    
    if (normalizedQuote === normalizedAuth) {
      return { isMatch: true, matchPercentage: 100 };
    }
    
    // For partial matches, calculate similarity
    const similarity = this.calculateSimilarity(normalizedQuote, normalizedAuth);
    
    return {
      isMatch: similarity >= 0.9, // 90% similarity threshold
      matchPercentage: Math.round(similarity * 100),
      differences: this.highlightDifferences(normalizedQuote, normalizedAuth)
    };
  }
  
  /**
   * Calculate similarity between two text strings
   */
  private calculateSimilarity(text1: string, text2: string): number {
    // Implement text similarity algorithm
    // This could use Levenshtein distance, Jaccard similarity, etc.
    // For simplicity, this is a placeholder
    return 0; // Placeholder value
  }
  
  /**
   * Normalize text for comparison
   */
  private normalizeText(text: string): string {
    return text
      .replace(/\s+/g, ' ')
      .replace(/[\u2018\u2019]/g, "'")
      .replace(/[\u201C\u201D]/g, '"')
      .trim();
  }
  
  /**
   * Generate a diff showing where texts differ
   */
  private highlightDifferences(text1: string, text2: string): string {
    // Implement diff generation logic
    // Placeholder for now
    return '';
  }
}

Content Script Integration

The content script brings everything together:

// Main content script
(async function() {
  const c2paDetector = new C2PADetector();
  const textDetector = new TextQuoteDetector();
  const validator = new YousedditManifestValidator();
  const ledgerApi = new YousedditLedgerAPI();
  
  // Process standard C2PA media
  const mediaElements = c2paDetector.detectC2PAMedia(document);
  for (const element of mediaElements) {
    try {
      const manifest = await validator.getManifest(element);
      if (!manifest) continue;
      
      // Standard C2PA validation
      const validationResult = await validator.validateManifest(manifest);
      
      // Check for YouSeddit blockchain assertions
      const blockchainResult = await validator.checkBlockchainAssertion(manifest);
      
      // Create and display validation UI
      displayMediaValidation(element, validationResult, blockchainResult);
    } catch (error) {
      console.error('Media validation error:', error);
    }
  }
  
  // Process text quotes
  const quoteElements = textDetector.scanForQuotes(document);
  for (const quote of quoteElements) {
    try {
      // Verify quote against blockchain
      const blockchainResult = await ledgerApi.verifyContent(quote.blockchainId);
      
      if (blockchainResult.verified && blockchainResult.authenticText) {
        // Validate quote text against authentic text
        const textValidator = new TextValidator();
        const textMatch = textValidator.validateText(
          quote.text, 
          blockchainResult.authenticText
        );
        
        // Verify domain contract
        const contractResult = await ledgerApi.verifyDomainContract(
          window.location.hostname,
          quote.blockchainId
        );
        
        // Display validation UI
        displayTextValidation(quote.element, textMatch, blockchainResult, contractResult);
      }
    } catch (error) {
      console.error('Text validation error:', error);
    }
  }
})();

Key Enhancements

The YouSeddit extension makes several key enhancements to the base c2pa-extension-validator:

1. Extended C2PA Format Support

Added support for Youseddit-specific C2PA assertions:

{
  "label": "youseddit.blockchain",
  "data": {
    "blockchainId": "0x7d931ff3a802d6c5...",
    "ledgerType": "ethereum",
    "contentType": "quote",
    "timestampVerified": "2025-03-15T14:22:31Z"
  }
}

2. Text Quote Detection

Enhanced content scanning to detect:

  • Blockquote elements
  • Text in quotation marks
  • Elements with data attributes referencing YouSeddit blockchain IDs
  • Adjacent attribution links with YouSeddit verification URLs

3. Smart Contract Validation

Added validation of domain authorization through:

  • Checking the domain against YouSeddit contract registry
  • Validating license terms and expiration
  • Verifying payment status for quote usage

4. Enhanced User Interface

Improved the user interface with:

  • Text-specific validation indicators
  • Detailed verification panels showing blockchain status
  • Smart contract information display
  • Highlighting of differences between quoted and authentic text

Building and Testing

Prerequisites

  • Node.js 18+
  • pnpm package manager
  • Chrome or Edge for development testing

Setup

  1. Clone the repository:

    git clone https://github.com/Sanmarcsoft/youseddit-c2pa-extension.git
    cd youseddit-c2pa-extension
    
  2. Install dependencies:

    pnpm install
    
  3. Build the extension:

    pnpm build
    
  4. Load the extension in Chrome:

    • Navigate to chrome://extensions/
    • Enable “Developer mode”
    • Click “Load unpacked” and select the dist directory

Testing

The extension includes comprehensive test cases:

# Run all tests
pnpm test

# Run specific test categories
pnpm test:c2pa         # C2PA validation tests
pnpm test:blockchain   # Blockchain integration tests
pnpm test:text         # Text validation tests
pnpm test:e2e          # End-to-end browser tests

Deployment

The extension will be packaged for distribution through:

  1. Chrome Web Store
  2. Microsoft Edge Add-ons Store
  3. Firefox Browser Add-ons

Each platform requires specific packaging and review processes, detailed in our deployment guide.

Future Development

Planned enhancements include:

  1. Offline Validation: Cache verification data for offline use
  2. API Integration: JavaScript API for website integration
  3. Browser Coverage: Support for additional browsers
  4. Performance Optimization: Reduce validation latency
  5. Expanded Text Detection: Improved algorithms for detecting quoted content
Last modified July 6, 2025: Update deploy.yml (d65b9c1)