- 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
234 lines
7.5 KiB
Markdown
234 lines
7.5 KiB
Markdown
# 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
|
|
|
|
```typescript
|
|
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
|
|
|
|
```typescript
|
|
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
|
|
|
|
```typescript
|
|
// 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
|
|
|
|
```typescript
|
|
// 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
|
|
|
|
```typescript
|
|
interface UserIdentity {
|
|
userId: string; // Hash of master public key
|
|
publicKey: Uint8Array; // Master public key
|
|
mnemonic?: string; // Recovery phrase
|
|
}
|
|
```
|
|
|
|
### DeviceIdentity
|
|
|
|
```typescript
|
|
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:
|
|
|
|
1. **Derive Ed25519 keypair** from HD path
|
|
2. **Add multicodec prefix** (0xed01) to public key
|
|
3. **Hash with SHA256** for standard format
|
|
4. **Encode as base58** with multihash prefix (0x12)
|
|
5. **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:
|
|
|
|
1. **Master device** tracks the highest device index
|
|
2. **New device** receives its assigned index during pairing
|
|
3. **Storage key**: `identity_<userId>_highestDeviceIndex`
|
|
4. **Fallback**: System can detect existing indices by testing derivations
|
|
|
|
This prevents peer ID collisions when multiple devices join the same identity.
|
|
|
|
## Security Considerations
|
|
|
|
1. **Mnemonic Storage**: The mnemonic is stored in AsyncStorage. In production, consider encrypting it.
|
|
2. **Private Keys**: Device private keys are stored locally. Use secure storage in production.
|
|
3. **Recovery Phrase**: Users should backup their recovery phrase securely.
|
|
4. **Device Removal**: Removing a device only removes it from the registry, not from the device itself.
|
|
5. **Peer ID Verification**: Any peer ID can be verified as belonging to a user by testing derivation paths.
|
|
6. **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:
|
|
|
|
1. User identity is registered with the DHT
|
|
2. Each device is registered under the user
|
|
3. DHT tracks online/offline status of devices
|
|
4. 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
|
|
|
|
1. **Detection**: System detects peer ID change after `restoreFromMnemonic()`
|
|
2. **Broadcast**: Sends update notification via `/metatrom/identity/peer-update/1.0.0` protocol
|
|
3. **Update**: Other devices update their records automatically
|
|
4. **Migration**: Chat messages and connections migrate to new peer ID
|
|
|
|
### Usage
|
|
|
|
```typescript
|
|
// 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 |