← Back to Main Documentation Core Systems Index

Plings HD Wallet Management Architecture

Created: Sön 13 Jul 2025 00:17:00 CEST
Version: 2.0 - Wallet-First Design
Status: Production Architecture

Overview

The Plings HD Wallet Management Architecture implements a wallet-first design where wallet versions serve as the primary organizational structure for all cryptographic operations. This architecture enables secure key management, seamless transitions during security incidents, and multi-environment support while maintaining backward compatibility.

Core Principle: Wallet Versions as Top-Level Hierarchy

Architectural Philosophy

Traditional Approach (Deprecated):

Master Key → Manufacturer → Products

Plings Wallet-First Approach (Current):

Master Key → Wallet Version → Manufacturer → Products

This inversion places wallet security and versioning at the foundation, enabling:

  • Clean key rotation without disrupting manufacturer hierarchies
  • Multi-environment support (development, testing, production)
  • Progressive security evolution from centralized to distributed key management
  • Incident response capabilities with automated key compromise handling

HD Wallet Structure

Solana Standard Hierarchy (SLIP-0044)

m/44'/501'/ (Solana Standard Base)
├── 1' → Wallet v1 (Current Production)
│   ├── 1/ → Plings (Manufacturer Index 1)
│   │   ├── 1/ → Generic Tags (Category 1)
│   │   ├── 2/ → Test Batches (Category 2)
│   │   └── 3/ → Manufacturer Batches (Category 3)
│   ├── 2/ → IKEA (Manufacturer Index 2)
│   │   ├── 1/ → Mountain Bikes (Category 1, Class Pointer: 3K7mX9abDcE)
│   │   ├── 2/ → Furniture (Category 2, Class Pointer: 4K7mX9abDcE)
│   │   └── 3/ → Tools (Category 3, Class Pointer: 5K7mX9abDcE)
│   ├── 3/ → Coca-Cola (Manufacturer Index 3)
│   │   ├── 1/ → Classic Products (Category 1, Class Pointer: 2rt5KqL9mXw)
│   │   ├── 2/ → Diet Products (Category 2, Class Pointer: jj9QmRxPtK8)
│   │   └── 3/ → Energy Products (Category 3, Class Pointer: 7K8mX9abDcE)
│   └── 4-999/ → Additional Manufacturers
├── 2' → Wallet v2 (Post-Key-Compromise)
│   ├── 1/ → Plings (New Wallet)
│   ├── 2/ → IKEA (Migrated to New Wallet)
│   ├── 3/ → Coca-Cola (Migrated to New Wallet)
│   └── 4-999/ → Other Manufacturers (Migrated)
├── 3' → Wallet v3 (Development/Testing)
│   ├── 1/ → Plings Dev Environment
│   ├── 10/ → Test Manufacturer A
│   └── 11/ → Test Manufacturer B
└── 4-999' → Future Wallet Versions

Path Examples with Wallet Context

Wallet v1 (Current Production)

# Plings Generic Tag
Path: 2.2.2.2.2
Class Pointer: 4K7mX9abDcE
HD Derivation: m/44'/501'/1'/1'/1'/1'/1'/1'
URL: https://s.plings.io?t=q&p=2.2.2.2.2&cp=4K7mX9abDcE&i=<solana_address>

# IKEA Mountain Bike Instance
Path: 2.3.2.7P.9j
Class Pointer: 3K7mX9abDcE
HD Derivation: m/44'/501'/1'/2'/1'/2024'/158'
URL: https://s.plings.io?t=q&p=2.3.2.7P.9j&cp=3K7mX9abDcE&i=<solana_address>

# Coca-Cola Classic Instance
Path: 2.3j.4.5Q.3L8z
Class Pointer: 2rt5KqL9mXw
HD Derivation: m/44'/501'/1'/3'/1255'/5847'/90000'
URL: https://s.plings.io?t=q&p=2.3j.4.5Q.3L8z&cp=2rt5KqL9mXw&i=<solana_address>

Wallet v2 (Post-Compromise Migration)

# Same logical paths, different wallet version
Path: 2.2.2.2.2 (Wallet v2)
Class Pointer: 4K7mX9abDcE (same as v1)
HD Derivation: m/44'/501'/2'/1'/1'/1'/1'/1'
URL: https://s.plings.io?t=q&p=2.2.2.2.2&cp=4K7mX9abDcE&i=<solana_address>

# IKEA Mountain Bike in New Wallet
Path: 2.3.2.7P.9j (Wallet v2)
Class Pointer: 3K7mX9abDcE (same as v1)
HD Derivation: m/44'/501'/2'/2'/1'/2024'/158'
URL: https://s.plings.io?t=q&p=2.3.2.7P.9j&cp=3K7mX9abDcE&i=<solana_address>

Wallet v3 (Development Environment)

# Development Testing
Path: 2.3.2.2.2 (Wallet v3)
Class Pointer: 6K7mX9abDcE (development class)
HD Derivation: m/44'/501'/3'/1'/2'/1'/1'/1'
URL: https://s.plings.io?t=q&p=2.3.2.2.2&cp=6K7mX9abDcE&i=<solana_address>

Database Architecture

Core Tables Structure

1. Wallet Versions Registry

