DARSHAN दर्शन
Decentralized Archive Remote Streaming and Hosting Access Network
View content without copying it. The host remains sovereign.
v1.0.0Philosophy
"Content stays on the altar. Pilgrims come to see."
In Hindu tradition, darshan (दर्शन) is the sacred act of beholding a deity — receiving the blessing of sight without possessing the divine. DARSHAN brings this principle to digital content:
- View ≠ Copy — Content decrypts during streaming, not before
- Host Sovereignty — You control bandwidth, quality, and access
- No Upload Required — Stream directly from your machine
- Proof of Viewing — Cryptographic attestation of view events
The Paradigm Shift
OLD MODEL (dying):
Creator → Upload → Central Server → Download × N
↑ bandwidth waste ↑ copies everywhere
DARSHAN MODEL (novel):
Creator's Node → Mesh Tunnel → Viewer's Node
↑ ↑
Content stays home View, not copy
Why upload your videos to YouTube when viewers can stream directly from you? DARSHAN eliminates the middleman while keeping you in control.
Architecture
┌─────────────────────────────────────────────────────────────┐
│ HOST NODE │
│ ┌─────────────────────┐ │
│ │ Local Content │ ← Never leaves unless permitted │
│ │ - Videos │ │
│ │ - Documents │ │
│ │ - Live streams │ │
│ └─────────┬───────────┘ │
│ │ │
│ ┌─────────▼───────────┐ │
│ │ DARSHAN Gateway │ ← Streams bytes on-demand │
│ │ - Access control │ ← GUMBA proofs for permission │
│ │ - Bandwidth shaping│ ← Host controls quality │
│ │ - View attestation │ ← Prove viewing, not copying │
│ └─────────┬───────────┘ │
└────────────┼────────────────────────────────────────────────┘
│
═══════════════ MESH TUNNEL (ANNEX E2E) ════════════════
│
┌────────────▼────────────────────────────────────────────────┐
│ VIEWER NODE │
│ ┌─────────────────────┐ │
│ │ Virtual Mount │ ← Appears as local file │
│ │ /yak/alice/video │ ← But bytes stream in real-time │
│ └─────────────────────┘ │
│ OR │
│ ┌─────────────────────┐ │
│ │ In-App Viewer │ ← Direct playback, no file saved │
│ └─────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
Core Concepts
DarshanContent
Metadata describing streamable content (never the content itself):
import { DarshanContent } from 'yakmesh/mesh/darshan.js';
const content = new DarshanContent({
hostNodeId: myNode.id,
path: '/videos/my-film.mp4', // Local path (private)
name: 'My Amazing Film', // Public metadata
contentType: 'video',
size: 524288000, // 500MB
duration: 7200, // 2 hours
permissions: ['view'], // View-only, no download
});
DarshanGateway
Host-side server that controls access and streams content:
import { DarshanGateway } from 'yakmesh/mesh/darshan.js';
const gateway = new DarshanGateway(identity, {
fileReader: myFileReader,
accessController: gumbaGate, // GUMBA integration
});
// Register content for sharing
await gateway.registerContent({
path: '/videos/my-film.mp4',
name: 'My Amazing Film',
contentType: 'video',
});
// Handle stream requests
gateway.on('stream:started', ({ streamId, viewerId }) => {
console.log(\Streaming to \\);
});
DarshanViewer
Client-side viewer that requests and displays content:
import { DarshanViewer } from 'yakmesh/mesh/darshan.js';
const viewer = new DarshanViewer(identity, {
sendMessage: mesh.send, // Mesh transport
});
// Start viewing
const stream = await viewer.startStream(hostId, contentId, {
quality: 'high',
onProgress: ({ percent }) => updateProgressBar(percent),
onChunk: (chunk) => videoPlayer.appendBuffer(chunk.data),
});
// Control playback
viewer.seek(stream.streamId, 60000); // Seek to 1 minute
viewer.pause(stream.streamId);
viewer.resume(stream.streamId);
DarshanMount
Virtual filesystem mount for OS integration:
import { DarshanMount } from 'yakmesh/mesh/darshan.js';
const mount = new DarshanMount({
mountPoint: '/yak',
viewer: myViewer,
cachePolicy: 'none', // No local storage
});
await mount.mount();
// Content appears as files in /yak/
mount.addContent('alice-node', aliceVideo, '/yak/alice/film.mp4');
// Now accessible via standard file APIs!
// vlc /yak/alice/film.mp4
Proof of Viewing
DARSHAN generates cryptographic proof that viewing occurred without copying:
import { DarshanAttestation } from 'yakmesh/mesh/darshan.js';
// Generated after viewing completes
const attestation = new DarshanAttestation({
contentHash: 'sha256:abc...',
viewerId: viewerNode.id,
hostId: hostNode.id,
streamId: stream.id,
startTime: Date.now() - 7200000,
endTime: Date.now(),
bytesReceived: 524288000,
completionPercent: 100,
});
// Sign by both parties
await attestation.signByViewer(viewerPrivateKey);
await attestation.signByHost(hostPrivateKey);
// Verify
const valid = attestation.verify(); // true
These attestations can be used for:
- Proof of access for subscription validation
- View counts that can't be faked
- Consumption analytics without tracking
- Payment triggers for pay-per-view
GUMBA Integration
DARSHAN integrates with GUMBA for permission-based access:
// Gateway with GUMBA access control
const gateway = new DarshanGateway(identity, {
accessController: {
checkAccess: async (viewerId, contentId, proof) => {
// Verify GUMBA proof
return await gumbaGate.verifyProof(proof, {
holder: viewerId,
requiredGroup: contentId,
requiredRole: 'viewer',
});
}
}
});
// Viewer must provide GUMBA proof
const stream = await viewer.startStream(hostId, contentId, {
accessProof: await gumbaGate.generateProof(credentials),
});
Lazy Byte Streaming
Content is streamed lazily — only requested bytes are transmitted:
// Seek to 50% without downloading first half
await viewer.seek(streamId, contentSize * 0.5);
// Stream with byte-range requests
const request = new DarshanRequest({
type: 'stream:request',
contentId,
byteStart: 262144000, // Start at 250MB
byteEnd: 262144000 + 1048576, // 1MB chunk
});
// Each chunk is integrity-verified
const chunk = new DarshanChunk({
streamId,
sequenceNumber: 250,
data: encryptedBytes,
hash: 'sha256:xyz...', // Verify integrity
});
Use Cases
Independent Filmmakers
Stream your films directly to viewers. No YouTube compression. No algorithm censorship. Full control over your art.
Confidential Documents
Legal documents viewed but never stored on client devices. Perfect for sensitive materials requiring read-only access.
Music Previews
Let listeners preview tracks without downloading. Prove they listened before triggering payments.
Live Dashboards
Stream real-time data visualizations. Viewers see current state without accumulating history.
Configuration
import { DarshanConfig } from 'yakmesh/mesh/darshan.js';
// Full configuration options
const config = new DarshanConfig({
// Streaming settings
defaultChunkSize: 1048576, // 1MB chunks
maxConcurrentStreams: 10, // Per gateway
qualityPresets: {
low: { maxBitrate: 500000 },
medium: { maxBitrate: 2000000 },
high: { maxBitrate: 10000000 },
},
// Timeouts
streamTimeout: 300000, // 5 minutes idle
chunkTimeout: 30000, // 30 seconds per chunk
attestationTimeout: 60000,
// Access control
requireGumba: true, // Require GUMBA proofs
allowDownload: false, // View only
// Content limits
maxContentSize: 10737418240, // 10GB
supportedTypes: ['video', 'audio', 'document'],
});
Security Model
- Encryption in Transit — All streams use ANNEX E2E encryption
- Chunk Verification — Each chunk includes SHA-256 hash
- Access Control — Optional GUMBA proof requirements
- No Persistent Storage — Default cache policy is "none"
- Rate Limiting — Hosts control bandwidth allocation
- Host Sovereignty — Host can terminate streams at any time
API Reference
DarshanContent
| Property | Type | Description |
|---|---|---|
hostNodeId | string | Node hosting the content |
contentId | string | Unique content identifier |
name | string | Display name |
contentType | string | video, audio, document |
size | number | Size in bytes |
duration | number | Duration in seconds (media) |
permissions | string[] | Allowed operations |
DarshanGateway Methods
| Method | Description |
|---|---|
registerContent(opts) | Register content for streaming |
unregisterContent(id) | Remove content from availability |
handleRequest(request) | Process incoming stream request |
terminateStream(streamId) | End an active stream |
getActiveStreams() | List active streams |
DarshanViewer Methods
| Method | Description |
|---|---|
browse(hostId) | List available content from host |
startStream(hostId, contentId, opts) | Begin streaming content |
seek(streamId, position) | Seek to byte position |
pause(streamId) | Pause streaming |
resume(streamId) | Resume streaming |
stop(streamId) | End streaming |
Events
// Gateway events
gateway.on('stream:started', ({ streamId, viewerId, contentId }) => {});
gateway.on('stream:progress', ({ streamId, bytesTransferred, percent }) => {});
gateway.on('stream:completed', ({ streamId, attestation }) => {});
gateway.on('stream:error', ({ streamId, error }) => {});
// Viewer events
viewer.on('content:discovered', ({ hostId, contents }) => {});
viewer.on('stream:started', ({ streamId, hostId, contentId }) => {});
viewer.on('chunk:received', ({ streamId, sequenceNumber, size }) => {});
viewer.on('stream:completed', ({ streamId, attestation }) => {});