bigbasealpha
Version:
Enterprise-Grade NoSQL Database System with Modular Logger & Offline HSM Security - Complete database platform with professional text-based logging, encryption, caching, indexing, JWT authentication, auto-generated REST API, real-time dashboard, and maste
1,058 lines (883 loc) • 30.5 kB
JavaScript
/**
* BigBaseAlpha - Blockchain Integration Engine
* Enterprise-grade blockchain integration with distributed ledger technology
* Supports multiple blockchain networks and cryptocurrency transactions
* WITH OFFLINE HSM INTEGRATION FOR MAXIMUM SECURITY
*
* @copyright 2025 ByAlphas. All rights reserved.
*/
import { EventEmitter } from 'events';
import crypto from 'crypto';
import fs from 'fs/promises';
import path from 'path';
import { OfflineHSM } from '../security/hsm.js';
export class BlockchainEngine extends EventEmitter {
constructor(options = {}) {
super();
this.config = {
dataPath: options.dataPath || './bigbase_data/blockchain',
networks: options.networks || ['ethereum', 'bitcoin', 'polygon'],
consensusAlgorithm: options.consensusAlgorithm || 'proof-of-stake',
blockSize: options.blockSize || 1024 * 1024, // 1MB
difficulty: options.difficulty || 4,
miningReward: options.miningReward || 10,
transactionFee: options.transactionFee || 0.001,
validationNodes: options.validationNodes || 3,
enableSmartContracts: options.enableSmartContracts !== false,
enableNFT: options.enableNFT !== false,
enableDeFi: options.enableDeFi !== false
};
// Blockchain State
this.blockchain = [];
this.pendingTransactions = [];
this.wallets = new Map();
this.smartContracts = new Map();
this.nftCollection = new Map();
this.stakingPools = new Map();
// Mining and Validation
this.miners = new Map();
this.validators = new Map();
this.consensusNodes = new Set();
// Network State
this.peers = new Map();
this.networkState = {
isConnected: false,
peerCount: 0,
syncProgress: 0,
lastBlock: null
};
// Transaction Pool
this.mempool = new Map();
this.txQueue = [];
// HSM Integration for Maximum Security (100% Offline)
this.hsm = new OfflineHSM({
secureStorePath: path.join(this.config.dataPath, 'hsm'),
keySize: 256,
algorithm: 'aes-256-gcm',
tamperDetection: true,
autoBackup: true
});
// Statistics
this.stats = {
totalBlocks: 0,
totalTransactions: 0,
totalWallets: 0,
totalSmartContracts: 0,
totalNFTs: 0,
networkHashRate: 0,
averageBlockTime: 600000, // 10 minutes
totalValue: 0,
circulatingSupply: 0,
marketCap: 0,
gasPrice: 20,
uptime: Date.now(),
hsmStatus: 'initializing'
};
this.initialized = false;
this.isRunning = false;
}
/**
* Initialize Blockchain Engine with HSM Security
*/
async initialize() {
if (this.initialized) return;
try {
// Initialize HSM first for maximum security
console.log('🔐 Initializing BigBaseAlpha HSM (100% Offline)...');
await this.hsm._initializeSecureStorage();
this.stats.hsmStatus = 'active';
// Create directories
await this._ensureDirectories();
// Load existing blockchain
await this._loadBlockchain();
// Load wallets
await this._loadWallets();
// Load smart contracts
await this._loadSmartContracts();
// Initialize genesis block if needed
if (this.blockchain.length === 0) {
await this._createGenesisBlock();
}
// Start network services
this._startNetworkServices();
// Start mining if enabled
this._startMining();
this.initialized = true;
this.isRunning = true;
this.emit('initialized', {
blockCount: this.blockchain.length,
walletCount: this.wallets.size,
contractCount: this.smartContracts.size
});
console.log('✅ Blockchain Engine initialized successfully');
} catch (error) {
console.error('❌ Failed to initialize Blockchain Engine:', error);
throw error;
}
}
/**
* Create a new wallet with HSM-secured private key
*/
async createWallet(userId, initialBalance = 0) {
// Generate secure key pair using HSM
const keyId = `wallet_${crypto.randomUUID()}`;
await this.hsm.generateKey(keyId, 'asymmetric', 256);
// Generate traditional keys for compatibility
const privateKey = crypto.randomBytes(32).toString('hex');
const publicKey = crypto.createHash('sha256').update(privateKey).digest('hex');
const address = this._generateAddress(publicKey);
// Encrypt private key using HSM
const encryptedPrivateKey = await this.hsm.encrypt(privateKey, keyId);
const wallet = {
id: crypto.randomUUID(),
userId,
address,
publicKey,
privateKey: null, // Never store plaintext private key
encryptedPrivateKey, // HSM-encrypted private key
hsmKeyId: keyId, // Reference to HSM key
balance: initialBalance,
transactions: [],
createdAt: Date.now(),
isActive: true,
securityLevel: 'HSM-Protected'
};
this.wallets.set(address, wallet);
this.stats.totalWallets++;
// Add initial balance transaction if needed
if (initialBalance > 0) {
await this._addTransaction({
from: 'system',
to: address,
amount: initialBalance,
type: 'initial_balance',
timestamp: Date.now()
});
}
await this._persistWallet(wallet);
this.emit('walletCreated', { ...wallet, privateKey: '[HSM-PROTECTED]' });
return { ...wallet, privateKey: '[HSM-PROTECTED]' };
}
/**
* Send transaction
*/
async sendTransaction(fromAddress, toAddress, amount, data = {}) {
try {
// Validate transaction
await this._validateTransaction(fromAddress, toAddress, amount);
const transaction = {
id: crypto.randomUUID(),
from: fromAddress,
to: toAddress,
amount: amount,
fee: this.config.transactionFee,
data: data,
timestamp: Date.now(),
status: 'pending',
signature: null,
hash: null
};
// Sign transaction
transaction.signature = this._signTransaction(transaction, fromAddress);
transaction.hash = this._calculateTransactionHash(transaction);
// Add to mempool
this.mempool.set(transaction.id, transaction);
this.pendingTransactions.push(transaction);
this.emit('transactionCreated', transaction);
// Process transaction in next block
await this._processTransactionQueue();
return transaction;
} catch (error) {
this.emit('transactionFailed', { fromAddress, toAddress, amount, error: error.message });
throw error;
}
}
/**
* Deploy Smart Contract
*/
async deploySmartContract(ownerAddress, contractCode, constructorArgs = []) {
try {
const contractAddress = this._generateContractAddress(ownerAddress);
const contract = {
id: crypto.randomUUID(),
address: contractAddress,
owner: ownerAddress,
code: contractCode,
abi: this._parseContractABI(contractCode),
storage: new Map(),
balance: 0,
createdAt: Date.now(),
deployedBlock: this.blockchain.length,
isActive: true
};
// Execute constructor
if (constructorArgs.length > 0) {
await this._executeContractFunction(contract, 'constructor', constructorArgs);
}
this.smartContracts.set(contractAddress, contract);
this.stats.totalSmartContracts++;
// Create deployment transaction
await this._addTransaction({
from: ownerAddress,
to: contractAddress,
amount: 0,
type: 'contract_deployment',
data: { contractCode, constructorArgs },
timestamp: Date.now()
});
await this._persistSmartContract(contract);
this.emit('contractDeployed', contract);
return contract;
} catch (error) {
this.emit('contractDeploymentFailed', { ownerAddress, error: error.message });
throw error;
}
}
/**
* Call Smart Contract Function
*/
async callContractFunction(contractAddress, functionName, args = [], fromAddress = null) {
try {
const contract = this.smartContracts.get(contractAddress);
if (!contract) {
throw new Error('Contract not found');
}
const result = await this._executeContractFunction(contract, functionName, args, fromAddress);
// Create transaction if state-changing
if (result.stateChanged) {
await this._addTransaction({
from: fromAddress || 'system',
to: contractAddress,
amount: 0,
type: 'contract_call',
data: { function: functionName, args, result: result.returnValue },
timestamp: Date.now()
});
}
this.emit('contractFunctionCalled', {
contractAddress,
functionName,
args,
result: result.returnValue
});
return result.returnValue;
} catch (error) {
this.emit('contractCallFailed', { contractAddress, functionName, error: error.message });
throw error;
}
}
/**
* Mint NFT
*/
async mintNFT(toAddress, tokenData, royalties = 0) {
if (!this.config.enableNFT) {
throw new Error('NFT functionality is disabled');
}
try {
const tokenId = crypto.randomUUID();
const tokenHash = crypto.createHash('sha256').update(JSON.stringify(tokenData)).digest('hex');
const nft = {
tokenId,
owner: toAddress,
creator: toAddress,
tokenHash,
metadata: tokenData,
royalties,
createdAt: Date.now(),
transferHistory: [],
isActive: true
};
this.nftCollection.set(tokenId, nft);
this.stats.totalNFTs++;
// Create mint transaction
await this._addTransaction({
from: 'system',
to: toAddress,
amount: 0,
type: 'nft_mint',
data: { tokenId, tokenHash, metadata: tokenData },
timestamp: Date.now()
});
this.emit('nftMinted', nft);
return nft;
} catch (error) {
this.emit('nftMintFailed', { toAddress, error: error.message });
throw error;
}
}
/**
* Transfer NFT
*/
async transferNFT(tokenId, fromAddress, toAddress) {
try {
const nft = this.nftCollection.get(tokenId);
if (!nft) {
throw new Error('NFT not found');
}
if (nft.owner !== fromAddress) {
throw new Error('Not the owner of this NFT');
}
// Update ownership
nft.owner = toAddress;
nft.transferHistory.push({
from: fromAddress,
to: toAddress,
timestamp: Date.now(),
blockNumber: this.blockchain.length
});
// Create transfer transaction
await this._addTransaction({
from: fromAddress,
to: toAddress,
amount: 0,
type: 'nft_transfer',
data: { tokenId, transferType: 'ownership' },
timestamp: Date.now()
});
this.emit('nftTransferred', { tokenId, fromAddress, toAddress });
return nft;
} catch (error) {
this.emit('nftTransferFailed', { tokenId, fromAddress, toAddress, error: error.message });
throw error;
}
}
/**
* Create Staking Pool
*/
async createStakingPool(ownerAddress, reward, duration, minStake = 1) {
try {
const poolId = crypto.randomUUID();
const stakingPool = {
id: poolId,
owner: ownerAddress,
reward: reward, // Annual percentage
duration: duration, // In milliseconds
minStake,
totalStaked: 0,
participants: new Map(),
createdAt: Date.now(),
isActive: true
};
this.stakingPools.set(poolId, stakingPool);
await this._addTransaction({
from: ownerAddress,
to: 'staking_system',
amount: 0,
type: 'staking_pool_created',
data: { poolId, reward, duration, minStake },
timestamp: Date.now()
});
this.emit('stakingPoolCreated', stakingPool);
return stakingPool;
} catch (error) {
this.emit('stakingPoolCreationFailed', { ownerAddress, error: error.message });
throw error;
}
}
/**
* Stake tokens
*/
async stakeTokens(poolId, userAddress, amount) {
try {
const pool = this.stakingPools.get(poolId);
if (!pool) {
throw new Error('Staking pool not found');
}
if (amount < pool.minStake) {
throw new Error(`Minimum stake is ${pool.minStake}`);
}
const wallet = this.wallets.get(userAddress);
if (!wallet || wallet.balance < amount) {
throw new Error('Insufficient balance');
}
// Lock tokens
wallet.balance -= amount;
const stake = {
amount,
startTime: Date.now(),
endTime: Date.now() + pool.duration,
rewards: 0,
isActive: true
};
pool.participants.set(userAddress, stake);
pool.totalStaked += amount;
await this._addTransaction({
from: userAddress,
to: 'staking_system',
amount: amount,
type: 'stake_tokens',
data: { poolId, stakedAmount: amount },
timestamp: Date.now()
});
this.emit('tokensStaked', { poolId, userAddress, amount });
return stake;
} catch (error) {
this.emit('stakingFailed', { poolId, userAddress, amount, error: error.message });
throw error;
}
}
/**
* Mine new block
*/
async mineBlock() {
if (this.pendingTransactions.length === 0) {
return null;
}
try {
const block = await this._createBlock(this.pendingTransactions);
// Validate block
if (await this._validateBlock(block)) {
this.blockchain.push(block);
this.stats.totalBlocks++;
this.stats.totalTransactions += block.transactions.length;
// Clear pending transactions
this.pendingTransactions = [];
this.mempool.clear();
// Update wallet balances
await this._processBlockTransactions(block);
// Persist block
await this._persistBlock(block);
this.emit('blockMined', block);
console.log(`⛏️ Block #${block.index} mined with ${block.transactions.length} transactions`);
return block;
}
} catch (error) {
console.error('Mining failed:', error);
this.emit('miningFailed', { error: error.message });
return null;
}
}
/**
* Get blockchain statistics
*/
getBlockchainStats() {
const latestBlock = this.blockchain[this.blockchain.length - 1];
return {
...this.stats,
latestBlock: latestBlock ? {
index: latestBlock.index,
hash: latestBlock.hash,
timestamp: latestBlock.timestamp,
transactionCount: latestBlock.transactions.length
} : null,
networkState: this.networkState,
pendingTransactions: this.pendingTransactions.length,
mempoolSize: this.mempool.size,
blockchainSize: this._calculateBlockchainSize(),
averageTransactionFee: this._calculateAverageTransactionFee(),
networkDifficulty: this.config.difficulty
};
}
/**
* Get wallet balance
*/
getWalletBalance(address) {
const wallet = this.wallets.get(address);
return wallet ? wallet.balance : 0;
}
/**
* Get transaction history
*/
getTransactionHistory(address, limit = 50) {
const transactions = [];
for (const block of this.blockchain) {
for (const tx of block.transactions) {
if (tx.from === address || tx.to === address) {
transactions.push({
...tx,
blockIndex: block.index,
blockHash: block.hash,
confirmations: this.blockchain.length - block.index
});
}
}
}
return transactions
.sort((a, b) => b.timestamp - a.timestamp)
.slice(0, limit);
}
/**
* Private Methods
*/
async _ensureDirectories() {
const dirs = [
this.config.dataPath,
path.join(this.config.dataPath, 'blocks'),
path.join(this.config.dataPath, 'wallets'),
path.join(this.config.dataPath, 'contracts')
];
for (const dir of dirs) {
await fs.mkdir(dir, { recursive: true });
}
}
async _loadBlockchain() {
try {
const blocksDir = path.join(this.config.dataPath, 'blocks');
const files = await fs.readdir(blocksDir);
const blockFiles = files
.filter(f => f.endsWith('.block.json'))
.sort((a, b) => {
const aIndex = parseInt(a.split('.')[0]);
const bIndex = parseInt(b.split('.')[0]);
return aIndex - bIndex;
});
for (const file of blockFiles) {
const filePath = path.join(blocksDir, file);
const content = await fs.readFile(filePath, 'utf8');
const block = JSON.parse(content);
this.blockchain.push(block);
}
this.stats.totalBlocks = this.blockchain.length;
console.log(`📚 Loaded ${this.blockchain.length} blocks from storage`);
} catch (error) {
if (error.code !== 'ENOENT') {
throw error;
}
}
}
async _loadWallets() {
try {
const walletsDir = path.join(this.config.dataPath, 'wallets');
const files = await fs.readdir(walletsDir);
for (const file of files) {
if (file.endsWith('.wallet.json')) {
const filePath = path.join(walletsDir, file);
const content = await fs.readFile(filePath, 'utf8');
const wallet = JSON.parse(content);
this.wallets.set(wallet.address, wallet);
}
}
this.stats.totalWallets = this.wallets.size;
console.log(`👛 Loaded ${this.wallets.size} wallets from storage`);
} catch (error) {
if (error.code !== 'ENOENT') {
throw error;
}
}
}
async _loadSmartContracts() {
try {
const contractsDir = path.join(this.config.dataPath, 'contracts');
const files = await fs.readdir(contractsDir);
for (const file of files) {
if (file.endsWith('.contract.json')) {
const filePath = path.join(contractsDir, file);
const content = await fs.readFile(filePath, 'utf8');
const contract = JSON.parse(content);
contract.storage = new Map(contract.storage);
this.smartContracts.set(contract.address, contract);
}
}
this.stats.totalSmartContracts = this.smartContracts.size;
console.log(`📜 Loaded ${this.smartContracts.size} smart contracts from storage`);
} catch (error) {
if (error.code !== 'ENOENT') {
throw error;
}
}
}
async _createGenesisBlock() {
const genesisBlock = {
index: 0,
timestamp: Date.now(),
transactions: [],
previousHash: '0',
nonce: 0,
hash: '',
merkleRoot: '',
difficulty: this.config.difficulty,
miner: 'system'
};
genesisBlock.hash = await this._calculateBlockHash(genesisBlock);
this.blockchain.push(genesisBlock);
await this._persistBlock(genesisBlock);
console.log('🔗 Genesis block created with HSM security');
}
_generateAddress(publicKey) {
return '0x' + crypto.createHash('sha256').update(publicKey).digest('hex').slice(0, 40);
}
_generateContractAddress(ownerAddress) {
const nonce = Date.now().toString();
return '0x' + crypto.createHash('sha256').update(ownerAddress + nonce).digest('hex').slice(0, 40);
}
_signTransaction(transaction, fromAddress) {
const wallet = this.wallets.get(fromAddress);
if (!wallet) {
throw new Error('Wallet not found');
}
const dataToSign = JSON.stringify({
from: transaction.from,
to: transaction.to,
amount: transaction.amount,
timestamp: transaction.timestamp
});
return crypto.createHmac('sha256', wallet.privateKey).update(dataToSign).digest('hex');
}
_calculateTransactionHash(transaction) {
const data = JSON.stringify({
from: transaction.from,
to: transaction.to,
amount: transaction.amount,
timestamp: transaction.timestamp,
signature: transaction.signature
});
return crypto.createHash('sha256').update(data).digest('hex');
}
/**
* Calculate block hash using HSM for maximum security
*/
async _calculateBlockHash(block) {
const data = JSON.stringify({
index: block.index,
timestamp: block.timestamp,
transactions: block.transactions,
previousHash: block.previousHash,
nonce: block.nonce
});
// Use HSM for secure hash generation with salt
try {
const hsmResult = await this.hsm.hash(data, 'sha256');
return hsmResult.hash;
} catch (error) {
// Fallback to traditional hashing if HSM fails
console.warn('HSM hash failed, using fallback:', error.message);
return crypto.createHash('sha256').update(data).digest('hex');
}
}
async _validateTransaction(fromAddress, toAddress, amount) {
if (fromAddress === 'system') return true;
const wallet = this.wallets.get(fromAddress);
if (!wallet) {
throw new Error('Sender wallet not found');
}
if (wallet.balance < amount + this.config.transactionFee) {
throw new Error('Insufficient balance');
}
if (amount <= 0) {
throw new Error('Amount must be positive');
}
return true;
}
async _addTransaction(txData) {
const transaction = {
id: crypto.randomUUID(),
...txData,
hash: this._calculateTransactionHash({ ...txData, signature: 'system' })
};
this.pendingTransactions.push(transaction);
return transaction;
}
async _createBlock(transactions) {
const previousBlock = this.blockchain[this.blockchain.length - 1];
const block = {
index: this.blockchain.length,
timestamp: Date.now(),
transactions: [...transactions],
previousHash: previousBlock ? previousBlock.hash : '0',
nonce: 0,
hash: '',
merkleRoot: this._calculateMerkleRoot(transactions),
difficulty: this.config.difficulty,
miner: 'system',
hsmSecured: true
};
// Proof of work with HSM-secured hashing
while (true) {
block.hash = await this._calculateBlockHash(block);
if (block.hash.startsWith('0'.repeat(this.config.difficulty))) {
break;
}
block.nonce++;
}
return block;
}
_calculateMerkleRoot(transactions) {
if (transactions.length === 0) return '0';
const hashes = transactions.map(tx => tx.hash || this._calculateTransactionHash(tx));
while (hashes.length > 1) {
const newLevel = [];
for (let i = 0; i < hashes.length; i += 2) {
const left = hashes[i];
const right = hashes[i + 1] || left;
newLevel.push(crypto.createHash('sha256').update(left + right).digest('hex'));
}
hashes.splice(0, hashes.length, ...newLevel);
}
return hashes[0];
}
async _validateBlock(block) {
// Validate hash using HSM
const calculatedHash = await this._calculateBlockHash(block);
if (calculatedHash !== block.hash) {
return false;
}
// Validate proof of work
if (!block.hash.startsWith('0'.repeat(this.config.difficulty))) {
return false;
}
// Validate previous hash
const previousBlock = this.blockchain[this.blockchain.length - 1];
if (previousBlock && block.previousHash !== previousBlock.hash) {
return false;
}
// Validate merkle root
const calculatedMerkleRoot = this._calculateMerkleRoot(block.transactions);
if (calculatedMerkleRoot !== block.merkleRoot) {
return false;
}
return true;
}
async _processBlockTransactions(block) {
for (const tx of block.transactions) {
if (tx.from !== 'system') {
const fromWallet = this.wallets.get(tx.from);
if (fromWallet) {
fromWallet.balance -= (tx.amount + tx.fee);
}
}
if (tx.to !== 'system') {
const toWallet = this.wallets.get(tx.to);
if (toWallet) {
toWallet.balance += tx.amount;
}
}
}
}
async _processTransactionQueue() {
if (this.pendingTransactions.length >= 10) {
await this.mineBlock();
}
}
_parseContractABI(contractCode) {
// Simplified ABI parsing
return {
functions: ['constructor', 'getValue', 'setValue'],
events: ['ValueChanged']
};
}
async _executeContractFunction(contract, functionName, args, fromAddress = null) {
// Simplified smart contract execution
let stateChanged = false;
let returnValue = null;
switch (functionName) {
case 'constructor':
contract.storage.set('initialized', true);
stateChanged = true;
break;
case 'getValue':
returnValue = contract.storage.get('value') || 0;
break;
case 'setValue':
contract.storage.set('value', args[0]);
stateChanged = true;
returnValue = true;
break;
default:
throw new Error(`Function ${functionName} not found`);
}
return { returnValue, stateChanged };
}
_calculateBlockchainSize() {
return this.blockchain.reduce((size, block) => {
return size + JSON.stringify(block).length;
}, 0);
}
_calculateAverageTransactionFee() {
if (this.stats.totalTransactions === 0) return 0;
let totalFees = 0;
let txCount = 0;
for (const block of this.blockchain) {
for (const tx of block.transactions) {
if (tx.fee) {
totalFees += tx.fee;
txCount++;
}
}
}
return txCount > 0 ? totalFees / txCount : 0;
}
async _persistBlock(block) {
const filePath = path.join(this.config.dataPath, 'blocks', `${block.index.toString().padStart(8, '0')}.block.json`);
await fs.writeFile(filePath, JSON.stringify(block, null, 2));
}
async _persistWallet(wallet) {
const filePath = path.join(this.config.dataPath, 'wallets', `${wallet.address}.wallet.json`);
await fs.writeFile(filePath, JSON.stringify(wallet, null, 2));
}
async _persistSmartContract(contract) {
const contractToSave = {
...contract,
storage: Array.from(contract.storage.entries())
};
const filePath = path.join(this.config.dataPath, 'contracts', `${contract.address}.contract.json`);
await fs.writeFile(filePath, JSON.stringify(contractToSave, null, 2));
}
_startNetworkServices() {
// Simulate network connectivity
this.networkState.isConnected = true;
this.networkState.peerCount = Math.floor(Math.random() * 20) + 5;
// Update network stats periodically
setInterval(() => {
this.stats.networkHashRate = Math.floor(Math.random() * 1000) + 500;
this.networkState.peerCount = Math.floor(Math.random() * 20) + 5;
this.emit('networkStatsUpdated', this.networkState);
}, 10000);
}
_startMining() {
// Auto-mine blocks when transactions are pending
setInterval(async () => {
if (this.pendingTransactions.length > 0) {
await this.mineBlock();
}
}, 30000); // Mine every 30 seconds if transactions pending
}
/**
* Get HSM health status and blockchain security info
*/
async getSecurityStatus() {
const hsmHealth = await this.hsm.healthCheck();
return {
hsm: hsmHealth,
blockchain: {
totalBlocks: this.blockchain.length,
securedWallets: Array.from(this.wallets.values())
.filter(w => w.hsmKeyId).length,
difficulty: this.config.difficulty,
lastBlockSecured: this.blockchain.length > 0 ?
this.blockchain[this.blockchain.length - 1].hsmSecured : false
},
security: {
offlineMode: true,
tamperDetection: this.hsm.config.tamperDetection,
encryptionAlgorithm: this.hsm.config.algorithm,
keySize: this.hsm.config.keySize,
autoBackup: this.hsm.config.autoBackup
}
};
}
/**
* Shutdown gracefully with HSM cleanup
*/
async shutdown() {
this.isRunning = false;
// Persist all data
for (const wallet of this.wallets.values()) {
await this._persistWallet(wallet);
}
for (const contract of this.smartContracts.values()) {
await this._persistSmartContract(contract);
}
// Shutdown HSM securely
await this.hsm.shutdown();
console.log('🛑 Blockchain Engine with HSM shutdown complete');
this.emit('shutdown');
}
/**
* Set database reference for blockchain integration
*/
setDatabase(database) {
this.database = database;
console.log('🔗 Blockchain Engine linked to database');
}
}
export default BlockchainEngine;