OverviewFilesCommitsIssuesDocsReleasesPeers

ollama_semantic_function_calling / ollamatools-new / second-device-keet / link_device.js

101 lines · javascript ref:
#!/usr/bin/env node
/**
 * Script to link a new device to an existing Keet identity
 */

import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';

// Get the directory name of the current module
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

// Configure logging
function log(level, message) {
  const timestamp = new Date().toISOString();
  console.log(`[${timestamp}] [${level}] ${message}`);
}

// Main function
async function main() {
  try {
    // Path to the first device's identity file
    const firstDeviceIdentityPath = path.join(__dirname, '..', 'test-keet-storage', 'identity.json');
    
    // Path to the second device's storage directory
    const secondDeviceStoragePath = path.join(__dirname, 'storage');
    
    // Create the storage directory if it doesn't exist
    if (!fs.existsSync(secondDeviceStoragePath)) {
      fs.mkdirSync(secondDeviceStoragePath, { recursive: true });
    }
    
    // Read the first device's identity
    log('INFO', `Reading identity from first device: ${firstDeviceIdentityPath}`);
    const firstDeviceIdentity = JSON.parse(fs.readFileSync(firstDeviceIdentityPath, 'utf8'));
    log('INFO', `First device identity: ${JSON.stringify(firstDeviceIdentity)}`);
    
    // Create a new device ID
    const newDeviceId = `device-${Date.now()}`;
    log('INFO', `Generated new device ID: ${newDeviceId}`);
    
    // Create a new device entry
    const newDevice = {
      deviceId: newDeviceId,
      isMobile: true,
      name: 'Mobile Device',
      confirmed: false // New devices start as unconfirmed
    };
    
    // Create a new identity for the second device that links to the first device's identity
    const secondDeviceIdentity = {
      anonymous: false, // Set to false for a real identity
      memberId: firstDeviceIdentity.memberId, // Use the same memberId as the first device
      timestamp: Date.now(),
      displayName: firstDeviceIdentity.displayName,
      avatar: firstDeviceIdentity.avatar,
      devices: [
        ...firstDeviceIdentity.devices, // Include all devices from the first device
        newDevice // Add the new device
      ],
      local: {
        deviceId: newDeviceId // Set the local device ID to the new device ID
      }
    };
    
    // Write the new identity to the second device's storage directory
    const secondDeviceIdentityPath = path.join(secondDeviceStoragePath, 'identity.json');
    log('INFO', `Writing identity to second device: ${secondDeviceIdentityPath}`);
    fs.writeFileSync(secondDeviceIdentityPath, JSON.stringify(secondDeviceIdentity));
    
    // Also update the first device's identity to include the new device
    log('INFO', `Updating first device identity to include the new device`);
    firstDeviceIdentity.devices.push(newDevice);
    fs.writeFileSync(firstDeviceIdentityPath, JSON.stringify(firstDeviceIdentity));
    
    log('INFO', `Device linking completed successfully!`);
    log('INFO', `New device ID: ${newDeviceId}`);
    log('INFO', `To confirm this device, run the following command:`);
    log('INFO', `node keet_cmd.js --confirm-device=${newDeviceId} --storage=../test-keet-storage`);
    
    return 0;
  } catch (error) {
    log('ERROR', `Error linking device: ${error.message}`);
    log('ERROR', error.stack);
    return 1;
  }
}

// Run the main function if this file is executed directly
if (import.meta.url === `file://${process.argv[1]}`) {
  try {
    const exitCode = await main();
    process.exit(exitCode);
  } catch (error) {
    log('ERROR', `Unhandled error: ${error.message}`);
    log('ERROR', error.stack);
    process.exit(1);
  }
}