CREATE TABLE wallet_versions (
    version_id INTEGER PRIMARY KEY,
    version_name VARCHAR(10) NOT NULL UNIQUE,    -- "v1", "v2", "v3", etc.
    master_key_id VARCHAR(100) NOT NULL,         -- HSM key reference
    description TEXT,                             -- "Production wallet", "Post-compromise v2"
    environment VARCHAR(20) DEFAULT 'production', -- "production", "testing", "development"
    security_level VARCHAR(20) DEFAULT 'standard', -- "standard", "high", "experimental"
    status VARCHAR(20) DEFAULT 'active',          -- "active", "compromised", "deprecated", "retired"
    created_at TIMESTAMP DEFAULT NOW(),
    compromised_at TIMESTAMP,                     -- When key compromise was detected
    retired_at TIMESTAMP,                         -- When wallet was fully retired
    is_default BOOLEAN DEFAULT FALSE,             -- Only one default wallet allowed
    
    -- Constraints
    CONSTRAINT unique_version_name UNIQUE (version_name),
    CONSTRAINT unique_default_wallet 
        EXCLUDE (is_default WITH =) WHERE (is_default = true),
    
    -- Indexes
    INDEX idx_wallet_status (status),
    INDEX idx_wallet_environment (environment),
    INDEX idx_wallet_default (is_default) WHERE (is_default = true)
);

-- Initialize production wallet v1
INSERT INTO wallet_versions (
    version_id, version_name, master_key_id, description, 
    environment, status, is_default
) VALUES (
    1, 'v1', 'plings_master_key_v1', 'Initial production wallet', 
    'production', 'active', true
);

2. Enhanced Manufacturer Registry

CREATE TABLE manufacturer_registry (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    wallet_version INTEGER NOT NULL REFERENCES wallet_versions(version_id),
    manufacturer_index INTEGER NOT NULL,          -- Index within this wallet (1=Plings, 2+=Others)
    manufacturer_name VARCHAR(100) NOT NULL,      -- "Plings", "IKEA", "Coca-Cola"
    organization_id UUID,                         -- Link to organization
    public_key TEXT,                              -- Ed25519 public key if delegated
    key_delegation_level VARCHAR(20) DEFAULT 'none', -- "none", "verification", "full"
    status VARCHAR(20) DEFAULT 'active',          -- "active", "suspended", "migrating", "retired"
    registered_by UUID NOT NULL,
    registered_at TIMESTAMP DEFAULT NOW(),
    migrated_from_wallet INTEGER,                 -- Previous wallet version (for migration tracking)
    migration_completed_at TIMESTAMP,
    
    -- Constraints
    CONSTRAINT unique_manufacturer_per_wallet 
        UNIQUE (wallet_version, manufacturer_index),
    CONSTRAINT unique_name_per_wallet 
        UNIQUE (wallet_version, manufacturer_name),
    CONSTRAINT check_plings_index_one
        CHECK (manufacturer_name != 'Plings' OR manufacturer_index = 1),
    
    -- Foreign Keys
    FOREIGN KEY (organization_id) REFERENCES organizations(id),
    FOREIGN KEY (registered_by) REFERENCES users(id),
    FOREIGN KEY (migrated_from_wallet) REFERENCES wallet_versions(version_id),
    
    -- Indexes
    INDEX idx_manufacturer_wallet_name (wallet_version, manufacturer_name),
    INDEX idx_manufacturer_organization (organization_id),
    INDEX idx_manufacturer_status (status)
);

-- Initialize Plings as manufacturer #1 in wallet v1
INSERT INTO manufacturer_registry (
    wallet_version, manufacturer_index, manufacturer_name, 
    status, registered_by
) VALUES (
    1, 1, 'Plings', 'active', '00000000-0000-0000-0000-000000000000'
);

3. Enhanced Path Registry

CREATE TABLE path_registry (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    wallet_version INTEGER NOT NULL REFERENCES wallet_versions(version_id),
    path VARCHAR(50) NOT NULL,                    -- e.g., "2.2.2", "2.3.2.9j" (class pointer separate)
    hd_derivation VARCHAR(100) NOT NULL,          -- e.g., "m/44'/501'/1'/1'/1'/1'"
    allocation_type VARCHAR(20) NOT NULL,         -- "generic", "test", "manufacturer", "development"
    manufacturer_name VARCHAR(100),               -- For manufacturer batch allocations
    batch_name VARCHAR(100),                      -- Human-readable batch identifier
    quantity INTEGER,                             -- Number of identifiers in this allocation
    purpose TEXT,                                 -- Description/notes
    status VARCHAR(20) DEFAULT 'active',          -- "active", "exhausted", "migrated", "retired"
    allocated_by UUID NOT NULL,
    allocated_at TIMESTAMP DEFAULT NOW(),
    completed_at TIMESTAMP,                       -- When batch generation completed
    migrated_to_wallet INTEGER,                   -- Target wallet for migration
    migrated_at TIMESTAMP,                        -- When migration completed
    
    -- Constraints
    CONSTRAINT unique_path_per_wallet 
        UNIQUE (wallet_version, path),
    
    -- Foreign Keys
    FOREIGN KEY (allocated_by) REFERENCES users(id),
    FOREIGN KEY (migrated_to_wallet) REFERENCES wallet_versions(version_id),
    
    -- Indexes
    INDEX idx_path_wallet_path (wallet_version, path),
    INDEX idx_path_allocation_type (allocation_type),
    INDEX idx_path_manufacturer (manufacturer_name),
    INDEX idx_path_status (status)
);

4. Manufacturer Migration Tracking

