Skip to content

bryanmatthewsimonson/nostr-article-capture

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

101 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

NOSTR Article Capture

Version License Platform

A Tampermonkey userscript that captures articles from any website, extracts metadata, tags entities, identifies claims with evidence linking, and publishes to NOSTR relays. All cryptography β€” including secp256k1, BIP-340 Schnorr signing, NIP-44 v2 encryption, and bech32 encoding β€” is implemented from scratch with zero external crypto dependencies.

πŸš€ Successor Project β€” X-Ray Browser Extension Multi-platform capture (social media, video, etc.) has moved to a dedicated browser extension: bryanmatthewsimonson/xray β€” Chrome/Firefox WebExtension (MV3), no userscript manager required. X-Ray covers article capture, URL-scoped metadata (annotations, fact-checks, ratings, comments, headline corrections), and is the active development target for platform-specific capture. This userscript remains the focused, stable article-capture tool.


πŸ“₯ Install

Install NOSTR Article Capture

Prerequisites: Tampermonkey browser extension.

The script auto-updates via @updateURL / @downloadURL in the userscript header. External dependencies are loaded via CDN @require tags:

Dependency Version Purpose
@mozilla/readability 0.5.0 Article content extraction
Turndown 7.2.0 HTML β†’ Markdown conversion
turndown-plugin-gfm 1.0.2 GitHub-Flavored Markdown tables & strikethrough

✨ Features

πŸ“° Article Capture

  • One-click capture via a floating action button (FAB) in a Shadow DOM container β€” immune to page CSS interference
  • Mozilla Readability extracts title, author, date, and body from any article
  • Smart date detection β€” JSON-LD, meta tags (article:published_time, datePublished)
  • Trusted Types CSP compatibility β€” works on sites with strict Content Security Policy headers
  • Editable URL β€” canonical URL displayed and editable; tracking parameter cleanup

πŸ“ Reader View

  • Full-page reader view with clean typography and optimal reading width
  • WYSIWYG visual editor β€” contentEditable rich-text editing directly in the reader view
  • Raw markdown editor β€” toggle between visual and markdown mode (auto-resizing textarea)
  • Preview as Published β€” HTML β†’ markdown β†’ HTML roundtrip to see exactly what NOSTR will display
  • Inline metadata editing β€” click author, publication, date, or URL to edit in place
  • Dark mode support via prefers-color-scheme
  • Mobile responsive β€” adaptive layout for mobile and tablet screens

🏷️ Entity System

  • Four entity types: Person πŸ‘€, Organization 🏒, Place πŸ“, Thing πŸ”·
  • Text selection popover β€” select text in content, choose entity type from a floating popover
  • Manual tagging β€” add entities by name via the "+ Tag Entity" button
  • Auto-detection β€” author (Person) and publication (Organization) automatically tagged on capture
  • Keypair per entity β€” each entity gets its own secp256k1 keypair (npub/nsec) for NOSTR identity
  • Entity aliases (canonical_id) β€” entities can be linked as aliases of a canonical entity
  • Auto-suggestion β€” automatically detects known entities from your registry in content text
  • Entity browser with search and type filtering (All / πŸ‘€ / 🏒 / πŸ“ / πŸ”·)
  • Entity detail view β€” rename, manage aliases, view keypair (npub/nsec with copy), articles list
  • JSON export/import for full entity registry backup and restore

πŸ“‹ Claim Extraction

  • πŸ“‹ Claim button in the text selection popover β€” select any text and extract it as a claim
  • Claim types β€” classify claims as Factual, Causal, Evaluative, or Predictive
  • Crux marking β€” mark key claims as "crux" (the most important claims)
  • Confidence slider β€” set confidence level (0–100%) on crux claims
  • Structured claim triples β€” [Subject] β†’ [Predicate] β†’ [Object] with entity references or freetext
  • Attribution types β€” direct quote, paraphrase, editorial assertion, or article thesis
  • Quote date β€” when the statement was made (distinct from article publish date)
  • Claims bar β€” displays extracted claims with type badges, claimant labels, and crux indicators
  • Per-URL persistence β€” claims stored per article URL and reloaded on revisit

πŸ”— Evidence Linking

  • πŸ”— button on each claim opens the evidence linker modal
  • Cross-content linking β€” link claims across different articles as supporting, contradicting, or contextualizing evidence
  • Relationship types β€” supports βœ…, contradicts ❌, contextualizes πŸ“Ž
  • Evidence indicators β€” claims with evidence links show a πŸ”— badge with link count

🌐 Social Features

  • 🌐 button in the claims bar fetches kind 30040 claim events from relays for the current URL
  • Grouped by publisher β€” remote claims organized by npub, filtering out your own
  • Cross-user claim discovery β€” see what claims others have extracted from the same content

