Apply Composer changes: comprehensive API updates, migrations, middleware, and infrastructure improvements
- Add comprehensive database migrations (001-024) for schema evolution - Enhance API schema with expanded type definitions and resolvers - Add new middleware: audit logging, rate limiting, MFA enforcement, security, tenant auth - Implement new services: AI optimization, billing, blockchain, compliance, marketplace - Add adapter layer for cloud integrations (Cloudflare, Kubernetes, Proxmox, storage) - Update Crossplane provider with enhanced VM management capabilities - Add comprehensive test suite for API endpoints and services - Update frontend components with improved GraphQL subscriptions and real-time updates - Enhance security configurations and headers (CSP, CORS, etc.) - Update documentation and configuration files - Add new CI/CD workflows and validation scripts - Implement design system improvements and UI enhancements
This commit is contained in:
281
api/src/services/blockchain.ts
Normal file
281
api/src/services/blockchain.ts
Normal file
@@ -0,0 +1,281 @@
|
||||
/**
|
||||
* Blockchain Service
|
||||
* Enterprise Ethereum Alliance (EEA) blockchain integration
|
||||
* For identity verification, resource tracking, and compliance
|
||||
*/
|
||||
|
||||
import { logger } from '../lib/logger.js'
|
||||
import { ethers } from 'ethers'
|
||||
|
||||
export interface BlockchainConfig {
|
||||
rpcUrl?: string
|
||||
networkId?: string
|
||||
contractAddress?: string
|
||||
privateKey?: string
|
||||
enabled: boolean
|
||||
}
|
||||
|
||||
export interface IdentityVerificationResult {
|
||||
verified: boolean
|
||||
address?: string
|
||||
timestamp?: Date
|
||||
error?: string
|
||||
}
|
||||
|
||||
class BlockchainService {
|
||||
private config: BlockchainConfig
|
||||
private initialized: boolean = false
|
||||
private provider: ethers.JsonRpcProvider | null = null
|
||||
private wallet: ethers.Wallet | null = null
|
||||
private identityContract: ethers.Contract | null = null
|
||||
|
||||
constructor() {
|
||||
this.config = {
|
||||
enabled: process.env.BLOCKCHAIN_ENABLED === 'true',
|
||||
rpcUrl: process.env.BLOCKCHAIN_RPC_URL,
|
||||
networkId: process.env.BLOCKCHAIN_NETWORK_ID,
|
||||
contractAddress: process.env.BLOCKCHAIN_IDENTITY_CONTRACT_ADDRESS,
|
||||
privateKey: process.env.BLOCKCHAIN_PRIVATE_KEY,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize blockchain service
|
||||
*/
|
||||
async initialize(): Promise<void> {
|
||||
if (!this.config.enabled) {
|
||||
logger.info('Blockchain service is disabled')
|
||||
this.initialized = true
|
||||
return
|
||||
}
|
||||
|
||||
if (!this.config.rpcUrl) {
|
||||
logger.warn('Blockchain RPC URL not configured, service will operate in mock mode')
|
||||
this.initialized = true
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
if (!this.config.rpcUrl) {
|
||||
throw new Error('Blockchain RPC URL is required when blockchain is enabled')
|
||||
}
|
||||
|
||||
// Initialize Ethers.js provider
|
||||
this.provider = new ethers.JsonRpcProvider(this.config.rpcUrl)
|
||||
|
||||
// Initialize wallet if private key is provided
|
||||
if (this.config.privateKey) {
|
||||
this.wallet = new ethers.Wallet(this.config.privateKey, this.provider)
|
||||
logger.info('Blockchain wallet initialized', {
|
||||
address: this.wallet.address,
|
||||
})
|
||||
}
|
||||
|
||||
// Load identity contract if address is provided
|
||||
if (this.config.contractAddress) {
|
||||
// Basic ABI for identity verification contract
|
||||
// In production, this would be loaded from contract artifacts
|
||||
const identityABI = [
|
||||
'function isVerified(address user) external view returns (bool)',
|
||||
'function registerIdentity(address user, bytes32 userIdHash) external returns (bool)',
|
||||
'function revokeIdentity(address user) external returns (bool)',
|
||||
]
|
||||
|
||||
const contractAddress = this.config.contractAddress
|
||||
const signer = this.wallet || this.provider
|
||||
|
||||
this.identityContract = new ethers.Contract(
|
||||
contractAddress,
|
||||
identityABI,
|
||||
signer
|
||||
)
|
||||
|
||||
// Verify contract is deployed
|
||||
const code = await this.provider.getCode(contractAddress)
|
||||
if (code === '0x') {
|
||||
throw new Error(`Contract not deployed at address ${contractAddress}`)
|
||||
}
|
||||
|
||||
logger.info('Identity contract loaded', { contractAddress })
|
||||
}
|
||||
|
||||
logger.info('Blockchain service initialized', {
|
||||
networkId: this.config.networkId,
|
||||
contractAddress: this.config.contractAddress,
|
||||
providerUrl: this.config.rpcUrl,
|
||||
})
|
||||
|
||||
this.initialized = true
|
||||
} catch (error) {
|
||||
logger.error('Failed to initialize blockchain service', { error })
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify blockchain identity
|
||||
* Checks if a user's blockchain address is registered and verified
|
||||
*/
|
||||
async verifyIdentity(
|
||||
userId: string,
|
||||
blockchainAddress: string
|
||||
): Promise<IdentityVerificationResult> {
|
||||
if (!this.initialized) {
|
||||
await this.initialize()
|
||||
}
|
||||
|
||||
if (!this.config.enabled) {
|
||||
logger.info('Blockchain verification skipped (disabled)', { userId, blockchainAddress })
|
||||
return {
|
||||
verified: true, // Allow when blockchain is disabled
|
||||
address: blockchainAddress,
|
||||
timestamp: new Date(),
|
||||
}
|
||||
}
|
||||
|
||||
if (!blockchainAddress || !blockchainAddress.match(/^0x[a-fA-F0-9]{40}$/)) {
|
||||
logger.warn('Invalid blockchain address format', { userId, blockchainAddress })
|
||||
return {
|
||||
verified: false,
|
||||
address: blockchainAddress,
|
||||
error: 'Invalid blockchain address format',
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
if (!this.provider) {
|
||||
throw new Error('Blockchain provider not initialized')
|
||||
}
|
||||
|
||||
if (!this.identityContract) {
|
||||
// If contract is not configured, verify address format only
|
||||
logger.info('Blockchain identity verification (no contract)', {
|
||||
userId,
|
||||
blockchainAddress,
|
||||
})
|
||||
return {
|
||||
verified: true,
|
||||
address: blockchainAddress,
|
||||
timestamp: new Date(),
|
||||
}
|
||||
}
|
||||
|
||||
// Query identity contract for verification status
|
||||
const isVerified = await this.identityContract.isVerified(blockchainAddress) as boolean
|
||||
|
||||
logger.info('Blockchain identity verification', {
|
||||
userId,
|
||||
blockchainAddress,
|
||||
verified: isVerified,
|
||||
networkId: this.config.networkId,
|
||||
})
|
||||
|
||||
return {
|
||||
verified: isVerified,
|
||||
address: blockchainAddress,
|
||||
timestamp: new Date(),
|
||||
...(isVerified ? {} : { error: 'Address not verified on blockchain' }),
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error('Blockchain verification failed', { userId, blockchainAddress, error })
|
||||
return {
|
||||
verified: false,
|
||||
address: blockchainAddress,
|
||||
error: error instanceof Error ? error.message : 'Unknown error',
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register identity on blockchain
|
||||
* Registers a user's blockchain address in the identity contract
|
||||
*/
|
||||
async registerIdentity(
|
||||
userId: string,
|
||||
blockchainAddress: string,
|
||||
metadata?: Record<string, unknown>
|
||||
): Promise<{ success: boolean; transactionHash?: string; error?: string }> {
|
||||
if (!this.initialized) {
|
||||
await this.initialize()
|
||||
}
|
||||
|
||||
if (!this.config.enabled) {
|
||||
logger.info('Blockchain registration skipped (disabled)', { userId, blockchainAddress })
|
||||
return { success: true }
|
||||
}
|
||||
|
||||
try {
|
||||
if (!this.provider) {
|
||||
throw new Error('Blockchain provider not initialized')
|
||||
}
|
||||
|
||||
if (!this.identityContract) {
|
||||
throw new Error('Identity contract not configured')
|
||||
}
|
||||
|
||||
if (!this.wallet) {
|
||||
throw new Error('Blockchain wallet not configured (private key required for registration)')
|
||||
}
|
||||
|
||||
// Create hash of userId for on-chain storage
|
||||
const userIdHash = ethers.id(userId)
|
||||
|
||||
// Prepare and send transaction
|
||||
logger.info('Registering identity on blockchain', {
|
||||
userId,
|
||||
blockchainAddress,
|
||||
userIdHash,
|
||||
})
|
||||
|
||||
const tx = await this.identityContract.registerIdentity(blockchainAddress, userIdHash)
|
||||
|
||||
logger.info('Blockchain registration transaction sent', {
|
||||
transactionHash: tx.hash,
|
||||
userId,
|
||||
blockchainAddress,
|
||||
})
|
||||
|
||||
// Wait for transaction confirmation
|
||||
const receipt = await tx.wait()
|
||||
|
||||
if (!receipt) {
|
||||
throw new Error('Transaction receipt not received')
|
||||
}
|
||||
|
||||
logger.info('Blockchain identity registered', {
|
||||
transactionHash: receipt.hash,
|
||||
blockNumber: receipt.blockNumber,
|
||||
userId,
|
||||
blockchainAddress,
|
||||
})
|
||||
|
||||
return {
|
||||
success: true,
|
||||
transactionHash: receipt.hash,
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error('Blockchain registration failed', { userId, blockchainAddress, error })
|
||||
return {
|
||||
success: false,
|
||||
error: error instanceof Error ? error.message : 'Unknown error',
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if blockchain service is enabled
|
||||
*/
|
||||
isEnabled(): boolean {
|
||||
return this.config.enabled
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if blockchain service is initialized
|
||||
*/
|
||||
isInitialized(): boolean {
|
||||
return this.initialized
|
||||
}
|
||||
}
|
||||
|
||||
// Singleton instance
|
||||
export const blockchainService = new BlockchainService()
|
||||
Reference in New Issue
Block a user