CREATE TABLE manufacturer_lineage (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    canonical_name VARCHAR(100) NOT NULL,         -- "IKEA", "Coca-Cola" (consistent across wallets)
    current_wallet_version INTEGER NOT NULL,
    current_manufacturer_index INTEGER NOT NULL,
    predecessor_wallet INTEGER,                    -- Previous wallet version
    predecessor_index INTEGER,                     -- Previous manufacturer index
    migration_reason VARCHAR(50),                  -- "key_compromise", "security_upgrade", "environment_separation"
    migration_date TIMESTAMP DEFAULT NOW(),
    migration_status VARCHAR(20) DEFAULT 'active', -- "active", "in_progress", "completed"
    migration_completion_percentage INTEGER DEFAULT 0, -- 0-100% for tracking progress
    
    -- Foreign Keys
    FOREIGN KEY (current_wallet_version, current_manufacturer_index) 
        REFERENCES manufacturer_registry(wallet_version, manufacturer_index),
    FOREIGN KEY (predecessor_wallet) REFERENCES wallet_versions(version_id),
    
    -- Constraints
    CONSTRAINT unique_canonical_manufacturer UNIQUE (canonical_name),
    
    -- Indexes
    INDEX idx_lineage_canonical (canonical_name),
    INDEX idx_lineage_current_wallet (current_wallet_version),
    INDEX idx_lineage_migration_status (migration_status)
);

Key Management Architecture

Three-Tier Key Storage Strategy

Plings implements a progressive three-tier key management approach that balances immediate deployment needs with long-term security requirements:

Tier Overview

Tier Solution Timeline Cost Security Level Use Case
Initial Vercel Environment Variables Immediate $0 Software-based MVP, early customers
Next Level SoftHSM 2-4 weeks $20-50/mo HSM-equivalent Growing business
Final Level Hardware HSM 6-9 months $1,500-5,000/mo Hardware-certified Enterprise

Tier 1: Vercel Environment Variables (Current)

Implementation:

// Initial tier - Vercel environment variables
class VercelKeyManager {
  constructor() {
    this.masterKey = process.env.PLINGS_MASTER_KEY; // Base58 encoded
    this.walletVersion = parseInt(process.env.PLINGS_DEFAULT_WALLET || '1');
  }
  
  async deriveKey(path) {
    // HD wallet derivation in API functions
    const wallet = new PlingsHDWallet(this.masterKey);
    const keyPair = wallet.deriveKey(path);
    
    // Return only public key, discard private key
    return {
      publicKey: keyPair.publicKey,
      // Private key is never stored or transmitted
    };
  }
}

Security Model:

  • Master key encrypted by Vercel infrastructure
  • Private keys derived on-demand, never stored
  • Environment-specific key isolation
  • Suitable for immediate production deployment

Tier 2: SoftHSM (Next Level)

Implementation:

// Next level - SoftHSM with PKCS#11
class SoftHSMKeyManager {
  constructor() {
    this.hsmEndpoint = process.env.HSM_ENDPOINT;
    this.apiKey = process.env.HSM_API_KEY;
  }
  
  async deriveKey(path) {
    // Call dedicated HSM service
    const response = await fetch(`${this.hsmEndpoint}/api/derive-key`, {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${this.apiKey}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ path })
    });
    
    return await response.json();
  }
}

Security Model:

  • PKCS#11 standard interface
  • Keys never leave HSM boundary
  • Full audit trail for compliance
  • Hardware-equivalent security

Tier 3: Hardware HSM (Final Level)

Implementation:

class PlingsHardwareHSMManager:
    """
    Hardware Security Module integration for enterprise-grade key management.
    
    Architecture:
    - Each wallet version has a unique master key stored in HSM
    - Keys are never extractable from HSM
    - Derivation operations performed within HSM when possible
    - Backup keys stored in geographically separate HSMs
    """
    
    def __init__(self, hsm_config: Dict[str, str]):
        self.primary_hsm = CloudHSM(hsm_config['primary_endpoint'])
        self.backup_hsm = CloudHSM(hsm_config['backup_endpoint'])
        self.wallet_versioning = hsm_config.get('wallet_versioning', True)

### Migration Strategy Between Tiers

#### Tier Progression Path

Initial Tier (Vercel) → Next Level (SoftHSM) → Final Level (Hardware HSM) ↓ ↓ ↓ Immediate 2-4 weeks 6-9 months $0 cost $20-50/mo $1,500-5,000/mo MVP ready Enhanced security Enterprise grade


#### Migration Triggers

**Vercel → SoftHSM Migration**:
- Customer base > 1,000 organizations
- Security audit requirements
- Need for audit trails
- Compliance requirements

**SoftHSM → Hardware HSM Migration**:
- Enterprise customer mandates
- Regulatory compliance (FIPS 140-2)
- Revenue > $1M annually
- Geographic redundancy requirements

#### Zero-Downtime Migration Process

```javascript
// Dual-mode operation during migration
class TieredKeyManager {
  constructor() {
    this.currentTier = process.env.KEY_MANAGEMENT_TIER || 'vercel';
    this.nextTier = process.env.MIGRATION_TARGET_TIER;
    this.migrationPhase = process.env.MIGRATION_PHASE || 'none';
  }
  
  async deriveKey(path) {
    switch (this.migrationPhase) {
      case 'testing':
        // Test new tier alongside current
        const [current, next] = await Promise.all([
          this.deriveWithTier(this.currentTier, path),
          this.deriveWithTier(this.nextTier, path)
        ]);
        this.validateConsistency(current, next);
        return current;
        
      case 'gradual':
        // Gradual rollout based on user/batch criteria
        const useNextTier = this.shouldUseNextTier(path);
        return this.deriveWithTier(useNextTier ? this.nextTier : this.currentTier, path);
        
      case 'complete':
        // Full migration to new tier
        return this.deriveWithTier(this.nextTier, path);
        
      default:
        // Normal operation
        return this.deriveWithTier(this.currentTier, path);
    }
  }
}

Wallet Version Continuity

Critical: Wallet versions remain consistent across all tiers:

  • Wallet v1 identifiers work the same on Vercel, SoftHSM, and Hardware HSM
  • Only the master key storage location changes
  • Same HD derivation paths and algorithms
  • Public keys remain identical during migration

Implementation Guides

For Initial Deployment: See Vercel Key Management Guide
For SoftHSM Migration: See SoftHSM Migration Guide
For Hardware HSM: See HSM Integration Guide

def get_master_key(self, wallet_version: int) -> bytes:
    """
    Retrieve wallet-specific master key from HSM.
    
    Args:
        wallet_version: Wallet version identifier (1, 2, 3, etc.)
        
    Returns:
        Master key bytes for cryptographic operations
        
    Raises:
        HSMKeyNotFoundError: If wallet key doesn't exist
        HSMAccessError: If HSM is unavailable
    """
    key_id = f"plings_master_key_v{wallet_version}"
    
    try:
        # Try primary HSM first
        return self.primary_hsm.get_key(key_id)
    except HSMKeyNotFoundError:
        logger.warning(f"Key {key_id} not found in primary HSM, trying backup")
        return self.backup_hsm.get_key(key_id)
    except HSMAccessError as e:
        logger.error(f"Primary HSM unavailable: {e}, failing over to backup")
        return self.backup_hsm.get_key(key_id)

def create_new_wallet(self, reason: str = "security_upgrade", 
                     environment: str = "production") -> int:
    """
    Generate new wallet version with fresh master key.
    
    Args:
        reason: Reason for new wallet ("key_compromise", "security_upgrade", etc.)
        environment: Target environment ("production", "testing", "development")
        
    Returns:
        New wallet version ID
    """
    # Get next available wallet version
    new_version = self._get_next_wallet_version()
    key_id = f"plings_master_key_v{new_version}"
    
    # Generate master key in both HSMs
    master_key_metadata = {
        "key_type": "ed25519",
        "extractable": False,
        "key_usage": ["derive", "sign"],
        "backup_required": True
    }
    
    # Create in primary HSM
    primary_key = self.primary_hsm.generate_key(key_id, master_key_metadata)
    
    # Create backup in secondary HSM
    backup_key = self.backup_hsm.generate_key(key_id, master_key_metadata)
    
    # Verify keys match (if extractable for verification)
    if not self._verify_key_consistency(primary_key, backup_key):
        raise HSMKeyConsistencyError("Primary and backup keys don't match")
    
    # Register new wallet version in database
    self._register_wallet_version(
        version_id=new_version,
        key_id=key_id,
        reason=reason,
        environment=environment
    )
    
    logger.info(f"✅ Created new wallet v{new_version} for {reason}")
    return new_version

def derive_wallet_key(self, wallet_version: int, derivation_path: str) -> bytes:
    """
    Derive child key from wallet master key using BIP32.
    
    Args:
        wallet_version: Wallet version to derive from
        derivation_path: BIP32 path (e.g., "m/44'/501'/1'/2'/1'/3'/158'")
        
    Returns:
        Derived key bytes
    """
    master_key = self.get_master_key(wallet_version)
    
    # Parse derivation path
    path_indices = self._parse_derivation_path(derivation_path)
    
    # Perform BIP32 derivation
    current_key = master_key
    for index in path_indices:
        current_key = self._derive_child_key(current_key, index)
    
    return current_key ```

Wallet Lifecycle Management

Wallet Creation Process

class WalletLifecycleManager:
    def __init__(self, key_manager: PlingsKeyManager):
        self.key_manager = key_manager
        self.db = DatabaseManager()
    
    def create_production_wallet(self, reason: str) -> Dict[str, Any]:
        """Create new production wallet with full security protocols."""
        
        # 1. Generate new wallet with HSM keys
        new_wallet_id = self.key_manager.create_new_wallet(
            reason=reason,
            environment="production"
        )
        
        # 2. Initialize Plings as manufacturer #1
        plings_manufacturer = self.db.create_manufacturer(
            wallet_version=new_wallet_id,
            manufacturer_index=1,
            name="Plings",
            status="active"
        )
        
        # 3. Set up basic path allocations
        basic_paths = [
            ("1.1", "generic_tags", "Plings generic tags"),
            ("1.2", "test_batches", "Plings test batches"),
            ("1.3", "manufacturer_batches", "Plings manufacturer batches")
        ]
        
        for path, alloc_type, purpose in basic_paths:
            self.db.allocate_path(
                wallet_version=new_wallet_id,
                path=path,
                allocation_type=alloc_type,
                purpose=purpose
            )
        
        # 4. Update wallet status and default if needed
        if reason == "key_compromise":
            self._handle_key_compromise_transition(new_wallet_id)
        
        logger.info(f"✅ Production wallet v{new_wallet_id} ready")
        return {
            "wallet_version": new_wallet_id,
            "version_name": f"v{new_wallet_id}",
            "manufacturer_count": 1,
            "initial_paths": len(basic_paths)
        }
    
    def create_development_wallet(self, description: str) -> Dict[str, Any]:
        """Create development wallet for testing."""
        
        dev_wallet_id = self.key_manager.create_new_wallet(
            reason="development_environment",
            environment="development"
        )
        
        # Initialize with test manufacturers
        test_manufacturers = [
            (1, "Plings"),
            (10, "Test Manufacturer A"),
            (11, "Test Manufacturer B"),
            (12, "Load Test Manufacturer")
        ]
        
        for index, name in test_manufacturers:
            self.db.create_manufacturer(
                wallet_version=dev_wallet_id,
                manufacturer_index=index,
                name=name,
                status="active"
            )
        
        logger.info(f"✅ Development wallet v{dev_wallet_id} ready")
        return {
            "wallet_version": dev_wallet_id,
            "version_name": f"v{dev_wallet_id}",
            "environment": "development",
            "manufacturer_count": len(test_manufacturers)
        }

