Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Refactor: Centralize Key and Blockchain Management in OceanNode
Summary
This PR refactors the OceanNode singleton to centralize key management and blockchain connection management. The refactoring introduces a new
KeyManagercomponent with a pluggable key provider architecture, and aBlockchainRegistryto manage blockchain instances per chain ID. This improves modularity, testability, and sets the foundation for future key management solutions (e.g., GCP KMS).Architecture Changes
Before
config.keysBlockchaininstances were created ad-hoc in 22+ locationsAfter
Key Components
1. KeyManager (
src/components/KeyManager/index.ts)Centralizes all key management for OceanNode:
peerId, libp2p keys, EVM address, and EVM signersIKeyProviderinterface to support multiple key sourcesRawPrivateKeyProviderfor raw private keysGcpKmsProvideror other key providersKey Methods:
getPeerId(): Returns libp2p PeerIdgetLibp2pPrivateKey(): Returns libp2p private keygetEthAddress(): Returns Ethereum addressgetEvmSigner(provider): Returns cached EVM signer for a providerencrypt(data, algorithm): Encrypts data using node keysdecrypt(data, algorithm): Decrypts data using node keysencryptStream(stream, algorithm): Encrypts streams (AES/ECIES)decryptStream(stream, algorithm): Decrypts streams (AES/ECIES)2. IKeyProvider Interface (
src/@types/KeyManager.ts)Defines the contract for all key provider implementations:
getType(): Returns provider type ('raw' | 'gcp-kms')getPeerId(),getLibp2pPrivateKey(),getPublicKey()getEthAddress(),getEthWallet()getRawPrivateKeyBytes(): For EVM signer creationencrypt(),decrypt(): Data encryption/decryptionencryptStream(),decryptStream(): Stream encryption/decryptioncleanup?(): Optional cleanup method3. RawPrivateKeyProvider (
src/components/KeyManager/providers/RawPrivateKeyProvider.ts)Implements
IKeyProviderfor raw private keys:initialize()needed)peerId, libp2p keys, and Ethereum address from raw private keyTransformstreams for efficient processing4. BlockchainRegistry (
src/components/BlockchainRegistry/index.ts)Manages
Blockchaininstances per chain ID:Blockchaininstances on-demandBlockchaininstances for the same chain IDgetBlockchain(chainId)method that returnsBlockchain | null5. Refactored Blockchain Class (
src/utils/blockchain.ts)Updated to work with the new architecture:
KeyManagerand uses it to get signersOceanNodeConfigfor signer creationKeyManager.getEvmSigner(provider)6. Updated OceanNode (
src/OceanNode.ts)Enhanced singleton with new components:
KeyManagerandBlockchainRegistryas parameters (dependency injection)getInstance()method updated to require these componentsgetKeyManager(): Returns KeyManager instancegetBlockchainRegistry(): Returns BlockchainRegistry instancegetBlockchain(chainId): Convenience method delegating to BlockchainRegistryMigration Changes
Handlers Updated
All handlers now use
OceanNode.getBlockchain()instead of creating newBlockchaininstances:ddoHandler.ts: UsesoceanNode.getBlockchain(chainId)for blockchain accessdownloadHandler.ts: Migrated to use centralized blockchain accessstartCompute.ts: Updated multiple locations to useoceanNode.getBlockchain(chainId)initialize.ts: Updated compute initialization to use centralized blockchaincollectFeesHandler.ts: Admin handler now usesoceanNode.getBlockchain(chainId)Escrow Refactoring (
src/components/core/utils/escrow.ts)BlockchainRegistryas a parametergetBlockchain(chainId)helper methodgetPaymentAmountInWei,getNumberFromWei,getUserAvailableFunds,getLocks,getAuthorizations,createLock,claimLock,cancelExpiredLocks) now use the centralized helperexistingChainparameter patterns - cleaner APIIndexer Updates (
src/components/Indexer/index.ts)BlockchainRegistryas a parameterstartThread()method retrievesBlockchaininstances viablockchainRegistry.getBlockchain(chainID)P2P Updates (
src/components/P2P/index.ts)KeyManageras a parameterconfig.keys.peerId,config.keys.publicKey,config.keys.privateKeywithKeyManagermethods:keyManager.getPeerIdString()keyManager.getLibp2pPublicKey()keyManager.getLibp2pPrivateKey()Main Initialization (
src/index.ts)KeyManagerinstance:new KeyManager(config)BlockchainRegistryinstance:new BlockchainRegistry(keyManager, config)OceanNode.getInstance()await keyManager.initialize()call (initialization happens in constructor)Configuration Changes
OceanNodeKeys Interface (
src/@types/OceanNode.ts)Enhanced to support key provider selection:
type?: 'raw' | 'gcp-kms': Specifies the key provider typerawPrivateKey?: string: For raw private key configuration (future)gcpKmsConfig?: For future GCP KMS integrationNote: The
typefield is currently inferred from the presence ofprivateKeyin config, but the interface supports explicit type specification for future extensibility.Stream Encryption/Decryption
Added support for streaming encryption/decryption in
RawPrivateKeyProvider:encryptStream(inputStream, algorithm): Encrypts aReadablestreamcrypto.createCipheriv()for streaming encryptiondecryptStream(inputStream, algorithm): Decrypts aReadablestreamcrypto.createDecipheriv()for streaming decryptionBenefits
KeyManager, making it easier to audit and secureTesting
Updated test files to work with the new architecture:
src/test/integration/credentials.test.ts: UsesblockchainRegistry.getBlockchain()src/test/integration/accessLists.test.ts: Updated to use new blockchain access patternsrc/test/unit/blockchain.test.ts: TestsBlockchainRegistryfunctionalityFiles Changed
New Files
src/@types/KeyManager.ts: Type definitions for key provider architecturesrc/components/KeyManager/index.ts: Main KeyManager classsrc/components/KeyManager/providers/RawPrivateKeyProvider.ts: Raw private key provider implementationsrc/components/BlockchainRegistry/index.ts: Blockchain registry implementationdocs/KeyManager.md: Documentation for KeyManagerModified Files
src/OceanNode.ts: Added KeyManager and BlockchainRegistry integrationsrc/index.ts: Updated initialization flowsrc/utils/blockchain.ts: Refactored to use KeyManagersrc/@types/OceanNode.ts: Enhanced OceanNodeKeys interfacesrc/components/P2P/index.ts: Uses KeyManager for P2P keyssrc/components/Indexer/index.ts: Uses BlockchainRegistrysrc/components/core/utils/escrow.ts: Refactored to use BlockchainRegistrysrc/components/core/handler/ddoHandler.ts: Uses OceanNode.getBlockchain()src/components/core/handler/downloadHandler.ts: Uses OceanNode.getBlockchain()src/components/core/compute/startCompute.ts: Uses OceanNode.getBlockchain()src/components/core/compute/initialize.ts: Uses OceanNode.getBlockchain()src/components/core/admin/collectFeesHandler.ts: Uses OceanNode.getBlockchain()Related Issues
This refactoring addresses the need for: