@hyperlane-xyz/cli
Version:
A command-line utility for common Hyperlane operations
115 lines • 4.34 kB
JavaScript
import { ProtocolType, assert, rootLogger } from '@hyperlane-xyz/utils';
import { ENV } from '../../../utils/env.js';
import { MultiProtocolSignerFactory } from './MultiProtocolSignerFactory.js';
/**
* @title MultiProtocolSignerManager
* @dev Context manager for signers across multiple protocols
*/
export class MultiProtocolSignerManager {
submissionStrategy;
chains;
multiProvider;
options;
signerStrategies;
signers;
logger;
constructor(submissionStrategy, chains, multiProvider, options = {}) {
this.submissionStrategy = submissionStrategy;
this.chains = chains;
this.multiProvider = multiProvider;
this.options = options;
this.logger =
options?.logger ||
rootLogger.child({
module: 'MultiProtocolSignerManager',
});
this.signerStrategies = new Map();
this.signers = new Map();
this.initializeStrategies();
}
/**
* @notice Sets up chain-specific signer strategies
*/
initializeStrategies() {
for (const chain of this.chains) {
if (this.multiProvider.getProtocol(chain) !== ProtocolType.Ethereum) {
this.logger.debug(`Skipping signer strategy initialization for non-EVM chain ${chain}`);
continue;
}
const strategy = MultiProtocolSignerFactory.getSignerStrategy(chain, this.submissionStrategy, this.multiProvider);
this.signerStrategies.set(chain, strategy);
}
}
/**
* @dev Configures signers for EVM chains in MultiProvider
*/
async getMultiProvider() {
for (const chain of this.chains) {
if (this.multiProvider.getProtocol(chain) !== ProtocolType.Ethereum) {
this.logger.debug(`Skipping signer initialization for non-EVM chain ${chain}`);
continue;
}
const signer = await this.initSigner(chain);
this.multiProvider.setSigner(chain, signer);
}
return this.multiProvider;
}
/**
* @notice Creates signer for specific chain
*/
async initSigner(chain) {
const { privateKey } = await this.resolveConfig(chain);
const signerStrategy = this.signerStrategies.get(chain);
assert(signerStrategy, `No signer strategy found for chain ${chain}`);
return signerStrategy.getSigner({ privateKey });
}
/**
* @notice Creates signers for all chains
*/
async initAllSigners() {
const signerConfigs = await this.resolveAllConfigs();
for (const { chain, privateKey } of signerConfigs) {
const signerStrategy = this.signerStrategies.get(chain);
if (signerStrategy) {
this.signers.set(chain, signerStrategy.getSigner({ privateKey }));
}
}
return this.signers;
}
/**
* @notice Resolves all chain configurations
*/
async resolveAllConfigs() {
return Promise.all(this.chains.map((chain) => this.resolveConfig(chain)));
}
/**
* @notice Resolves single chain configuration
*/
async resolveConfig(chain) {
const signerStrategy = this.signerStrategies.get(chain);
assert(signerStrategy, `No signer strategy found for chain ${chain}`);
let privateKey;
if (this.options.key) {
this.logger.debug(`Using private key passed via CLI --key flag for chain ${chain}`);
privateKey = this.options.key;
}
else if (ENV.HYP_KEY) {
this.logger.debug(`Using private key from .env for chain ${chain}`);
privateKey = ENV.HYP_KEY;
}
else {
privateKey = await this.extractPrivateKey(chain, signerStrategy);
}
return { chain, privateKey };
}
/**
* @notice Gets private key from strategy
*/
async extractPrivateKey(chain, signerStrategy) {
const strategyConfig = await signerStrategy.getSignerConfig(chain);
assert(strategyConfig.privateKey, `No private key found for chain ${chain}`);
this.logger.debug(`Extracting private key from strategy config/user prompt for chain ${chain}`);
return strategyConfig.privateKey;
}
}
//# sourceMappingURL=MultiProtocolSignerManager.js.map