@solarity/hardhat-migrate
Version:
The simplest way to deploy smart contracts
140 lines • 4.48 kB
JavaScript
import { exec } from "child_process";
import { promisify } from "util";
import { MigrateError } from "../../utils/index.js";
const execAsync = promisify(exec);
export async function getCastVersion() {
try {
const { stdout } = await execAsync("cast -V");
return stdout.trim();
}
catch (error) {
throw new MigrateError(`Error executing cast -V: ${error.message}. Is cast installed?`);
}
}
export async function getSignedTxViaCast(tx, castOpts = {}) {
tx.signature = await signMessage(tx.unsignedHash, {
noHash: true,
...castOpts,
});
return tx.serialized;
}
function normalizeNameForEnv(name) {
return `PASSWORD_${name.replace(/[-_]/g, "_").toUpperCase()}`;
}
/**
* Get the Ethereum address associated with the Cast wallet configuration
*
* @param options Cast wallet options
* @returns The Ethereum address
*/
export async function getCastWalletAddress(options = {}) {
const args = ["wallet", "address"];
appendWalletOptions(args, options);
const command = `cast ${args.join(" ")}`;
try {
const { stdout, stderr } = await execAsync(command);
if (stderr && stderr.trim()) {
console.error("cast stderr:", stderr);
}
return stdout.trim();
}
catch (error) {
throw new MigrateError(`Error getting address from Cast wallet: ${error.message}`);
}
}
/**
* Sign a message (or data/transaction hash) using Foundry's cast wallet sign command.
*
* @param message The message (or hash) to sign.
* @param options Additional options mapping to cast's flags.
* @returns The signature string from cast.
*/
export async function signMessage(message, options = {}) {
const args = ["wallet", "sign"];
// Process signing-specific flags
if (options.data)
args.push("--data");
if (options.fromFile)
args.push("--from-file");
if (options.noHash)
args.push("--no-hash");
// Add wallet options
appendWalletOptions(args, options);
// Add the message to sign
args.push(message);
const command = `cast ${args.join(" ")}`;
try {
const { stdout, stderr } = await execAsync(command);
if (stderr && stderr.trim()) {
console.error("cast stderr:", stderr);
}
return stdout.trim();
}
catch (error) {
throw new MigrateError(`Error executing cast sign command: ${error.message}`);
}
}
/**
* Helper function to append common wallet options to a command args array
*/
function appendWalletOptions(args, options) {
if (options.account) {
const possiblePassword = process.env[normalizeNameForEnv(options.account)];
if (possiblePassword) {
options.password = possiblePassword;
delete options.passwordFile;
}
}
if (options.from) {
args.push("--from", options.from);
}
if (options.interactive)
args.push("--interactive");
if (options.privateKey) {
args.push("--private-key", options.privateKey);
}
if (options.mnemonic) {
args.push("--mnemonic", options.mnemonic);
}
if (options.mnemonicPassphrase) {
args.push("--mnemonic-passphrase", options.mnemonicPassphrase);
}
if (options.mnemonicDerivationPath) {
args.push("--mnemonic-derivation-path", options.mnemonicDerivationPath);
}
if (typeof options.mnemonicIndex === "number") {
args.push("--mnemonic-index", options.mnemonicIndex.toString());
}
if (options.keystore) {
args.push("--keystore", options.keystore);
}
if (options.account) {
args.push("--account", options.account);
}
if (options.password) {
args.push("--password", `'${options.password}'`);
}
if (options.passwordFile) {
args.push("--password-file", options.passwordFile);
}
if (options.ledger)
args.push("--ledger");
if (options.trezor)
args.push("--trezor");
if (options.aws)
args.push("--aws");
if (options.color) {
args.push("--color", options.color);
}
if (options.json)
args.push("--json");
if (options.quiet)
args.push("--quiet");
if (options.verbosity && options.verbosity > 0) {
args.push("-" + "v".repeat(options.verbosity));
}
if (typeof options.threads === "number") {
args.push("--threads", options.threads.toString());
}
}
//# sourceMappingURL=cast-integration.js.map