URL Format and Backward Compatibility

URL Parameter Strategy

Current URLs (Wallet v1 - Default)

# Default wallet (v1) - no wallet parameter needed
https://s.plings.io?t=q&i=<instance>&p=1.1.1
https://s.plings.io?t=q&p=2.3.2.9j&cp=4K7mX9abDcE&i=<solana_address>
https://s.plings.io?t=q&p=2.3.4.5Q&cp=3K7mX9abDcE&i=<solana_address>

Legacy Identifier Resolution

def resolve_identifier_url(instance_key: str, path: str) -> Dict[str, Any]:
    """
    Resolve identifier with intelligent wallet detection.
    
    Resolution Priority:
    1. Cryptographic verification against all active wallets
    2. Default wallet for new identifier generation
    3. Multi-wallet search for legacy identifier migration
    """
    
    # Try default wallet first (fastest path for new identifiers)
    default_wallet = get_default_wallet_version()
    result = verify_identifier(instance_key, path, default_wallet)
    if result["valid"]:
        return result
    
    # Fall back to multi-wallet search for legacy identifiers
    logger.info(f"Identifier not found in default wallet, searching all active wallets")
    for wallet_id in get_active_wallet_versions():
        if wallet_id == default_wallet:
            continue  # Already tried
        
        result = verify_identifier(instance_key, path, wallet_id)
        if result["valid"]:
            logger.info(f"Legacy identifier found in wallet v{wallet_id}")
            return {
                **result,
                "legacy_identifier": True,
                "detected_wallet": f"v{wallet_id}",
                "current_url": f"https://s.plings.io?t=q&i={instance_key}&p={path}"
            }
    
    return {"valid": False, "reason": "Identifier not found in any active wallet"}

Security Model

Multi-Wallet Threat Analysis

Threat: Key Compromise

Impact: Single wallet compromised, others remain secure Mitigation:

  • Immediate wallet retirement
  • Automated new wallet creation
  • Manufacturer migration protocols
  • Grace period for legacy identifier support

Threat: HSM Failure

Impact: Loss of access to specific wallet keys Mitigation:

  • Redundant HSM infrastructure
  • Cross-region key backups
  • Automatic failover protocols
  • Emergency key recovery procedures

Threat: Database Compromise

Impact: Wallet metadata exposed, but not private keys Mitigation:

  • Keys remain secure in HSM
  • Wallet version obfuscation
  • Database encryption at rest
  • Audit logging for all wallet operations

Progressive Security Evolution

Phase 1: Plings-Managed (Current)

class PlingsmanagedSecurity:
    """
    All keys stored in Plings HSM infrastructure.
    Organizations trust Plings for key management.
    """
    
    def generate_manufacturer_key(self, manufacturer_name: str, 
                                 wallet_version: int) -> Dict[str, str]:
        """Generate manufacturer key within Plings HSM."""
        master_key = self.key_manager.get_master_key(wallet_version)
        manufacturer_index = self.get_manufacturer_index(manufacturer_name, wallet_version)
        
        # Derive manufacturer key
        derivation_path = f"m/44'/501'/{wallet_version}'/{manufacturer_index}'"
        manufacturer_key = derive_key(master_key, derivation_path)
        
        # Store public key for verification
        public_key = get_public_key(manufacturer_key)
        self.db.update_manufacturer_public_key(
            wallet_version, manufacturer_index, public_key
        )
        
        return {
            "manufacturer_key": manufacturer_key,  # Private - stays in HSM
            "public_key": public_key,              # Public - stored in database
            "derivation_path": derivation_path
        }

Phase 2: Hybrid Management (Planned)

class HybridSecurity:
    """
    Organizations can provide their own public keys for verification.
    Private keys can be in Plings HSM or organization's control.
    """
    
    def register_organization_key(self, manufacturer_name: str, 
                                 organization_public_key: str,
                                 key_source: str) -> Dict[str, str]:
        """Register organization-provided public key."""
        
        # Validate public key format
        if not self.validate_ed25519_public_key(organization_public_key):
            raise InvalidPublicKeyError("Invalid Ed25519 public key format")
        
        # Store in manufacturer registry
        self.db.update_manufacturer(
            manufacturer_name=manufacturer_name,
            public_key=organization_public_key,
            key_delegation_level="verification",
            key_source=key_source  # "organization_hsm", "organization_managed", "plings_hsm"
        )
        
        return {
            "verification_method": "organization_public_key",
            "key_delegation_level": "verification",
            "public_key": organization_public_key
        }

Phase 3: Full Delegation (Future)

