Complete documentation of Graphiti extension features.
- Authentication
- Drawing Mode
- Text Annotations
- Bookmarks & Tags
- Social Feed
- Profile System
- Debug Tools
- Technical Architecture
Secure authentication using the Pubky Ring mobile app.
Flow:
- Click "Sign In with Pubky Ring" to generate QR code
- Scan with Pubky Ring mobile app
- Authentication token is encrypted and transmitted via relay
- Session is established with your homeserver
Technical Details:
- 32-byte cryptographic client secret
- SHA-256 channel ID generation
pubkyauth://URL scheme with relay and capabilities- 2-second polling interval
- XOR-encrypted token transmission
- Session stored locally with capabilities
Draw graffiti directly on any webpage with a persistent canvas overlay.
- Activate: Press
Alt+Dor click the Drawing button in popup - Draw: Click and drag to create strokes
- Customize: Choose colors and brush thickness in toolbar
- Save: Click "Save & Exit" or press
Alt+Dagain
- 8-color palette: Red, Cyan, Blue, Orange, Mint, Yellow, Purple, White
- Adjustable brush: 2-20px thickness
- Persistent storage: Drawings save per URL
- Pubky sync: Automatic backup to homeserver at
/pub/graphiti.dev/drawings/
interface Drawing {
id: string; // Unique identifier
url: string; // Page URL
canvasData: string; // Base64 PNG image
timestamp: number; // Creation time
author: string; // Pubky ID
pubkyUrl?: string; // Homeserver URL after sync
}- Drawings are viewport-dependent
- Scrolling disabled during drawing
- Complex SPAs may affect positioning
Highlight text on webpages and add comments shared as Pubky posts.
- Select text on any webpage
- Click "Add Annotation" button that appears
- Write your comment in the modal
- Click "Post Annotation"
Annotations are visible to all users with the extension!
- Persistent highlights: Yellow background, clickable
- Network-wide visibility: Shared via Pubky posts
- Sidebar integration: View all annotations for current page
- Click-to-navigate: Click annotation card to scroll to highlight
Annotations use a two-phase sync strategy:
- Phase 1: Immediate local save (instant highlight)
- Phase 2: Background sync to Pubky homeserver
This ensures annotations work even if the network is slow.
interface Annotation {
id: string;
url: string;
selectedText: string;
comment: string;
startPath: string; // DOM XPath
endPath: string;
startOffset: number;
endOffset: number;
timestamp: number;
author: string;
postUri?: string;
color: string;
}Annotations are stored as posts with:
- Kind:
short - Content: JSON with annotation data
- Tags: URL hash tag +
pubky:annotation
One-click bookmarking with Pubky integration.
How it works:
- Click bookmark button in popup
- Extension creates a Link Post with the URL
- Extension creates a Bookmark pointing to that post
- Both are indexed by Nexus
Important Architecture Note:
Pubky bookmarks must point to posts, not external URLs:
HTTP URL (https://example.com)
↓
Link Post (pubky://.../posts/ABC) ← Indexed by Nexus
↓
Bookmark (pubky://.../bookmarks/XYZ) → references Post
↓
Visible in Pubky App ✅
Add custom tags to any URL.
Features:
- Multi-tag support (comma or space separated)
- Auto-normalize: lowercase, trimmed, max 20 chars
- Stored on homeserver with Pubky App schema
- Automatic URL hash tag for discovery
Every post automatically gets a deterministic hash tag based on the URL. This enables:
- Fast querying via Nexus
- Finding posts about the same URL
- Privacy-preserving (hash doesn't reveal URL)
See UTF-16 Hash Encoding for technical details.
View what your network is sharing about the current page.
- Context-aware: Shows posts about current URL
- Social graph: Posts from users you follow
- Real-time refresh: Pull to refresh
- Rich display: Author avatars, timestamps, post types
- Tab navigation: Switch between Posts and Annotations
The sidebar queries Nexus using the URL hash tag:
// Generate hash for current page
const urlHashTag = await generateUrlHashTag(currentUrl);
// Query Nexus
const posts = await nexusClient.streamPosts({
tags: urlHashTag,
viewer_id: session.pubky,
limit: 50
});Edit your Pubky profile directly from the extension.
Features:
- Live data loading: Fetches current profile from homeserver
- Emoji picker: 200+ emojis for status
- Link management: Add social links
- Avatar support: Set profile image URL
Profile Fields:
- Name
- Bio
- Avatar URL
- Status (emoji + text)
- Links (title + URL pairs)
pubky:// and pk:// URLs on web pages are automatically converted to clickable buttons.
Features:
- Beautiful purple gradient buttons
- Works on dynamic content (SPAs)
- Opens profile renderer on click
Access via the 🔧 button in popup.
Features:
- Real-time log viewer
- Filter by level (DEBUG, INFO, WARN, ERROR)
- Context-based filtering
- Export logs as JSON
- Clear all logs
Auth- Authentication flowStorage- Data persistencePubkyAPI/PubkyAPISDK- API operationsCrypto- Cryptographic operationsDrawingManager- Drawing featureAnnotationManager- Annotation featureBackground- Service workerSidePanel- Feed operations
- 1000 logs in memory buffer
- Persisted to Chrome storage
- Survives extension reload
- React 18 - UI framework
- TypeScript - Type safety
- Tailwind CSS - Styling
- Vite - Build tool
- Vitest - Testing
- Chrome Extension Manifest V3
| Component | File | Purpose |
|---|---|---|
| Background | src/background/background.ts |
Service worker, message handling |
| Content | src/content/content.ts |
Page injection, drawing, annotations |
| Popup | src/popup/ |
Main UI, auth, quick actions |
| Sidepanel | src/sidepanel/ |
Feed viewer, annotation browser |
| Profile | src/profile/ |
Profile rendering |
| Module | Purpose |
|---|---|
auth-sdk.ts |
Authentication via official Pubky SDK |
crypto.ts |
Cryptographic functions, URL hashing |
storage.ts |
Local storage wrapper |
pubky-api-sdk.ts |
Homeserver operations |
nexus-client.ts |
Nexus API queries |
annotations.ts |
Annotation management |
drawing-sync.ts |
Drawing synchronization |
logger.ts |
Debug logging |
| Data Type | Local Storage | Homeserver Path |
|---|---|---|
| Session | session |
- |
| Bookmarks | bookmarks |
/pub/pubky.app/bookmarks/ |
| Tags | tags |
/pub/pubky.app/tags/ |
| Posts | - | /pub/pubky.app/posts/ |
| Drawings | pubky_drawings |
/pub/graphiti.dev/drawings/ |
| Annotations | pubky_annotations |
As posts with special tags |
| Profile | profile |
/pub/pubky.app/profile.json |
| Logs | debugLogs |
- |
| Shortcut | Action |
|---|---|
Alt+P |
Open popup |
Alt+D |
Toggle drawing mode |
Alt+S |
Toggle sidebar |
Alt+A |
Open annotations |
On Mac, use Option instead of Alt
background.js: ~1.4 KBpopup: ~21 KB + shared chunkssidepanel: ~12 KB + shared chunks- Shared (React): ~233 KB
- Code splitting for popup/sidepanel
- Lazy loading of components
- Debounced DOM observers
- Indexed local storage lookups
- Background sync for network operations
- Client-side encryption for auth tokens
- Local-first data storage
- No third-party tracking
- URL hashing for privacy
- Your keys, your data via Pubky
All data syncs to your personal Pubky homeserver - no central servers.