mirror of
https://github.com/datahaven-xyz/datahaven
synced 2026-05-24 09:50:01 +00:00
fix: avoid passing private key by command line
This commit is contained in:
parent
396715ecd9
commit
3a554e21c7
3 changed files with 21 additions and 14 deletions
|
|
@ -206,9 +206,9 @@ const deployServiceManagerImplementation = async (
|
|||
|
||||
const actualDeployments = await parseDeploymentsFile(chain);
|
||||
|
||||
// Use environment variables to avoid command injection
|
||||
// Note: Private key is passed via environment variable as required by forge
|
||||
// This is a known limitation of the forge toolchain
|
||||
// Use environment variables to avoid command injection and process list exposure
|
||||
// Note: Private key is passed via PRIVATE_KEY environment variable (not command-line)
|
||||
// to prevent it from appearing in system process lists (security best practice)
|
||||
const env = {
|
||||
...process.env,
|
||||
PRIVATE_KEY: privateKey,
|
||||
|
|
@ -226,8 +226,6 @@ const deployServiceManagerImplementation = async (
|
|||
"deployServiceManagerImpl()",
|
||||
"--rpc-url",
|
||||
rpcUrl,
|
||||
"--private-key",
|
||||
privateKey,
|
||||
"--broadcast",
|
||||
"--non-interactive"
|
||||
];
|
||||
|
|
@ -296,8 +294,8 @@ const updateServiceManagerProxyWithVersion = async (
|
|||
) => {
|
||||
logger.info(`🔄 Updating ServiceManager proxy and setting version to ${version}...`);
|
||||
|
||||
// Note: Private key is passed via environment variable as required by forge
|
||||
// This is a known limitation of the forge toolchain
|
||||
// Note: Private key is passed via PRIVATE_KEY environment variable (not command-line)
|
||||
// to prevent it from appearing in system process lists (security best practice)
|
||||
const proxyAdmin = (deployments as any).ProxyAdmin ?? process.env.PROXY_ADMIN;
|
||||
if (!proxyAdmin) {
|
||||
throw new Error(
|
||||
|
|
@ -322,8 +320,6 @@ const updateServiceManagerProxyWithVersion = async (
|
|||
"updateServiceManagerProxyWithVersion()",
|
||||
"--rpc-url",
|
||||
rpcUrl,
|
||||
"--private-key",
|
||||
privateKey,
|
||||
"--broadcast",
|
||||
"--non-interactive"
|
||||
];
|
||||
|
|
|
|||
|
|
@ -160,10 +160,13 @@ export const fundValidators = async (options: FundValidatorsOptions): Promise<bo
|
|||
const ethTransferAmount = BigInt(creatorEthBalance) / BigInt(100); // 1% of the balance
|
||||
logger.debug(`Transferring ${erc20TransferAmount} tokens to each validator`);
|
||||
|
||||
// Security Note: Private keys are passed via stdin with --interactive flag
|
||||
// using printf (not echo) to avoid command-line exposure in process lists
|
||||
for (const validator of validators) {
|
||||
if (validator.publicKey !== tokenCreator) {
|
||||
const transferCmd = `${castExecutable} send --private-key ${creatorPrivateKey} ${underlyingTokenAddress} "transfer(address,uint256)" ${validator.publicKey} ${erc20TransferAmount} --rpc-url ${rpcUrl}`;
|
||||
const transferCmd = `printf '%s\\n' "\${PRIVATE_KEY}" | ${castExecutable} send --interactive ${underlyingTokenAddress} "transfer(address,uint256)" ${validator.publicKey} ${erc20TransferAmount} --rpc-url ${rpcUrl}`;
|
||||
const { exitCode: transferExitCode, stderr: transferStderr } = await $`sh -c ${transferCmd}`
|
||||
.env({ ...process.env, PRIVATE_KEY: creatorPrivateKey })
|
||||
.nothrow()
|
||||
.quiet();
|
||||
if (transferExitCode !== 0) {
|
||||
|
|
@ -196,9 +199,12 @@ export const fundValidators = async (options: FundValidatorsOptions): Promise<bo
|
|||
|
||||
// Transfer ETH only if the validator has no ETH
|
||||
if (BigInt(validatorEthBalance) === BigInt(0)) {
|
||||
const ethTransferCmd = `${castExecutable} send --private-key ${creatorPrivateKey} ${validator.publicKey} --value ${ethTransferAmount} --rpc-url ${rpcUrl}`;
|
||||
const ethTransferCmd = `printf '%s\\n' "\${PRIVATE_KEY}" | ${castExecutable} send --interactive ${validator.publicKey} --value ${ethTransferAmount} --rpc-url ${rpcUrl}`;
|
||||
const { exitCode: ethTransferExitCode, stderr: ethTransferStderr } =
|
||||
await $`sh -c ${ethTransferCmd}`.nothrow().quiet();
|
||||
await $`sh -c ${ethTransferCmd}`
|
||||
.env({ ...process.env, PRIVATE_KEY: creatorPrivateKey })
|
||||
.nothrow()
|
||||
.quiet();
|
||||
if (ethTransferExitCode !== 0) {
|
||||
logger.error(
|
||||
`Failed to transfer ETH to validator ${validator.publicKey}: ${ethTransferStderr.toString()}`
|
||||
|
|
|
|||
|
|
@ -45,16 +45,21 @@ export const updateValidatorSet = async (options: UpdateValidatorSetOptions): Pr
|
|||
const serviceManagerAddress = deployments.ServiceManager;
|
||||
invariant(serviceManagerAddress, "ServiceManager address not found in deployments");
|
||||
|
||||
// Security Note: Private key is passed via stdin with --interactive flag
|
||||
// using printf to avoid command-line exposure in process lists (security best practice)
|
||||
// Using cast to send the transaction
|
||||
const executionFee = "100000000000000000"; // 0.1 ETH
|
||||
const relayerFee = "200000000000000000"; // 0.2 ETH
|
||||
const value = "300000000000000000"; // 0.3 ETH (sum of fees)
|
||||
|
||||
const sendCommand = `${castExecutable} send --private-key ${ownerPrivateKey} --value ${value} ${serviceManagerAddress} "sendNewValidatorSet(uint128,uint128)" ${executionFee} ${relayerFee} --rpc-url ${rpcUrl}`;
|
||||
const sendCommand = `printf '%s\\n' "\${PRIVATE_KEY}" | ${castExecutable} send --interactive --value ${value} ${serviceManagerAddress} "sendNewValidatorSet(uint128,uint128)" ${executionFee} ${relayerFee} --rpc-url ${rpcUrl}`;
|
||||
|
||||
logger.debug(`Running command: ${sendCommand}`);
|
||||
|
||||
const { exitCode, stderr } = await $`sh -c ${sendCommand}`.nothrow().quiet();
|
||||
const { exitCode, stderr } = await $`sh -c ${sendCommand}`
|
||||
.env({ ...process.env, PRIVATE_KEY: ownerPrivateKey })
|
||||
.nothrow()
|
||||
.quiet();
|
||||
|
||||
if (exitCode !== 0) {
|
||||
logger.error(`Failed to send validator set: ${stderr.toString()}`);
|
||||
|
|
|
|||
Loading…
Reference in a new issue