class FullDelegation:
    """
    Organizations control their hardened derivation path.
    Provide verification APIs to Plings ecosystem.
    Payment routing maintained through Plings PDAs.
    """
    
    def register_organization_delegation(self, manufacturer_name: str,
                                       verification_endpoint: str,
                                       pda_delegation_key: str) -> Dict[str, str]:
        """Register fully delegated organization verification."""
        
        # Validate verification endpoint
        if not self.validate_verification_endpoint(verification_endpoint):
            raise InvalidEndpointError("Verification endpoint validation failed")
        
        # Test verification capability
        test_result = self.test_organization_verification(verification_endpoint)
        if not test_result["success"]:
            raise VerificationTestFailure("Organization verification test failed")
        
        # Register delegation
        self.db.update_manufacturer(
            manufacturer_name=manufacturer_name,
            verification_endpoint=verification_endpoint,
            pda_delegation_key=pda_delegation_key,
            key_delegation_level="full"
        )
        
        return {
            "verification_method": "organization_api",
            "key_delegation_level": "full",
            "verification_endpoint": verification_endpoint,
            "pda_delegation_active": True
        }

Operational Procedures

Wallet Monitoring and Alerts

Health Check System

class WalletMonitoring:
    def __init__(self):
        self.alert_manager = AlertManager()
        self.metrics = MetricsCollector()
    
    def monitor_wallet_health(self) -> Dict[str, Any]:
        """Comprehensive wallet health monitoring."""
        
        health_report = {
            "timestamp": datetime.utcnow(),
            "wallets": {},
            "overall_status": "healthy",
            "alerts": []
        }
        
        for wallet in get_all_wallets():
            wallet_health = self._check_wallet_health(wallet)
            health_report["wallets"][wallet.version_name] = wallet_health
            
            # Generate alerts for critical issues
            if wallet_health["status"] == "critical":
                self.alert_manager.send_alert(
                    severity="critical",
                    message=f"Wallet {wallet.version_name} health critical",
                    details=wallet_health
                )
            
        return health_report
    
    def _check_wallet_health(self, wallet: WalletVersion) -> Dict[str, Any]:
        """Check individual wallet health metrics."""
        
        health = {
            "wallet_version": wallet.version_name,
            "status": "healthy",
            "issues": [],
            "metrics": {}
        }
        
        # Check HSM key accessibility
        try:
            key_accessible = self.key_manager.test_key_access(wallet.version_id)
            health["metrics"]["hsm_key_accessible"] = key_accessible
            if not key_accessible:
                health["issues"].append("HSM key not accessible")
                health["status"] = "critical"
        except Exception as e:
            health["issues"].append(f"HSM error: {str(e)}")
            health["status"] = "critical"
        
        # Check identifier generation rate
        generation_rate = self.metrics.get_identifier_generation_rate(wallet.version_id)
        health["metrics"]["daily_identifiers"] = generation_rate
        
        # Check verification success rate
        verification_rate = self.metrics.get_verification_success_rate(wallet.version_id)
        health["metrics"]["verification_success_rate"] = verification_rate
        if verification_rate < 0.95:  # Less than 95% success rate
            health["issues"].append("Low verification success rate")
            health["status"] = "warning"
        
        # Check manufacturer count
        manufacturer_count = self.db.count_active_manufacturers(wallet.version_id)
        health["metrics"]["active_manufacturers"] = manufacturer_count
        
        return health

Key Compromise Response Protocol

Automated Incident Response

class IncidentResponse:
    def __init__(self):
        self.key_manager = PlingsKeyManager()
        self.notification_service = NotificationService()
        self.audit_logger = AuditLogger()
    
    def handle_key_compromise(self, wallet_version: int, 
                            evidence: Dict[str, Any],
                            reporter: str) -> Dict[str, Any]:
        """
        Execute automated key compromise response protocol.
        
        Steps:
        1. Immediately mark wallet as compromised
        2. Create new wallet version
        3. Update default wallet
        4. Notify all stakeholders
        5. Begin manufacturer migration process
        """
        
        # Log incident
        incident_id = self.audit_logger.log_security_incident(
            incident_type="key_compromise",
            wallet_version=wallet_version,
            evidence=evidence,
            reporter=reporter
        )
        
        try:
            # 1. Mark wallet as compromised
            self.db.update_wallet_status(
                version_id=wallet_version,
                status="compromised",
                compromised_at=datetime.utcnow()
            )
            
            # 2. Create new wallet version
            new_wallet_id = self.key_manager.create_new_wallet(
                reason="key_compromise",
                environment="production"
            )
            
            # 3. Update default wallet
            self.db.set_default_wallet(new_wallet_id)
            
            # 4. Migrate Plings to new wallet immediately
            self._migrate_plings_to_new_wallet(new_wallet_id)
            
            # 5. Notify all stakeholders
            self.notification_service.send_security_alert(
                incident_id=incident_id,
                wallet_compromised=wallet_version,
                new_wallet=new_wallet_id,
                immediate_actions_required=True
            )
            
            # 6. Schedule manufacturer migrations
            migration_plan = self._create_migration_plan(wallet_version, new_wallet_id)
            
            self.audit_logger.log_incident_response(
                incident_id=incident_id,
                actions_taken=[
                    "wallet_marked_compromised",
                    "new_wallet_created",
                    "default_wallet_updated",
                    "plings_migrated",
                    "stakeholders_notified"
                ],
                new_wallet_version=new_wallet_id
            )
            
            return {
                "incident_id": incident_id,
                "compromised_wallet": f"v{wallet_version}",
                "new_wallet": f"v{new_wallet_id}",
                "migration_plan": migration_plan,
                "status": "incident_response_complete"
            }
            
        except Exception as e:
            self.audit_logger.log_incident_response_failure(
                incident_id=incident_id,
                error=str(e)
            )
            # Send emergency notification
            self.notification_service.send_emergency_alert(
                message="Key compromise response failed",
                incident_id=incident_id,
                error=str(e)
            )
            raise

