KeyStorage

The KeyStorage class provides secure key management and storage capabilities for Radix Agent Kit. It handles encryption, decryption, and secure storage of sensitive cryptographic material.

Constructor

constructor(config: KeyStorageConfig)

Creates a new KeyStorage instance with specified security configuration.

KeyStorageConfig

interface KeyStorageConfig {
  storageType: 'file' | 'memory' | 'vault';
  encryptionKey?: string;
  storagePath?: string;
  compressionLevel?: number;
  backupEnabled?: boolean;
}

Example:

import { KeyStorage } from "radix-agent-kit";

const keyStorage = new KeyStorage({
  storageType: 'file',
  encryptionKey: process.env.ENCRYPTION_KEY,
  storagePath: './secure-keys',
  compressionLevel: 9,
  backupEnabled: true
});

Core Storage Operations

store(keyId: string, keyData: KeyData): Promise<void>

Store encrypted key data securely.

interface KeyData {
  privateKey: string;
  publicKey: string;
  address: string;
  metadata?: Record<string, any>;
  createdAt: Date;
  lastUsed?: Date;
}

await keyStorage.store('main-wallet', {
  privateKey: privateKeyHex,
  publicKey: publicKeyHex,
  address: accountAddress,
  metadata: {
    name: 'Main Wallet',
    purpose: 'Primary trading account'
  },
  createdAt: new Date()
});

console.log("✅ Key stored securely");

retrieve(keyId: string): Promise<KeyData>

Retrieve and decrypt stored key data.

const keyData = await keyStorage.retrieve('main-wallet');

console.log("Address:", keyData.address);
console.log("Created:", keyData.createdAt);
console.log("Metadata:", keyData.metadata);
// Private key is decrypted automatically

exists(keyId: string): Promise<boolean>

Check if a key exists in storage.

const hasKey = await keyStorage.exists('main-wallet');
if (hasKey) {
  console.log("Key found in storage");
} else {
  console.log("Key not found");
}

delete(keyId: string): Promise<void>

Securely delete a stored key.

await keyStorage.delete('old-wallet');
console.log("✅ Key securely deleted");

Key Management

listKeys(): Promise<KeyInfo[]>

List all stored keys (without sensitive data).

interface KeyInfo {
  keyId: string;
  address: string;
  createdAt: Date;
  lastUsed?: Date;
  metadata?: Record<string, any>;
}

const keys = await keyStorage.listKeys();

keys.forEach(key => {
  console.log(`${key.keyId}: ${key.address}`);
  console.log(`Created: ${key.createdAt}`);
  console.log(`Last used: ${key.lastUsed || 'Never'}`);
});

updateMetadata(keyId: string, metadata: Record<string, any>): Promise<void>

Update key metadata without affecting the key itself.

await keyStorage.updateMetadata('main-wallet', {
  name: 'Updated Main Wallet',
  purpose: 'Primary trading and staking',
  lastBackup: new Date()
});

updateLastUsed(keyId: string): Promise<void>

Update the last used timestamp for a key.

await keyStorage.updateLastUsed('main-wallet');

Security Features

changeEncryptionKey(oldKey: string, newKey: string): Promise<void>

Change the encryption key for all stored keys.

await keyStorage.changeEncryptionKey(
  process.env.OLD_ENCRYPTION_KEY!,
  process.env.NEW_ENCRYPTION_KEY!
);

console.log("✅ Encryption key updated for all stored keys");

backup(backupPath: string): Promise<void>

Create an encrypted backup of all keys.

await keyStorage.backup('./backups/keys-backup-2024.enc');
console.log("✅ Backup created successfully");

restore(backupPath: string, encryptionKey: string): Promise<void>

Restore keys from an encrypted backup.

await keyStorage.restore('./backups/keys-backup-2024.enc', backupEncryptionKey);
console.log("✅ Keys restored from backup");

verify(): Promise<VerificationResult>

Verify the integrity of stored keys.

interface VerificationResult {
  totalKeys: number;
  validKeys: number;
  corruptedKeys: string[];
  missingKeys: string[];
}

const result = await keyStorage.verify();

console.log(`Verified ${result.validKeys}/${result.totalKeys} keys`);
if (result.corruptedKeys.length > 0) {
  console.warn("Corrupted keys:", result.corruptedKeys);
}

