- Hierarchical user/device identity system with HD key derivation - Dependency injection for AsyncStorage and Platform - Self-contained TypeScript declarations - Ed25519 keypairs managed by IdentityManager - Deterministic peer ID generation from BIP39 mnemonic
Identity Management Component v1.0.0
Hierarchical user/device identity management system with HD key derivation for multi-device support.
Features
- HD Key Derivation: Uses BIP39 mnemonics and BIP32 HD wallets
- User/Device Hierarchy: Master user identity with derived device identities
- Deterministic Peer IDs: Generates standard libp2p peer IDs (12D3KooW format) from HD keys
- Secure Storage: Persistent storage with AsyncStorage adapter
- Device Management: Add, remove, and list devices with unique indices
- Recovery: 24-word mnemonic phrase for backup/restore
- libp2p Compatible: Generates Ed25519 keypairs and standard peer IDs
- Verifiable Identity: Peer IDs can be cryptographically verified as belonging to a user
Usage
Basic Usage
import { identityManager } from '@/components/identity/1.0.0';
// Initialize identity (creates new or loads existing)
const userIdentity = await identityManager.initialize();
console.log('User ID:', userIdentity.userId);
// Get current device
const device = await identityManager.getCurrentDevice();
console.log('Device ID:', device.deviceId);
// Get libp2p keypair
const keypair = await identityManager.getLibp2pKeypair();
Advanced Usage with Dependency Injection
import {
createIdentityManager,
IdentityConfig
} from '@/components/identity/1.0.0';
const config: IdentityConfig = {
storagePrefix: '@MyApp',
mnemonicStrength: 256,
deviceNameProvider: async () => 'Custom Device Name'
};
const identityManager = createIdentityManager(config);
Device Management
// Create new device identity (auto-increments index)
const newDevice = await identityManager.createDeviceIdentity('Tablet');
console.log('New device peer ID:', newDevice.deviceId); // 12D3KooW...
// List all devices
const devices = await identityManager.getRegisteredDevices();
// Remove a device
await identityManager.removeDevice(deviceId);
// Verify a peer belongs to this user
const peerBelongsToUser = await identityManager.verifyPeerOwnership(peerId);
Backup and Recovery
// Get recovery phrase
const mnemonic = identityManager.getMnemonic();
// Restore from mnemonic (maintains device index coordination)
await identityManager.restoreFromMnemonic(mnemonic);
// After restoration, device gets next available index
const device = await identityManager.getCurrentDevice();
console.log('Device index:', device.derivationPath); // e.g., m/44'/0'/0'/0/1
Interfaces
IIdentityManager
Main interface for identity management operations.
UserIdentity
interface UserIdentity {
userId: string; // Hash of master public key
publicKey: Uint8Array; // Master public key
mnemonic?: string; // Recovery phrase
}
DeviceIdentity
interface DeviceIdentity {
deviceId: string; // libp2p peer ID (12D3KooW... format)
deviceName: string; // Human-readable name
publicKey: Uint8Array; // Ed25519 public key
privateKey: Uint8Array; // Ed25519 private key (seed)
derivationPath: string; // HD derivation path (m/44'/0'/0'/0/index)
createdAt: number;
lastSeen?: number;
}
Architecture
┌─────────────────────────────────┐
│ IdentityFactory │
│ (Singleton Factory) │
└─────────────┬───────────────────┘
│
▼
┌─────────────────────────────────┐
│ IdentityManager │
│ (Core Implementation) │
└─────────────┬───────────────────┘
│
▼
┌─────────────────────────────────┐
│ AsyncStorageAdapter │
│ (Persistence Layer) │
└─────────────────────────────────┘
HD Key Derivation Path
The component uses BIP44-like derivation paths:
m/44'/0'/0'/0/[device_index]
44': Purpose (identity management)0': Coin type (custom for this app)0': Account (always 0 for now)0: External chain[device_index]: Sequential device index (0, 1, 2, ...)
Each device gets a unique index, ensuring unique peer IDs while maintaining the cryptographic relationship to the user identity.
Peer ID Generation
The system generates standard libp2p peer IDs from Ed25519 keys:
- Derive Ed25519 keypair from HD path
- Add multicodec prefix (0xed01) to public key
- Hash with SHA256 for standard format
- Encode as base58 with multihash prefix (0x12)
- Result: Peer IDs starting with
12D3KooW...
This ensures compatibility with all libp2p implementations while maintaining deterministic generation from the mnemonic.
Device Index Coordination
During device pairing:
- Master device tracks the highest device index
- New device receives its assigned index during pairing
- Storage key:
identity_<userId>_highestDeviceIndex - Fallback: System can detect existing indices by testing derivations
This prevents peer ID collisions when multiple devices join the same identity.
Security Considerations
- Mnemonic Storage: The mnemonic is stored in AsyncStorage. In production, consider encrypting it.
- Private Keys: Device private keys are stored locally. Use secure storage in production.
- Recovery Phrase: Users should backup their recovery phrase securely.
- Device Removal: Removing a device only removes it from the registry, not from the device itself.
- Peer ID Verification: Any peer ID can be verified as belonging to a user by testing derivation paths.
- Deterministic Generation: Lost devices can be recovered with the same peer ID using mnemonic + index.
DHT Integration
The identity system integrates with the DHT for user/device discovery:
- User identity is registered with the DHT
- Each device is registered under the user
- DHT tracks online/offline status of devices
- Enables device handoff and multi-device sync
Peer ID Update Broadcasting
When a device's peer ID changes (typically after pairing and identity restoration), the system automatically notifies other devices:
How It Works
- Detection: System detects peer ID change after
restoreFromMnemonic() - Broadcast: Sends update notification via
/metatrom/identity/peer-update/1.0.0protocol - Update: Other devices update their records automatically
- Migration: Chat messages and connections migrate to new peer ID
Usage
// Automatic during pairing
const oldPeerId = await identityManager.getCurrentDevice()?.deviceId;
await identityManager.restoreFromMnemonic(mnemonic);
const newPeerId = await identityManager.getCurrentDevice()?.deviceId;
// Broadcast if changed (automatic in pairing flow)
if (oldPeerId !== newPeerId) {
await identityManager.broadcastPeerIdUpdate(
oldPeerId,
newPeerId,
sendProtocolData
);
}
Benefits
- Seamless Updates: No manual intervention needed
- Preserves History: Chat and connection history maintained
- Prevents Duplicates: Eliminates duplicate peer ID issues
- Network Coherence: All devices stay synchronized
Version
- Component Version: 1.0.0
- Protocol Version: /metatrom/identity/1.0.0
License
MIT