πŸ“€ NOSTR Publishing

Six event kinds are published:

Kind Purpose
0 Entity profiles (with refers_to for aliases)
30023 Long-form content (articles in Markdown)
30040 Claims (structured triples, crux, confidence)
30043 Evidence links (supports/contradicts/contextualizes)
30078 Entity sync (NIP-44 encrypted)
32125 Entity relationships (author, mentioned, claimant, subject)

Two signing methods:

Method Description
NIP-07 Extension Browser extensions like nos2x or Alby β€” keys never leave the extension
Local Keypair BIP-340 Schnorr signing with a locally generated or imported key
  • Parallel relay publishing via Promise.allSettled() β€” events sent to all selected relays concurrently
  • Event preview β€” inspect the full event JSON before publishing

πŸ” Crypto (built-in, no dependencies)

All cryptographic operations implemented in pure JavaScript:

Primitive Implementation
secp256k1 Key generation, public key derivation (BigInt field arithmetic)
BIP-340 Schnorr Signing and verification
Bech32 Encoding/decoding (npub/nsec) via BIP-173
ECDH Shared secret derivation for NIP-44 conversation keys
ChaCha20 Stream cipher (RFC 7539 quarter-round)
HKDF-SHA256 Key derivation (extract + expand)
HMAC-SHA256 Message authentication with constant-time comparison
NIP-44 v2 Padded encryption (ChaCha20 + HMAC-SHA256 encrypt-then-MAC)
NIP-04 AES-256-CBC encrypt/decrypt (legacy, via Web Crypto SubtleCrypto)
SHA-256 Hashing via Web Crypto API

πŸ’Ύ Storage

  • GM_setValue / GM_getValue for persistent Tampermonkey storage with localStorage fallback (iOS)
  • Storage quota monitoring β€” color-coded display in settings (green β†’ orange at 1 MB β†’ red at 5 MB)
  • Size breakdown β€” entities, identity, relays, claims shown separately
  • Compression fallback β€” _compressForSave() strips optional fields when writes fail
  • Graceful error handling β€” storage save failures show user-facing toasts

🎨 UI & Accessibility

  • Responsive design β€” mobile-friendly FAB positioning and layout
  • Dark mode β€” full prefers-color-scheme support
  • Shadow DOM FAB β€” floating action button isolated from page CSS via closed shadow root (with regular DOM fallback)
  • ARIA labels on interactive elements
  • Focus trap within the reader view β€” Tab / Shift+Tab cycles through focusable elements
  • Panel stack Escape handling β€” Escape closes the topmost overlay in order
  • :focus-visible styling for clear keyboard focus indicators

πŸš€ Usage

  1. Navigate to any article
  2. Click the floating action button (πŸ“° bottom-right corner)
  3. Read the content in the clean reader view
  4. Edit metadata β€” click author, publication, date, or URL to edit inline
  5. Toggle Edit mode for content editing (visual WYSIWYG or raw markdown)
  6. Tag entities β€” select text to tag people, orgs, places, or things
  7. Extract claims β€” select text and click πŸ“‹ Claim with type classification and crux marking
  8. Preview as Published β€” check the final markdown roundtrip format
  9. Publish β€” click Publish β†’ select relays and signing method β†’ publish to NOSTR
  10. Settings β€” manage identity (generate, import nsec, NIP-07), relays, entities, sync

πŸ“‹ NOSTR Event Kinds

Kind Name Usage
0 Profile Metadata (NIP-01) Optional public identity for entities; alias entities include ["refers_to", canonical_npub]
30023 Long-form Content (NIP-23) Articles in Markdown with entity p tags and claim summary tags
30040 Claim Event Individual claim with claimant/subject/object p tags, predicate, quote-date, attribution type, confidence, crux flag
30043 Evidence Link Cross-content claim relationship: supports, contradicts, or contextualizes
30078 Application Data (NIP-78) Encrypted entity sync (NIP-44 v2 encrypt-to-self; NIP-04 fallback on read)
32125 Entity Relationship Links an entity to content with a typed relationship (author, mentioned, claimant, subject)

Claim Events (Kind 30040)

{
  "kind": 30040,
  "tags": [
    ["d", "claim_abc123"],
    ["r", "https://example.com/article"],
    ["claim-text", "The unemployment rate dropped to 3.4%"],
    ["claim-type", "factual"],
    ["attribution", "direct_quote"],
    ["confidence", "85"],
    ["crux", "true"],
    ["p", "<claimant-pubkey>", "", "claimant"],
    ["claimant", "Larry Summers"],
    ["predicate", "dropped to"],
    ["quote-date", "2024-01-15"],
    ["client", "nostr-article-capture"]
  ],
  "content": "surrounding context text"
}

Evidence Links (Kind 30043)