Advanced Operations

export(keyId: string, format: ‘json’ | ‘pem’ | ‘hex’): Promise<string>

Export a key in specified format.

// Export as JSON
const jsonExport = await keyStorage.export('main-wallet', 'json');

// Export as hex
const hexExport = await keyStorage.export('main-wallet', 'hex');

console.log("Key exported successfully");

import(keyData: string, format: ‘json’ | ‘pem’ | ‘hex’, keyId: string): Promise<void>

Import a key from external format.

await keyStorage.import(externalKeyData, 'json', 'imported-wallet');
console.log("✅ Key imported successfully");

generateKey(keyId: string, options?: GenerateKeyOptions): Promise<KeyData>

Generate and store a new key.

interface GenerateKeyOptions {
  keyType: 'Ed25519' | 'Secp256k1';
  networkId: number;
  metadata?: Record<string, any>;
}

const newKey = await keyStorage.generateKey('new-wallet', {
  keyType: 'Ed25519',
  networkId: 2, // Stokenet
  metadata: {
    name: 'Generated Wallet',
    purpose: 'Testing'
  }
});

console.log("New wallet address:", newKey.address);

Storage Types

File Storage

Secure file-based storage with encryption.

const fileStorage = new KeyStorage({
  storageType: 'file',
  encryptionKey: process.env.ENCRYPTION_KEY,
  storagePath: './secure-keys',
  backupEnabled: true
});

Features:

  • AES-256 encryption
  • Automatic file permissions
  • Backup support
  • Cross-platform compatibility

Memory Storage

In-memory storage for temporary use.

const memoryStorage = new KeyStorage({
  storageType: 'memory',
  encryptionKey: process.env.ENCRYPTION_KEY
});

Features:

  • No disk persistence
  • Fast access
  • Automatic cleanup on exit
  • Suitable for testing

Vault Storage

Hardware security module integration.

const vaultStorage = new KeyStorage({
  storageType: 'vault',
  encryptionKey: process.env.VAULT_KEY,
  storagePath: '/secure/vault/path'
});

Features:

  • Hardware security module support
  • Maximum security
  • Audit logging
  • Enterprise-grade protection

Usage Examples

Basic Key Management

import { KeyStorage } from "radix-agent-kit";

// Initialize secure storage
const storage = new KeyStorage({
  storageType: 'file',
  encryptionKey: process.env.ENCRYPTION_KEY,
  storagePath: './wallet-keys'
});

// Store a new wallet
await storage.store('trading-wallet', {
  privateKey: privateKeyHex,
  publicKey: publicKeyHex,
  address: accountAddress,
  metadata: {
    name: 'Trading Wallet',
    purpose: 'DeFi operations',
    riskLevel: 'medium'
  },
  createdAt: new Date()
});

// Retrieve when needed
const keyData = await storage.retrieve('trading-wallet');
console.log("Wallet address:", keyData.address);

Multi-Wallet Management

async function manageMultipleWallets() {
  const storage = new KeyStorage({
    storageType: 'file',
    encryptionKey: process.env.ENCRYPTION_KEY,
    storagePath: './wallets'
  });
  
  // Generate multiple wallets
  const walletTypes = ['trading', 'staking', 'treasury', 'development'];
  
  for (const type of walletTypes) {
    const keyData = await storage.generateKey(`${type}-wallet`, {
      keyType: 'Ed25519',
      networkId: 2,
      metadata: {
        name: `${type.charAt(0).toUpperCase() + type.slice(1)} Wallet`,
        purpose: `${type} operations`,
        createdBy: 'automated-setup'
      }
    });
    
    console.log(`${type} wallet: ${keyData.address}`);
  }
  
  // List all wallets
  const allKeys = await storage.listKeys();
  console.log(`Total wallets: ${allKeys.length}`);
}

await manageMultipleWallets();

Backup and Recovery

