UNPKG

hardhat

Version:

Hardhat is an extensible developer tool that helps smart contract developers increase productivity by reliably bringing together the tools they want.

155 lines 5.76 kB
import { LogKind, CallKind } from "@nomicfoundation/edr"; import { assertHardhatInvariant } from "@nomicfoundation/hardhat-errors"; import { bytesToHexString } from "@nomicfoundation/hardhat-utils/hex"; import chalk from "chalk"; export function formatArtifactId(artifactId, sourceNameToUserSourceName) { const sourceName = sourceNameToUserSourceName.get(artifactId.source) ?? artifactId.source; return `${sourceName}:${artifactId.name}`; } export function formatLogs(logs, indent, colorizer) { return colorizer.grey(logs.map((log) => `${" ".repeat(indent)}${log}`).join("\n")); } function formatInputs(inputs, color) { if (inputs instanceof Uint8Array) { return inputs.length > 0 ? bytesToHexString(inputs) : undefined; } else { const formattedName = color !== undefined ? color(inputs.name) : inputs.name; return `${formattedName}(${inputs.arguments.join(", ")})`; } } function formatOutputs(outputs) { if (outputs instanceof Uint8Array) { return outputs.length > 0 ? bytesToHexString(outputs) : undefined; } else { return outputs; } } function formatLog(log, colorizer = chalk) { const { parameters } = log; const lines = []; if (Array.isArray(parameters)) { const topics = parameters.map((topic) => bytesToHexString(topic)); if (topics.length > 0) { lines.push(`emit topic 0: ${colorizer.cyan(topics[0])}`); } for (let i = 1; i < topics.length - 1; i++) { lines.push(` topic ${i}: ${colorizer.cyan(topics[i])}`); } if (topics.length > 1) { lines.push(` data: ${colorizer.cyan(topics[topics.length - 1])}`); } } else { lines.push(`emit ${parameters.name}(${colorizer.cyan(parameters.arguments.join(", "))})`); } return lines; } function formatKind(kind) { assertHardhatInvariant(kind !== CallKind.Create, "Unexpected call kind 'Create'"); switch (kind) { case CallKind.Call: return undefined; case CallKind.CallCode: return "callcode"; case CallKind.DelegateCall: return "delegatecall"; case CallKind.StaticCall: return "staticcall"; } } function formatTrace(trace, colorizer) { const { success, address, contract, inputs, gasUsed, value, kind, isCheatcode, outputs, } = trace; let color; if (isCheatcode) { color = colorizer.blue; } else if (success) { color = colorizer.green; } else { color = colorizer.red; } const formattedInputs = formatInputs(inputs, color); const formattedOutputs = formatOutputs(outputs); let openingLine; let closingLine; if (kind === CallKind.Create) { openingLine = `[${gasUsed}] ${colorizer.yellow("→ new")} ${contract ?? "<unknown>"}@${address}`; // TODO: Uncomment this when the formattedInputs starts containing // the address of where the contract was deployed instead of the code. // if (formattedInputs !== undefined) { // openingLine = `${openingLine}@${formattedInputs}`; // } } else { const formattedKind = formatKind(kind); openingLine = `[${gasUsed}] ${color(contract ?? address)}`; if (formattedInputs !== undefined) { openingLine = `${openingLine}::${formattedInputs}`; } if (value !== BigInt(0)) { openingLine = `${openingLine} {value: ${value}}`; } if (formattedKind !== undefined) { openingLine = `${openingLine} ${colorizer.yellow(`[${formattedKind}]`)}`; } } if (formattedOutputs !== undefined) { if (formattedOutputs === "EvmError: Revert" || formattedOutputs.startsWith("revert:")) { closingLine = `${color("←")} ${color("[Revert]")} ${formattedOutputs}`; } else { closingLine = `${color("←")} ${formattedOutputs}`; } } const lines = []; lines.push(openingLine); for (const child of trace.children) { if (child.kind === LogKind.Log) { lines.push(formatLog(child)); } else { lines.push(formatTrace(child, colorizer)); } } if (closingLine !== undefined) { lines.push([closingLine]); } return lines; } function formatNestedArray(data, prefix = "", isTopLevel = true) { let output = ""; for (let i = 0; i < data.length; i++) { const item = data[i]; if (Array.isArray(item) && typeof item[0] === "string") { const [label, ...children] = item; if (isTopLevel) { output += `${prefix}${label}\n`; output += formatNestedArray(children, prefix, false); } else { const isLast = i === data.length - 1; const connector = isLast ? " └─ " : " ├─ "; const childPrefix = isLast ? " " : " │ "; output += `${prefix}${connector}${label}\n`; output += formatNestedArray(children, prefix + childPrefix, false); } } else if (typeof item === "string") { const isLast = i === data.length - 1; const connector = isLast ? " └─ " : " ├─ "; output += `${prefix}${connector}${item}\n`; } } return output; } export function formatTraces(traces, prefix, colorizer) { const lines = traces.map((trace) => formatTrace(trace, colorizer)); const formattedTraces = formatNestedArray(lines, prefix); // Remove the trailing newline return formattedTraces.slice(0, -1); } //# sourceMappingURL=formatters.js.map