Implementation Roadmap

Phase 1: Core Wallet Infrastructure (2 weeks)

  • ✅ Database schema updates
  • ✅ Wallet registry implementation
  • ✅ Basic HSM integration
  • ✅ Wallet-aware identifier generation

Phase 2: Migration & Security (2 weeks)

  • 🔄 Key compromise response protocols
  • 🔄 Manufacturer migration workflows
  • 🔄 Multi-wallet verification system
  • 🔄 Operational monitoring tools

Phase 3: Advanced Features (3 weeks)

  • 🔲 Development environment wallets
  • 🔲 Organization key delegation (Phase 2 security model)
  • 🔲 Automated wallet health monitoring
  • 🔲 Performance optimization for multi-wallet operations

Phase 4: Full Delegation Preparation (Future)

  • 🔲 Organization verification API framework
  • 🔲 PDA delegation protocols
  • 🔲 Full key delegation support
  • 🔲 Distributed key management tools

Benefits Summary

Security Benefits

  • Isolated key compromise impact: Only affected wallet compromised, others remain secure
  • Rapid incident response: Automated protocols for key compromise scenarios
  • Progressive security evolution: Smooth transition from centralized to distributed key management
  • HSM integration: Hardware-level security for all master keys

Operational Benefits

  • Multi-environment support: Separate wallets for development, testing, production
  • Clean migrations: Logical manufacturer namespaces maintained across wallet versions
  • Monitoring & alerting: Comprehensive health monitoring for all wallet operations
  • Audit trails: Complete traceability of all wallet and key management operations

Scalability Benefits

  • Unlimited wallet versions: No architectural limits on wallet creation
  • Manufacturer isolation: Manufacturers can operate independently within wallet namespaces
  • Performance optimization: Wallet-specific caching and optimization strategies
  • Global distribution: Wallet-specific geographic distribution for compliance

This wallet-first architecture provides the foundation for secure, scalable, and operationally robust HD wallet management while maintaining the simplicity and elegance needed for global adoption.

Wallet-Aware Path Registry Implementation

Path Allocation with Wallet Context

The path registry system is deeply integrated with the wallet architecture, ensuring cryptographic security and namespace isolation for each manufacturer.

Path Allocation Ranges by Wallet

Wallet Manufacturer Range Purpose Example Paths Management
v1 Plings (1) 2.2.*.x Generic Tags 2.2.2.2.2, 2.2.2.3.2 + class pointers Plings Internal
v1 Plings (1) 2.3.*.x Test Batches 2.3.2.2.2, 2.3.2.5.2 + class pointers Plings Internal
v1 IKEA (2) 2.*.*.x Furniture/Bikes 2.3.2.7P.9j + class pointer 4K7mX9abDcE IKEA
v1 Coca-Cola (3) 2.*.*.x Classic Products 2.3j.4.5Q.3L8z + class pointer 3K7mX9abDcE Coca-Cola
v2 All Same patterns Secondary production Production paths Same manufacturers
v3 Dev/Test 2.B.*.*.x, B.2.*.*.x Development 2.B.2.2.2, B.2.2.2 + class pointers Plings Dev

Wallet-Aware Path Allocation Process

def allocate_path_in_wallet(wallet_version: int, allocation_type: str, 
                           quantity: int, **kwargs) -> Dict[str, Any]:
    """
    Allocate path in specific wallet version.
    
    Args:
        wallet_version: Target wallet (1, 2, 3, etc.)
        allocation_type: Type of allocation
        quantity: Number of identifiers needed
        **kwargs: Additional parameters
    
    Returns:
        Allocation details with wallet-specific derivation
    """
    # Get manufacturer index within this wallet
    manufacturer_name = kwargs.get('manufacturer_name', 'Plings')
    manufacturer_index = get_manufacturer_index_in_wallet(wallet_version, manufacturer_name)
    
    if not manufacturer_index:
        # Auto-register manufacturer in new wallet if transferring
        if kwargs.get('source_wallet'):
            manufacturer_index = transfer_manufacturer_to_wallet(
                manufacturer_name, 
                source_wallet=kwargs['source_wallet'],
                target_wallet=wallet_version
            )
        else:
            raise ValueError(f"Manufacturer {manufacturer_name} not registered in wallet v{wallet_version}")
    
    # Build wallet-aware path
    if allocation_type == "generic":
        base_path = f"{manufacturer_index}.1"
    elif allocation_type == "test":
        base_path = f"{manufacturer_index}.2"
    elif allocation_type == "manufacturer_batch":
        base_path = f"{manufacturer_index}.3"
    elif allocation_type == "development":
        base_path = f"{manufacturer_index}.10"  # Development paths use 10+ range
    else:
        raise ValueError(f"Unknown allocation type: {allocation_type}")
    
    # Find next available index within this wallet
    max_index = get_max_index_for_wallet_path(wallet_version, base_path)
    new_path = f"{base_path}.{max_index + 1}"
    
    # Generate wallet-aware HD derivation
    hd_derivation = path_to_wallet_hd_derivation(new_path, wallet_version)
    
    # Register allocation
    allocation_id = register_wallet_path_allocation(
        wallet_version=wallet_version,
        path=new_path,
        hd_derivation=hd_derivation,
        allocation_type=allocation_type,
        quantity=quantity,
        **kwargs
    )
    
    return {
        "allocation_id": allocation_id,
        "wallet_version": wallet_version,
        "path": new_path,
        "hd_derivation": hd_derivation,
        "manufacturer_index": manufacturer_index,
        "url_format": f"https://s.plings.io?t=q&i=&p={new_path}",
        "transfer_capable": True
    }

Path-to-HD-Derivation Conversion

The wallet system converts business-friendly paths to cryptographic HD derivations:

def path_to_wallet_hd_derivation(path: str, wallet_version: int) -> str:
    """
    Convert path to wallet-aware HD derivation.
    
    Args:
        path: Object path (e.g., "2.3.2.7P.9j") with separate class pointer
        wallet_version: Wallet version (1, 2, 3, etc.)
        
    Returns:
        Wallet-aware HD derivation (e.g., "m/44'/501'/1'/2'/1'/3'/2024'/158'")
    """
    parts = path.split('.')
    
    # Start with Solana standard + wallet version (hardened)
    derivation = f"m/44'/501'/{wallet_version}'"
    
    # Manufacturer level is hardened (anchor point)
    manufacturer_index = parts[0]
    derivation += f"/{manufacturer_index}'"
    
    # Process remaining parts (class information handled separately via class pointer)
    for part in parts[1:]:
        # All path segments are regular indices, no special markers
        derivation += f"/{part}'"
    
    return derivation

Multi-Wallet Path Verification

When verifying identifiers, the system searches across all active wallets:

def resolve_identifier_with_wallet_detection(instance_key: str, path: str) -> Dict[str, Any]:
    """
    Resolve identifier with intelligent wallet detection.
    
    Resolution Priority:
    1. Cryptographic verification against all active wallets
    2. Default wallet for new identifier generation
    3. Multi-wallet search for legacy identifier migration
    """
    
    # Try default wallet first (fastest path for new identifiers)
    default_wallet = get_default_wallet_version()
    result = verify_identifier_in_wallet(instance_key, path, default_wallet)
    if result["valid"]:
        return {
            **result,
            "wallet_version": default_wallet,
            "is_default_wallet": True
        }
    
    # Fall back to multi-wallet search for legacy identifiers
    logger.info(f"Identifier not found in default wallet v{default_wallet}, searching all active wallets")
    for wallet_id in get_active_wallet_versions():
        if wallet_id == default_wallet:
            continue  # Already tried
        
        result = verify_identifier_in_wallet(instance_key, path, wallet_id)
        if result["valid"]:
            logger.info(f"Legacy identifier found in wallet v{wallet_id}")
            return {
                **result,
                "wallet_version": wallet_id,
                "legacy_identifier": True,
                "recommended_url": f"https://s.plings.io?t=q&i={instance_key}&p={path}",
                "migration_available": can_migrate_to_default_wallet(wallet_id)
            }
    
    return {
        "valid": False, 
        "reason": "Identifier not found in any active wallet",
        "searched_wallets": get_active_wallet_versions()
    }

Manufacturer Transfer Between Wallets

When migrating manufacturers between wallet versions:

def transfer_manufacturer_to_new_wallet(manufacturer_name: str, 
                                       source_wallet: int,
                                       target_wallet: int,
                                       transfer_reason: str) -> Dict[str, Any]:
    """
    Transfer manufacturer from source wallet to target wallet.
    
    This preserves the manufacturer's path allocations while moving
    them to a new cryptographic namespace.
    """
    # Get original manufacturer details
    original_manufacturer = get_manufacturer_in_wallet(source_wallet, manufacturer_name)
    if not original_manufacturer:
        raise ValueError(f"Manufacturer {manufacturer_name} not found in wallet v{source_wallet}")
    
    # Preserve manufacturer index for logical consistency
    new_manufacturer_index = original_manufacturer.manufacturer_index
    
    # Check if index is available in target wallet
    if is_manufacturer_index_taken(target_wallet, new_manufacturer_index):
        # Find next available index if original is taken
        new_manufacturer_index = get_next_available_manufacturer_index(target_wallet)
    
    # Create manufacturer in target wallet
    new_manufacturer_id = create_manufacturer_in_wallet(
        wallet_version=target_wallet,
        manufacturer_index=new_manufacturer_index,
        manufacturer_name=manufacturer_name,
        organization_id=original_manufacturer.organization_id,
        status="active",
        transferred_from_wallet=source_wallet,
        transfer_reason=transfer_reason
    )
    
    # Update manufacturer lineage tracking
    update_manufacturer_lineage(
        canonical_name=manufacturer_name,
        current_wallet_version=target_wallet,
        current_manufacturer_index=new_manufacturer_index,
        predecessor_wallet=source_wallet,
        predecessor_index=original_manufacturer.manufacturer_index,
        assignment_reason=transfer_reason
    )
    
    logger.info(f"✅ Transferred {manufacturer_name} from wallet v{source_wallet} to v{target_wallet}")
    
    return {
        "manufacturer_name": manufacturer_name,
        "source_wallet": source_wallet,
        "target_wallet": target_wallet,
        "new_manufacturer_index": new_manufacturer_index,
        "transfer_reason": transfer_reason,
        "status": "transfer_complete"
    }

Documentation Status: Core architecture complete
Next Phase: Implementation of key compromise response protocols
Review Required: Security team review of HSM integration design