async function backupAndRestore() {
  const storage = new KeyStorage({
    storageType: 'file',
    encryptionKey: process.env.ENCRYPTION_KEY,
    storagePath: './production-keys',
    backupEnabled: true
  });
  
  // Create backup
  const backupPath = `./backups/keys-${Date.now()}.enc`;
  await storage.backup(backupPath);
  console.log("✅ Backup created:", backupPath);
  
  // Verify backup integrity
  const verification = await storage.verify();
  console.log("Verification result:", verification);
  
  // In case of disaster recovery
  if (verification.corruptedKeys.length > 0) {
    console.log("🔄 Restoring from backup...");
    await storage.restore(backupPath, process.env.ENCRYPTION_KEY!);
    console.log("✅ Recovery completed");
  }
}

Security Rotation

async function rotateSecurityKeys() {
  const storage = new KeyStorage({
    storageType: 'file',
    encryptionKey: process.env.CURRENT_ENCRYPTION_KEY,
    storagePath: './secure-keys'
  });
  
  // Create backup before rotation
  await storage.backup('./backups/pre-rotation-backup.enc');
  
  // Rotate encryption key
  await storage.changeEncryptionKey(
    process.env.CURRENT_ENCRYPTION_KEY!,
    process.env.NEW_ENCRYPTION_KEY!
  );
  
  // Verify all keys after rotation
  const verification = await storage.verify();
  
  if (verification.validKeys === verification.totalKeys) {
    console.log("✅ Security rotation completed successfully");
  } else {
    console.error("❌ Security rotation failed - restore from backup");
  }
}

Integration with Wallets

import { RadixMnemonicWallet } from "radix-agent-kit";

async function integrateWithWallet() {
  const storage = new KeyStorage({
    storageType: 'file',
    encryptionKey: process.env.ENCRYPTION_KEY,
    storagePath: './wallet-storage'
  });
  
  // Create wallet and store securely
  const wallet = RadixMnemonicWallet.generateRandom({ networkId: 2 });
  
  await storage.store('main-wallet', {
    privateKey: wallet.getPrivateKeyHex(),
    publicKey: wallet.getPublicKey(),
    address: wallet.getAddress(),
    metadata: {
      mnemonic: wallet.getMnemonic(), // Store mnemonic securely
      derivationPath: "m/44'/1022'/0'/0/0",
      networkId: 2
    },
    createdAt: new Date()
  });
  
  // Later, recreate wallet from storage
  const storedKey = await storage.retrieve('main-wallet');
  const restoredWallet = RadixMnemonicWallet.fromMnemonic(
    storedKey.metadata!.mnemonic,
    { networkId: 2 }
  );
  
  console.log("Original address:", wallet.getAddress());
  console.log("Restored address:", restoredWallet.getAddress());
  console.log("Addresses match:", wallet.getAddress() === restoredWallet.getAddress());
}

Error Handling

try {
  const keyData = await keyStorage.retrieve('non-existent-key');
} catch (error) {
  if (error.message.includes('Key not found')) {
    console.error("Key does not exist in storage");
  } else if (error.message.includes('Decryption failed')) {
    console.error("Invalid encryption key or corrupted data");
  } else if (error.message.includes('Permission denied')) {
    console.error("Insufficient file system permissions");
  } else if (error.message.includes('Storage unavailable')) {
    console.error("Storage backend is not accessible");
  } else {
    console.error("Key storage operation failed:", error.message);
  }
}

Security Best Practices

  1. Strong Encryption: Use cryptographically secure encryption keys (32+ bytes)
  2. Key Rotation: Regularly rotate encryption keys
  3. Backup Strategy: Maintain secure, encrypted backups
  4. Access Control: Implement proper file system permissions
  5. Audit Logging: Log all key access operations
  6. Verification: Regularly verify key integrity
  7. Secure Deletion: Use secure deletion methods for sensitive data

Performance Considerations

  • Caching: KeyStorage implements intelligent caching for frequently accessed keys
  • Compression: Optional compression reduces storage size
  • Batch Operations: Use batch operations for multiple keys
  • Memory Management: Automatic cleanup of decrypted data

Integration Notes

  • RadixAgent: Automatically uses KeyStorage for wallet management
  • RadixMnemonicWallet: Can be integrated with KeyStorage for persistence
  • VaultWallet: Uses KeyStorage internally for secure key management
  • Cross-Platform: Works on Windows, macOS, and Linux

Security: KeyStorage handles sensitive cryptographic material. Always use strong encryption keys and secure storage locations in production.

Backup: Regular backups are essential for key recovery. Store backups in secure, separate locations from primary storage.