Files
wifi-densepose/vendor/ruvector/examples/edge-net/pkg/networks.js

818 lines
23 KiB
JavaScript

#!/usr/bin/env node
/**
* Edge-Net Multi-Network Module
*
* Enables creation, discovery, and contribution to multiple edge networks.
* Each network is cryptographically isolated with its own:
* - Genesis block and network ID
* - QDAG ledger
* - Peer registry
* - Access control (public/private/invite-only)
*
* Security Features:
* - Network ID derived from genesis hash (tamper-evident)
* - Ed25519 signatures for network announcements
* - Optional invite codes for private networks
* - Cryptographic proof of network membership
*/
import { createHash, randomBytes } from 'crypto';
import { promises as fs } from 'fs';
import { homedir } from 'os';
import { join, dirname } from 'path';
import { fileURLToPath } from 'url';
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
// ANSI colors
const colors = {
reset: '\x1b[0m',
bold: '\x1b[1m',
dim: '\x1b[2m',
cyan: '\x1b[36m',
green: '\x1b[32m',
yellow: '\x1b[33m',
blue: '\x1b[34m',
magenta: '\x1b[35m',
red: '\x1b[31m',
};
const c = (color, text) => `${colors[color]}${text}${colors.reset}`;
// Network types
const NetworkType = {
PUBLIC: 'public', // Anyone can join and discover
PRIVATE: 'private', // Requires invite code to join
CONSORTIUM: 'consortium', // Requires approval from existing members
};
// Well-known public networks (bootstrap)
const WELL_KNOWN_NETWORKS = [
{
id: 'mainnet',
name: 'Edge-Net Mainnet',
description: 'Primary public compute network',
type: NetworkType.PUBLIC,
genesisHash: 'edgenet-mainnet-genesis-v1',
bootstrapNodes: ['edge-net.ruvector.dev:9000'],
created: '2024-01-01T00:00:00Z',
},
{
id: 'testnet',
name: 'Edge-Net Testnet',
description: 'Testing and development network',
type: NetworkType.PUBLIC,
genesisHash: 'edgenet-testnet-genesis-v1',
bootstrapNodes: ['testnet.ruvector.dev:9000'],
created: '2024-01-01T00:00:00Z',
},
];
// Directory structure
function getNetworksDir() {
const dir = join(homedir(), '.ruvector', 'networks');
if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
return dir;
}
function getRegistryFile() {
return join(getNetworksDir(), 'registry.json');
}
function getNetworkDir(networkId) {
const dir = join(getNetworksDir(), networkId);
if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
return dir;
}
/**
* Network Genesis - defines a network's identity
*/
export class NetworkGenesis {
constructor(options = {}) {
this.version = 1;
this.name = options.name || 'Custom Network';
this.description = options.description || 'A custom edge-net network';
this.type = options.type || NetworkType.PUBLIC;
this.creator = options.creator || null; // Creator's public key
this.creatorSiteId = options.creatorSiteId || 'anonymous';
this.created = options.created || new Date().toISOString();
this.parameters = {
minContributors: options.minContributors || 1,
confirmationThreshold: options.confirmationThreshold || 3,
creditMultiplier: options.creditMultiplier || 1.0,
maxPeers: options.maxPeers || 100,
...options.parameters,
};
this.inviteRequired = this.type !== NetworkType.PUBLIC;
this.approvers = options.approvers || []; // For consortium networks
this.nonce = options.nonce || randomBytes(16).toString('hex');
}
/**
* Compute network ID from genesis hash
*/
computeNetworkId() {
const data = JSON.stringify({
version: this.version,
name: this.name,
type: this.type,
creator: this.creator,
created: this.created,
parameters: this.parameters,
nonce: this.nonce,
});
const hash = createHash('sha256').update(data).digest('hex');
return `net-${hash.slice(0, 16)}`;
}
/**
* Create signed genesis block
*/
createSignedGenesis(signFn) {
const genesis = {
...this,
networkId: this.computeNetworkId(),
};
if (signFn) {
const dataToSign = JSON.stringify(genesis);
genesis.signature = signFn(dataToSign);
}
return genesis;
}
/**
* Generate invite code for private networks
*/
generateInviteCode() {
if (this.type === NetworkType.PUBLIC) {
throw new Error('Public networks do not require invite codes');
}
const networkId = this.computeNetworkId();
const secret = randomBytes(16).toString('hex');
const code = Buffer.from(`${networkId}:${secret}`).toString('base64url');
return {
code,
networkId,
validUntil: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString(), // 7 days
};
}
}
/**
* Network Registry - manages known networks
*/
export class NetworkRegistry {
constructor() {
this.networks = new Map();
this.activeNetwork = null;
this.loaded = false;
}
async load() {
try {
// Load well-known networks
for (const network of WELL_KNOWN_NETWORKS) {
this.networks.set(network.id, {
...network,
isWellKnown: true,
joined: false,
stats: null,
});
}
// Load user's network registry
if (existsSync(getRegistryFile())) {
const data = JSON.parse(await fs.readFile(getRegistryFile(), 'utf-8'));
for (const network of data.networks || []) {
this.networks.set(network.id, {
...network,
isWellKnown: false,
});
}
this.activeNetwork = data.activeNetwork || null;
}
this.loaded = true;
} catch (err) {
console.error('Failed to load network registry:', err.message);
}
}
async save() {
const data = {
version: 1,
activeNetwork: this.activeNetwork,
networks: Array.from(this.networks.values()).filter(n => !n.isWellKnown),
savedAt: new Date().toISOString(),
};
await fs.writeFile(getRegistryFile(), JSON.stringify(data, null, 2));
}
/**
* Create a new network
*/
async createNetwork(options, identity) {
const genesis = new NetworkGenesis({
...options,
creator: identity?.publicKey,
creatorSiteId: identity?.siteId,
});
const networkId = genesis.computeNetworkId();
// Create network directory structure
const networkDir = getNetworkDir(networkId);
await fs.mkdir(join(networkDir, 'peers'), { recursive: true });
// Save genesis block
const genesisData = genesis.createSignedGenesis(
identity?.sign ? (data) => identity.sign(data) : null
);
await fs.writeFile(
join(networkDir, 'genesis.json'),
JSON.stringify(genesisData, null, 2)
);
// Initialize QDAG for this network
const qdag = {
networkId,
nodes: [{
id: 'genesis',
type: 'genesis',
timestamp: Date.now(),
message: `Genesis: ${genesis.name}`,
parents: [],
weight: 1,
confirmations: 0,
}],
tips: ['genesis'],
confirmed: ['genesis'],
createdAt: Date.now(),
};
await fs.writeFile(
join(networkDir, 'qdag.json'),
JSON.stringify(qdag, null, 2)
);
// Initialize peer list
await fs.writeFile(
join(networkDir, 'peers.json'),
JSON.stringify([], null, 2)
);
// Register network
const networkEntry = {
id: networkId,
name: genesis.name,
description: genesis.description,
type: genesis.type,
creator: genesis.creator,
creatorSiteId: genesis.creatorSiteId,
created: genesis.created,
parameters: genesis.parameters,
genesisHash: createHash('sha256')
.update(JSON.stringify(genesisData))
.digest('hex')
.slice(0, 32),
joined: true,
isOwner: true,
stats: { nodes: 1, contributors: 0, credits: 0 },
};
this.networks.set(networkId, networkEntry);
await this.save();
// Generate invite codes if private
let inviteCodes = null;
if (genesis.type !== NetworkType.PUBLIC) {
inviteCodes = [];
for (let i = 0; i < 5; i++) {
inviteCodes.push(genesis.generateInviteCode());
}
await fs.writeFile(
join(networkDir, 'invites.json'),
JSON.stringify(inviteCodes, null, 2)
);
}
return { networkId, genesis: genesisData, inviteCodes };
}
/**
* Join an existing network
*/
async joinNetwork(networkId, inviteCode = null) {
const network = this.networks.get(networkId);
if (!network) {
throw new Error(`Network not found: ${networkId}`);
}
if (network.joined) {
return { alreadyJoined: true, network };
}
// Verify invite code for private networks
if (network.type === NetworkType.PRIVATE) {
if (!inviteCode) {
throw new Error('Private network requires invite code');
}
const isValid = await this.verifyInviteCode(networkId, inviteCode);
if (!isValid) {
throw new Error('Invalid or expired invite code');
}
}
// Create local network directory
const networkDir = getNetworkDir(networkId);
// For well-known networks, create initial structure
if (network.isWellKnown) {
const qdag = {
networkId,
nodes: [{
id: 'genesis',
type: 'genesis',
timestamp: Date.now(),
message: `Joined: ${network.name}`,
parents: [],
weight: 1,
confirmations: 0,
}],
tips: ['genesis'],
confirmed: ['genesis'],
createdAt: Date.now(),
};
await fs.writeFile(
join(networkDir, 'qdag.json'),
JSON.stringify(qdag, null, 2)
);
await fs.writeFile(
join(networkDir, 'peers.json'),
JSON.stringify([], null, 2)
);
}
network.joined = true;
network.joinedAt = new Date().toISOString();
await this.save();
return { joined: true, network };
}
/**
* Verify invite code
*/
async verifyInviteCode(networkId, code) {
try {
const decoded = Buffer.from(code, 'base64url').toString();
const [codeNetworkId, secret] = decoded.split(':');
if (codeNetworkId !== networkId) {
return false;
}
// In production, verify against network's invite registry
// For local simulation, accept any properly formatted code
return secret && secret.length === 32;
} catch {
return false;
}
}
/**
* Discover networks from DHT/registry
*/
async discoverNetworks(options = {}) {
const discovered = [];
// Always include well-known networks
for (const network of WELL_KNOWN_NETWORKS) {
const existing = this.networks.get(network.id);
discovered.push({
...network,
joined: existing?.joined || false,
source: 'well-known',
});
}
// Scan for locally known networks
try {
const networksDir = getNetworksDir();
const dirs = await fs.readdir(networksDir);
for (const dir of dirs) {
if (dir === 'registry.json') continue;
const genesisPath = join(networksDir, dir, 'genesis.json');
if (existsSync(genesisPath)) {
try {
const genesis = JSON.parse(await fs.readFile(genesisPath, 'utf-8'));
const existing = this.networks.get(genesis.networkId || dir);
if (!existing?.isWellKnown) {
discovered.push({
id: genesis.networkId || dir,
name: genesis.name,
description: genesis.description,
type: genesis.type,
creator: genesis.creatorSiteId,
created: genesis.created,
joined: existing?.joined || false,
source: 'local',
});
}
} catch (e) {
// Skip invalid genesis files
}
}
}
} catch (err) {
// Networks directory doesn't exist yet
}
// In production: Query DHT/bootstrap nodes for public networks
// This is simulated here
return discovered;
}
/**
* Set active network for contributions
*/
async setActiveNetwork(networkId) {
const network = this.networks.get(networkId);
if (!network) {
throw new Error(`Network not found: ${networkId}`);
}
if (!network.joined) {
throw new Error(`Must join network first: ${networkId}`);
}
this.activeNetwork = networkId;
await this.save();
return network;
}
/**
* Get network info
*/
getNetwork(networkId) {
return this.networks.get(networkId);
}
/**
* Get active network
*/
getActiveNetwork() {
if (!this.activeNetwork) return null;
return this.networks.get(this.activeNetwork);
}
/**
* Get all joined networks
*/
getJoinedNetworks() {
return Array.from(this.networks.values()).filter(n => n.joined);
}
/**
* Get network statistics
*/
async getNetworkStats(networkId) {
const networkDir = getNetworkDir(networkId);
const qdagPath = join(networkDir, 'qdag.json');
const peersPath = join(networkDir, 'peers.json');
const stats = {
nodes: 0,
contributions: 0,
contributors: 0,
credits: 0,
peers: 0,
};
try {
if (existsSync(qdagPath)) {
const qdag = JSON.parse(await fs.readFile(qdagPath, 'utf-8'));
const contributions = (qdag.nodes || []).filter(n => n.type === 'contribution');
stats.nodes = qdag.nodes?.length || 0;
stats.contributions = contributions.length;
stats.contributors = new Set(contributions.map(c => c.contributor)).size;
stats.credits = contributions.reduce((sum, c) => sum + (c.credits || 0), 0);
}
if (existsSync(peersPath)) {
const peers = JSON.parse(await fs.readFile(peersPath, 'utf-8'));
stats.peers = peers.length;
}
} catch (err) {
// Stats not available
}
return stats;
}
/**
* List all networks
*/
listNetworks() {
return Array.from(this.networks.values());
}
}
/**
* Multi-Network Manager - coordinates contributions across networks
*/
export class MultiNetworkManager {
constructor(identity) {
this.identity = identity;
this.registry = new NetworkRegistry();
this.activeConnections = new Map();
}
async initialize() {
await this.registry.load();
return this;
}
/**
* Create a new network
*/
async createNetwork(options) {
console.log(`\n${c('cyan', 'Creating new network...')}\n`);
const result = await this.registry.createNetwork(options, this.identity);
console.log(`${c('green', '✓')} Network created successfully!`);
console.log(` ${c('cyan', 'Network ID:')} ${result.networkId}`);
console.log(` ${c('cyan', 'Name:')} ${options.name}`);
console.log(` ${c('cyan', 'Type:')} ${options.type}`);
console.log(` ${c('cyan', 'Description:')} ${options.description || 'N/A'}`);
if (result.inviteCodes) {
console.log(`\n${c('bold', 'Invite Codes (share these to invite members):')}`);
for (const invite of result.inviteCodes.slice(0, 3)) {
console.log(` ${c('yellow', invite.code)}`);
}
console.log(` ${c('dim', `(${result.inviteCodes.length} codes saved to network directory)`)}`);
}
console.log(`\n${c('dim', 'Network directory:')} ~/.ruvector/networks/${result.networkId}`);
return result;
}
/**
* Discover available networks
*/
async discoverNetworks() {
console.log(`\n${c('cyan', 'Discovering networks...')}\n`);
const networks = await this.registry.discoverNetworks();
if (networks.length === 0) {
console.log(` ${c('dim', 'No networks found.')}`);
return networks;
}
console.log(`${c('bold', 'Available Networks:')}\n`);
for (const network of networks) {
const status = network.joined ? c('green', '● Joined') : c('dim', '○ Not joined');
const typeIcon = network.type === NetworkType.PUBLIC ? '🌐' :
network.type === NetworkType.PRIVATE ? '🔒' : '🏢';
console.log(` ${status} ${typeIcon} ${c('bold', network.name)}`);
console.log(` ${c('dim', 'ID:')} ${network.id}`);
console.log(` ${c('dim', 'Type:')} ${network.type}`);
console.log(` ${c('dim', 'Description:')} ${network.description || 'N/A'}`);
console.log(` ${c('dim', 'Source:')} ${network.source}`);
console.log('');
}
return networks;
}
/**
* Join a network
*/
async joinNetwork(networkId, inviteCode = null) {
console.log(`\n${c('cyan', `Joining network ${networkId}...`)}\n`);
try {
const result = await this.registry.joinNetwork(networkId, inviteCode);
if (result.alreadyJoined) {
console.log(`${c('yellow', '⚠')} Already joined network: ${result.network.name}`);
} else {
console.log(`${c('green', '✓')} Successfully joined: ${result.network.name}`);
}
// Set as active if it's the only joined network
const joinedNetworks = this.registry.getJoinedNetworks();
if (joinedNetworks.length === 1) {
await this.registry.setActiveNetwork(networkId);
console.log(` ${c('dim', 'Set as active network')}`);
}
return result;
} catch (err) {
console.log(`${c('red', '✗')} Failed to join: ${err.message}`);
throw err;
}
}
/**
* Switch active network
*/
async switchNetwork(networkId) {
const network = await this.registry.setActiveNetwork(networkId);
console.log(`${c('green', '✓')} Active network: ${network.name} (${networkId})`);
return network;
}
/**
* Show network status
*/
async showStatus() {
const active = this.registry.getActiveNetwork();
const joined = this.registry.getJoinedNetworks();
console.log(`\n${c('bold', 'NETWORK STATUS:')}\n`);
if (!active) {
console.log(` ${c('yellow', '⚠')} No active network`);
console.log(` ${c('dim', 'Join a network to start contributing')}\n`);
return;
}
const stats = await this.registry.getNetworkStats(active.id);
console.log(`${c('bold', 'Active Network:')}`);
console.log(` ${c('cyan', 'Name:')} ${active.name}`);
console.log(` ${c('cyan', 'ID:')} ${active.id}`);
console.log(` ${c('cyan', 'Type:')} ${active.type}`);
console.log(` ${c('cyan', 'QDAG Nodes:')} ${stats.nodes}`);
console.log(` ${c('cyan', 'Contributions:')} ${stats.contributions}`);
console.log(` ${c('cyan', 'Contributors:')} ${stats.contributors}`);
console.log(` ${c('cyan', 'Total Credits:')} ${stats.credits}`);
console.log(` ${c('cyan', 'Connected Peers:')} ${stats.peers}`);
if (joined.length > 1) {
console.log(`\n${c('bold', 'Other Joined Networks:')}`);
for (const network of joined) {
if (network.id !== active.id) {
console.log(` ${c('dim', '○')} ${network.name} (${network.id})`);
}
}
}
console.log('');
}
/**
* Get active network directory for contributions
*/
getActiveNetworkDir() {
const active = this.registry.getActiveNetwork();
if (!active) return null;
return getNetworkDir(active.id);
}
}
// CLI interface
async function main() {
const args = process.argv.slice(2);
const command = args[0];
const registry = new NetworkRegistry();
await registry.load();
if (command === 'list' || command === 'ls') {
console.log(`\n${c('bold', 'NETWORKS:')}\n`);
const networks = registry.listNetworks();
const active = registry.activeNetwork;
for (const network of networks) {
const isActive = network.id === active;
const status = network.joined ?
(isActive ? c('green', '● Active') : c('cyan', '○ Joined')) :
c('dim', ' Available');
const typeIcon = network.type === NetworkType.PUBLIC ? '🌐' :
network.type === NetworkType.PRIVATE ? '🔒' : '🏢';
console.log(` ${status} ${typeIcon} ${c('bold', network.name)}`);
console.log(` ${c('dim', 'ID:')} ${network.id}`);
if (network.description) {
console.log(` ${c('dim', network.description)}`);
}
console.log('');
}
} else if (command === 'discover') {
const manager = new MultiNetworkManager(null);
await manager.initialize();
await manager.discoverNetworks();
} else if (command === 'create') {
const name = args[1] || 'My Network';
const type = args.includes('--private') ? NetworkType.PRIVATE :
args.includes('--consortium') ? NetworkType.CONSORTIUM :
NetworkType.PUBLIC;
const description = args.find((a, i) => args[i - 1] === '--desc') || '';
const manager = new MultiNetworkManager(null);
await manager.initialize();
await manager.createNetwork({ name, type, description });
} else if (command === 'join') {
const networkId = args[1];
const inviteCode = args.find((a, i) => args[i - 1] === '--invite');
if (!networkId) {
console.log(`${c('red', '✗')} Usage: networks join <network-id> [--invite <code>]`);
process.exit(1);
}
const manager = new MultiNetworkManager(null);
await manager.initialize();
await manager.joinNetwork(networkId, inviteCode);
} else if (command === 'switch' || command === 'use') {
const networkId = args[1];
if (!networkId) {
console.log(`${c('red', '✗')} Usage: networks switch <network-id>`);
process.exit(1);
}
const manager = new MultiNetworkManager(null);
await manager.initialize();
await manager.switchNetwork(networkId);
} else if (command === 'status') {
const manager = new MultiNetworkManager(null);
await manager.initialize();
await manager.showStatus();
} else if (command === 'help' || !command) {
console.log(`
${c('bold', 'Edge-Net Multi-Network Manager')}
${c('bold', 'COMMANDS:')}
${c('green', 'list')} List all known networks
${c('green', 'discover')} Discover available networks
${c('green', 'create')} Create a new network
${c('green', 'join')} Join an existing network
${c('green', 'switch')} Switch active network
${c('green', 'status')} Show current network status
${c('green', 'help')} Show this help
${c('bold', 'EXAMPLES:')}
${c('dim', '# List networks')}
$ node networks.js list
${c('dim', '# Create a public network')}
$ node networks.js create "My Research Network" --desc "For ML research"
${c('dim', '# Create a private network')}
$ node networks.js create "Team Network" --private
${c('dim', '# Join a network')}
$ node networks.js join net-abc123def456
${c('dim', '# Join a private network with invite')}
$ node networks.js join net-xyz789 --invite <invite-code>
${c('dim', '# Switch active network')}
$ node networks.js switch net-abc123def456
${c('bold', 'NETWORK TYPES:')}
${c('cyan', '🌐 Public')} Anyone can join and discover
${c('cyan', '🔒 Private')} Requires invite code to join
${c('cyan', '🏢 Consortium')} Requires approval from members
`);
}
}
main().catch(console.error);