Files

Edge-Net Browser Deployment

Deploy edge-net directly in browsers without running your own infrastructure. Earn rUv (Resource Utility Vouchers) by contributing idle compute.

┌─────────────────────────────────────────────────────────────────────────┐
│                   BROWSER DEPLOYMENT OPTIONS                            │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│   Option A: CDN + Public Genesis          Option B: Self-Hosted        │
│   ┌────────────────────────────┐          ┌────────────────────────┐   │
│   │  Your Website              │          │  Your Website          │   │
│   │  <script src="cdn/...">   │          │  <script src="local">  │   │
│   │         │                  │          │         │              │   │
│   │         ▼                  │          │         ▼              │   │
│   │  ┌────────────────┐       │          │  ┌────────────────┐    │   │
│   │  │ Public Genesis │◄──┐   │          │  │ Your Genesis   │    │   │
│   │  │    Nodes       │   │   │          │  │    Node        │    │   │
│   │  └────────────────┘   │   │          │  └────────────────┘    │   │
│   │                       │   │          │                         │   │
│   │  ┌────────────────┐   │   │          │  P2P via WebRTC        │   │
│   │  │ Public GUN     │◄──┘   │          │  or WebSocket          │   │
│   │  │   Relays       │       │          │                         │   │
│   │  └────────────────┘       │          └────────────────────────┘   │
│   └────────────────────────────┘                                       │
│                                                                         │
│   Best for: Quick start, testing         Best for: Control, privacy   │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

1. Add Script Tag

<!DOCTYPE html>
<html>
<head>
  <title>My Site</title>
</head>
<body>
  <!-- Your website content -->

  <!-- Edge-Net: Contribute compute, earn credits -->
  <script type="module">
    import { EdgeNet } from 'https://cdn.jsdelivr.net/npm/@ruvector/edge-net/dist/edge-net.min.js';

    const node = await EdgeNet.init({
      siteId: 'my-site-unique-id',
      contribution: 0.3,  // 30% CPU when idle
    });

    console.log(`Node ID: ${node.nodeId()}`);
    console.log(`Balance: ${node.creditBalance()} rUv`);
  </script>
</body>
</html>

2. NPM Installation (Alternative)

npm install @ruvector/edge-net
import { EdgeNet } from '@ruvector/edge-net';

const node = await EdgeNet.init({
  siteId: 'my-site',
  contribution: 0.3,
});

Configuration Options

Basic Configuration

const node = await EdgeNet.init({
  // Required
  siteId: 'your-unique-site-id',

  // Contribution settings
  contribution: {
    cpuLimit: 0.3,              // 0.0 - 1.0 (30% max CPU)
    memoryLimit: 256_000_000,   // 256MB max memory
    bandwidthLimit: 1_000_000,  // 1MB/s max bandwidth
    tasks: ['vectors', 'embeddings', 'encryption'],
  },

  // Idle detection
  idle: {
    minIdleTime: 5000,          // Wait 5s of idle before working
    respectBattery: true,       // Reduce when on battery
    respectDataSaver: true,     // Respect data saver mode
  },

  // UI integration
  ui: {
    showBadge: true,            // Show contribution badge
    badgePosition: 'bottom-right',
    onEarn: (credits) => {
      // Custom notification on earning
      console.log(`Earned ${credits} QDAG!`);
    },
  },
});

Advanced Configuration

const node = await EdgeNet.init({
  siteId: 'my-site',

  // Network settings
  network: {
    // Use public genesis nodes (default)
    genesis: [
      'https://us-east1-edge-net.cloudfunctions.net/genesis',
      'https://europe-west1-edge-net.cloudfunctions.net/genesis',
      'https://asia-east1-edge-net.cloudfunctions.net/genesis',
    ],

    // P2P relay servers
    relays: [
      'https://gun-manhattan.herokuapp.com/gun',
      'https://gun-us.herokuapp.com/gun',
    ],

    // WebRTC configuration
    webrtc: {
      enabled: true,
      iceServers: [
        { urls: 'stun:stun.l.google.com:19302' },
      ],
    },
  },

  // Staking for higher priority
  stake: {
    amount: 100,                // Stake 100 QDAG
    autoStake: true,            // Auto-stake earnings
  },

  // Callbacks
  onCredit: (earned, total) => console.log(`+${earned} QDAG`),
  onTask: (task) => console.log(`Processing: ${task.type}`),
  onError: (error) => console.error('Edge-Net error:', error),
  onConnect: (peers) => console.log(`Connected to ${peers} peers`),
  onDisconnect: () => console.log('Disconnected'),
});

Widget Integration

Contribution Badge

Show users their rUv contribution status:

<!-- Include the badge component -->
<div id="edge-net-badge"></div>

<script type="module">
  import { EdgeNet, Badge } from '@ruvector/edge-net';

  const node = await EdgeNet.init({ siteId: 'my-site' });

  // Mount badge
  Badge.mount('#edge-net-badge', node, {
    theme: 'dark',          // 'light' | 'dark' | 'auto'
    showRuv: true,          // Show rUv balance
    showMultiplier: true,
    showUptime: true,
    minimizable: true,
  });
</script>

Dashboard Widget

Full contribution dashboard:

<div id="edge-net-dashboard" style="width: 400px; height: 300px;"></div>

<script type="module">
  import { EdgeNet, Dashboard } from '@ruvector/edge-net';

  const node = await EdgeNet.init({ siteId: 'my-site' });

  Dashboard.mount('#edge-net-dashboard', node, {
    showStats: true,
    showHistory: true,
    showTasks: true,
    showPeers: true,
  });
</script>

Opt-In Modal

<script type="module">
  import { EdgeNet, ConsentModal } from '@ruvector/edge-net';

  // Show consent modal before initializing
  const consent = await ConsentModal.show({
    title: 'Help power our AI features',
    message: 'Contribute idle compute cycles to earn QDAG credits.',
    benefits: [
      'Earn credits while browsing',
      'Use credits for AI features',
      'Early adopter bonus: 5.2x multiplier',
    ],
    learnMoreUrl: '/edge-net-info',
  });

  if (consent.accepted) {
    const node = await EdgeNet.init({
      siteId: 'my-site',
      contribution: consent.cpuLimit,  // User-selected limit
    });
  }
</script>

Banner Opt-In

<div id="edge-net-banner"></div>

<script type="module">
  import { EdgeNet, ConsentBanner } from '@ruvector/edge-net';

  ConsentBanner.show('#edge-net-banner', {
    onAccept: async (settings) => {
      const node = await EdgeNet.init({
        siteId: 'my-site',
        contribution: settings.cpuLimit,
      });
    },
    onDecline: () => {
      // User declined - respect their choice
      console.log('User declined edge-net participation');
    },
  });
</script>

Task Submission

Use earned credits for compute tasks:

// Check balance first
if (node.creditBalance() >= 5) {
  // Submit vector search task
  const result = await node.submitTask('vector_search', {
    query: new Float32Array(128).fill(0.5),
    k: 10,
  }, {
    maxRuv: 5,            // Max rUv to spend
    timeout: 30000,       // 30s timeout
    priority: 'normal',   // 'low' | 'normal' | 'high'
  });

  console.log('Results:', result.results);
  console.log('Cost:', result.cost, 'rUv');
}

Available Task Types

Type Description Cost
vector_search k-NN search in HNSW index ~1 rUv / 1K vectors
vector_insert Add vectors to index ~0.5 rUv / 100 vectors
embedding Generate text embeddings ~5 rUv / 100 texts
semantic_match Task-to-agent routing ~1 rUv / 10 queries
encryption AES encrypt/decrypt ~0.1 rUv / MB
compression Adaptive quantization ~0.2 rUv / MB

Framework Integration

React

import { useEdgeNet, Badge } from '@ruvector/edge-net/react';

function App() {
  const { node, balance, multiplier, isConnected } = useEdgeNet({
    siteId: 'my-react-app',
    contribution: 0.3,
  });

  return (
    <div>
      <h1>My App</h1>
      {isConnected && (
        <Badge balance={balance} multiplier={multiplier} />
      )}
    </div>
  );
}

Vue 3

<template>
  <div>
    <h1>My App</h1>
    <EdgeNetBadge v-if="isConnected" :node="node" />
  </div>
</template>

<script setup>
import { useEdgeNet, EdgeNetBadge } from '@ruvector/edge-net/vue';

const { node, isConnected } = useEdgeNet({
  siteId: 'my-vue-app',
  contribution: 0.3,
});
</script>

Next.js

// components/EdgeNetProvider.jsx
'use client';

import { EdgeNetProvider } from '@ruvector/edge-net/react';

export default function Providers({ children }) {
  return (
    <EdgeNetProvider config={{ siteId: 'my-next-app', contribution: 0.3 }}>
      {children}
    </EdgeNetProvider>
  );
}

// app/layout.jsx
import Providers from '@/components/EdgeNetProvider';

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        <Providers>{children}</Providers>
      </body>
    </html>
  );
}

Self-Hosting the WASM Bundle

If you prefer to host the WASM files yourself:

1. Download the Package

npm pack @ruvector/edge-net
tar -xzf ruvector-edge-net-*.tgz
cp -r package/dist/ ./public/edge-net/

2. Configure Your Web Server

# nginx configuration
location /edge-net/ {
    add_header Cross-Origin-Opener-Policy same-origin;
    add_header Cross-Origin-Embedder-Policy require-corp;

    # WASM MIME type
    types {
        application/wasm wasm;
    }
}

3. Use Local Path

<script type="module">
  import { EdgeNet } from '/edge-net/edge-net.min.js';

  const node = await EdgeNet.init({
    siteId: 'my-site',
    wasmPath: '/edge-net/',  // Path to WASM files
  });
</script>

Option B: Self-Hosted Genesis Node

For full control, run your own genesis node:

Using Docker

# Pull the edge-net genesis image
docker pull ruvector/edge-net-genesis:latest

# Run genesis node
docker run -d \
  --name edge-net-genesis \
  -p 8080:8080 \
  -e NODE_ENV=production \
  -e GENESIS_KEYS_PATH=/keys/genesis.json \
  -v ./keys:/keys:ro \
  ruvector/edge-net-genesis:latest

Connect Browsers to Your Genesis

const node = await EdgeNet.init({
  siteId: 'my-site',
  network: {
    genesis: ['https://your-genesis.example.com'],
    relays: ['wss://your-relay.example.com'],
  },
});

See ../gcloud/README.md for Google Cloud Functions deployment.

Privacy & Compliance

GDPR Compliance

// Check for prior consent
const hasConsent = localStorage.getItem('edge-net-consent') === 'true';

if (hasConsent) {
  const node = await EdgeNet.init({ siteId: 'my-site' });
} else {
  // Show consent UI
  showConsentDialog();
}

// Handle "forget me" requests
async function handleForgetMe() {
  const node = await EdgeNet.getNode();
  if (node) {
    await node.deleteAllData();
    await node.disconnect();
  }
  localStorage.removeItem('edge-net-consent');
}

Data Collected

Data Purpose Retention
Node ID Identity Until user clears
Task results Verification 24 hours
rUv balance Economics Permanent (on-chain)
IP address Rate limiting Not stored
Browser fingerprint Sybil prevention Hashed, 7 days

No Personal Data

Edge-net does NOT collect:

  • Names or emails
  • Browsing history
  • Cookie contents
  • Form inputs
  • Screen recordings

Performance Impact

Scenario CPU Impact Memory Network
Idle (no tasks) 0% ~10MB 0
Light tasks 5-10% ~50MB ~1KB/s
Active contribution 10-30% ~100MB ~10KB/s
Heavy workload 30% (capped) ~256MB ~50KB/s

Optimization Tips

const node = await EdgeNet.init({
  siteId: 'my-site',

  contribution: {
    cpuLimit: 0.2,              // Lower CPU for sensitive sites
    memoryLimit: 128_000_000,   // Lower memory footprint
  },

  idle: {
    minIdleTime: 10000,         // Wait longer before starting
    checkInterval: 5000,        // Check less frequently
  },

  // Pause during critical interactions
  pauseDuringInteraction: true,
});

// Manually pause during important operations
node.pause();
await performCriticalOperation();
node.resume();

Monitoring & Analytics

Built-in Stats

const stats = node.getStats();
console.log({
  uptime: stats.uptimeHours,
  tasksCompleted: stats.tasksCompleted,
  creditsEarned: stats.creditsEarned,
  reputation: stats.reputation,
  peers: stats.connectedPeers,
});

Integration with Analytics

// Send to your analytics
const node = await EdgeNet.init({
  siteId: 'my-site',
  onCredit: (earned, total) => {
    gtag('event', 'edge_net_credit', {
      earned,
      total,
      multiplier: node.getMultiplier(),
    });
  },
});

Troubleshooting

Common Issues

WASM fails to load

Error: Failed to load WASM module

Solution: Ensure CORS headers allow WASM loading from CDN.

SharedArrayBuffer not available

Error: SharedArrayBuffer is not defined

Solution: Add required COOP/COEP headers:

Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp

WebWorkers blocked

Error: Worker constructor blocked

Solution: Ensure your CSP allows worker-src.

Debug Mode

const node = await EdgeNet.init({
  siteId: 'my-site',
  debug: true,  // Enable verbose logging
});

Support