import { IdentityManager } from './lib/identity-manager.js';
import { FileManager } from './lib/file-ops.js';
import fs from 'fs';
import path from 'path';
async function testCompleteDeviceChainWorkflow() {
console.log('=== Testing Complete Device Chain Workflow ===\n');
try {
// Clean up any existing test data
const testDir = path.join(FileManager.getHyperidentPath());
if (fs.existsSync(testDir)) {
fs.rmSync(testDir, { recursive: true, force: true });
console.log('✓ Cleaned up existing test data');
}
// Step 1: Generate new identity with device chain
console.log('\n--- Step 1: Generate Identity with Device Chain ---');
const identity = await IdentityManager.generateIdentity(null, 'laptop-main');
console.log('✓ Generated identity:', {
publicKey: identity.publicKey.substring(0, 16) + '...',
algorithm: identity.algorithm,
deviceChain: identity.deviceChain,
created: identity.created
});
// Step 2: Verify device chain exists and is valid
console.log('\n--- Step 2: Verify Device Chain ---');
const chainExists = await IdentityManager.deviceChainExists();
console.log('✓ Device chain exists:', chainExists);
if (chainExists) {
const deviceChain = await IdentityManager.loadDeviceChain();
console.log('✓ Device chain loaded:', {
publicKeyLength: deviceChain.keyPair.publicKey.length,
secretKeyLength: deviceChain.keyPair.secretKey.length,
proofLength: deviceChain.proof.length,
deviceName: deviceChain.metadata.name
});
// Verify the proof
const verification = await IdentityManager.verifyDeviceProof(deviceChain.proof);
console.log('✓ Device proof verified:', verification !== null);
if (verification) {
console.log(' - Identity matches:', verification.identityPublicKey.toString('hex').substring(0, 16) + '...');
console.log(' - Device matches:', verification.devicePublicKey.toString('hex').substring(0, 16) + '...');
}
}
// Step 3: Create a profile and test address generation
console.log('\n--- Step 3: Create Profile and Test Address ---');
await IdentityManager.createProfile('test-profile', 'Test profile for device chain');
const address = await IdentityManager.getProfileAddress('test-profile');
console.log('✓ Profile created with address:', address.substring(0, 16) + '...');
// Step 4: Export device bundle
console.log('\n--- Step 4: Export Device Bundle ---');
const bundle = await IdentityManager.exportDeviceBundle();
console.log('✓ Device bundle exported:', {
version: bundle.version,
hasIdentity: !!bundle.identity,
hasDeviceChain: !!bundle.deviceChain,
hasProfiles: !!bundle.profiles,
profileCount: Object.keys(bundle.profiles).length
});
// Step 5: Simulate importing on a new device
console.log('\n--- Step 5: Simulate New Device Import ---');
// Clean up current identity to simulate new device
fs.rmSync(testDir, { recursive: true, force: true });
console.log('✓ Cleaned up for new device simulation');
// Import the bundle on "new device"
await IdentityManager.importDeviceBundle(bundle, 'phone-secondary');
console.log('✓ Bundle imported on new device');
// Step 6: Verify new device chain
console.log('\n--- Step 6: Verify New Device Chain ---');
const newChainExists = await IdentityManager.deviceChainExists();
console.log('✓ New device chain exists:', newChainExists);
if (newChainExists) {
const newDeviceChain = await IdentityManager.loadDeviceChain();
console.log('✓ New device chain loaded:', {
deviceName: newDeviceChain.metadata.name,
proofLength: newDeviceChain.proof.length
});
// Verify the new device proof
const newVerification = await IdentityManager.verifyDeviceProof(newDeviceChain.proof);
console.log('✓ New device proof verified:', newVerification !== null);
if (newVerification) {
console.log(' - Same identity:', newVerification.identityPublicKey.toString('hex').substring(0, 16) + '...');
console.log(' - New device key:', newVerification.devicePublicKey.toString('hex').substring(0, 16) + '...');
}
}
// Step 7: Verify profiles were imported
console.log('\n--- Step 7: Verify Profile Import ---');
const profiles = await IdentityManager.listProfiles();
console.log('✓ Profiles imported:', Object.keys(profiles.profiles));
if (profiles.profiles['test-profile']) {
const importedAddress = await IdentityManager.getProfileAddress('test-profile');
console.log('✓ Profile address matches:', address === importedAddress);
}
// Step 8: Test cross-device attestation
console.log('\n--- Step 8: Test Cross-Device Attestation ---');
// Generate a third device keypair
const { CryptoManager } = await import('./lib/crypto.js');
const thirdDeviceKeyPair = await CryptoManager.generateRawDeviceKeyPair();
// Attest the third device using the second device
const thirdDeviceProof = await IdentityManager.attestNewDevice(thirdDeviceKeyPair.publicKey);
console.log('✓ Third device attested, proof length:', thirdDeviceProof.length);
// Verify the third device proof
const thirdVerification = await IdentityManager.verifyDeviceProof(thirdDeviceProof);
console.log('✓ Third device proof verified:', thirdVerification !== null);
console.log('\n=== All Tests Passed! ===');
console.log('✓ Device chain generation works');
console.log('✓ Device proof verification works');
console.log('✓ Device bundle export/import works');
console.log('✓ Cross-device attestation works');
console.log('✓ Profile addresses are consistent across devices');
return true;
} catch (error) {
console.error('\n❌ Test failed:', error.message);
console.error('Stack:', error.stack);
return false;
}
}
// Run the test
testCompleteDeviceChainWorkflow()
.then(success => {
if (success) {
console.log('\n🎉 Complete device chain workflow test PASSED!');
process.exit(0);
} else {
console.log('\n💥 Complete device chain workflow test FAILED!');
process.exit(1);
}
})
.catch(error => {
console.error('\n💥 Unexpected error:', error);
process.exit(1);
});