{
  "kind": 30043,
  "tags": [
    ["d", "evidence_link_id"],
    ["source-claim", "claim_abc123"],
    ["target-claim", "claim_def456"],
    ["relationship", "supports"],
    ["r", "https://example.com/article-1"],
    ["r", "https://example.com/article-2"],
    ["client", "nostr-article-capture"]
  ],
  "content": "optional explanation note"
}

Entity Relationships (Kind 32125)

{
  "kind": 32125,
  "tags": [
    ["d", "<entity-id>:<article-url>:<relationship>"],
    ["r", "https://example.com/article"],
    ["p", "<entity-pubkey>", "", "author"],
    ["entity-name", "Helen Andrews"],
    ["entity-type", "person"],
    ["relationship", "author"],
    ["client", "nostr-article-capture"]
  ],
  "content": ""
}

πŸ“œ NIPs Used

NIP Name Usage
NIP-01 Basic Protocol Event structure, relay communication (EVENT, OK, NOTICE, REQ, CLOSE)
NIP-04 Encrypted Direct Messages Legacy AES-256-CBC encryption (fallback for reading older entity sync events)
NIP-07 Browser Extension Signing window.nostr.signEvent() and window.nostr.getPublicKey() integration
NIP-19 Bech32 Encoding npub / nsec key encoding and decoding
NIP-23 Long-form Content Kind 30023 events for articles
NIP-32 Labels L/l label tags on entity sync events for app-specific categorization
NIP-33 Parameterized Replaceable Kinds 30023, 30040, 30043, 30078, 32125 β€” all replaceable by d tag
NIP-44 Versioned Encryption v2 padded encryption (ChaCha20 + HMAC-SHA256) for entity sync
NIP-78 Application-specific Data Kind 30078 events for storing encrypted entity data on relays

🌐 Default Relays

Pre-configured with 10 public relays:

wss://nos.lol Β· wss://relay.primal.net Β· wss://relay.nostr.net Β· wss://nostr.mom Β· wss://relay.nostr.bg Β· wss://nostr.oxtr.dev Β· wss://relay.snort.social Β· wss://offchain.pub Β· wss://nostr-pub.wellorder.net Β· wss://nostr.fmt.wiz.biz


πŸ§ͺ Testing

File Tests Coverage
tests/crypto-tests.js 65 secp256k1 key generation, BIP-340 Schnorr vectors, bech32 encode/decode, SHA-256, ECDH, NIP-04, event signing
tests/nip44-test.js 5 ChaCha20 RFC 7539 vectors, NIP-44 padding, pad/unpad roundtrip, encrypt/decrypt roundtrip, HMAC tamper detection
node tests/crypto-tests.js && node tests/nip44-test.js

πŸ“ Project Structure

nostr-article-capture/
β”œβ”€β”€ nostr-article-capture.user.js    # Single-file userscript (monolith)
β”œβ”€β”€ tests/
β”‚   β”œβ”€β”€ crypto-tests.js              # 65 crypto tests
β”‚   └── nip44-test.js                # 5 NIP-44 tests
β”œβ”€β”€ docs/
β”‚   β”œβ”€β”€ project-history-and-migration.md  # Complete project history & X-Ray migration guide
β”‚   β”œβ”€β”€ data-model.md                # Entity, claim, evidence data structures
β”‚   β”œβ”€β”€ entity-hierarchy-design.md   # Entity alias system design
β”‚   β”œβ”€β”€ entity-sync-design.md        # NIP-78 encrypted sync protocol
β”‚   β”œβ”€β”€ archive-reader-design.md     # Archive reader design (reference)
β”‚   β”œβ”€β”€ nostr-nips-analysis.md       # NIP usage and rationale
β”‚   β”œβ”€β”€ article-data-collection.md   # Article capture field reference
β”‚   β”œβ”€β”€ article-complete-inventory.md  # Full inventory of captured data
β”‚   └── tampermonkey-article-capture-plan.md  # Original v1 plan
└── README.md

πŸ“š Documentation

Document Description
Project History & Migration Guide Complete project history (v1–v4), data model reference, and X-Ray browser extension migration guide
Data Model Entity, claim, and evidence data structures
Entity Hierarchy Design Entity alias system and canonical_id design
Entity Sync Design NIP-78 encrypted sync protocol (NIP-44 + NIP-04 fallback)
NOSTR NIPs Analysis NIP usage and rationale

πŸ”— Successor Project

X-Ray Browser Extension β€” A Chrome/Firefox WebExtension (MV3) that extends article capture with multi-platform support (social media, video, etc.), URL-scoped metadata, and the platform-specific capture features that were explored in v3/v4 of this userscript. See docs/project-history-and-migration.md for the full migration story.


πŸ”— Related Projects


πŸ“„ License

MIT License

About

Archive articles to NOSTR

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors