-
Notifications
You must be signed in to change notification settings - Fork 18
/
anvil-server.ts
123 lines (109 loc) · 3.26 KB
/
anvil-server.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import { spawn } from "child_process";
import debug from "debug";
import { getAnvilCommand } from "@foundry-rs/easy-foundryup";
import { AnvilOptions } from "./anvil-service";
const log = debug("hardhat::plugin::anvil::spawn");
export class AnvilServer {
private readonly _anvil: any;
private readonly _options: AnvilOptions;
private constructor(options: AnvilOptions, anvil: any) {
this._options = options;
this._anvil = anvil;
}
public static async launch(
options: any,
inherit: boolean = false
): Promise<AnvilServer> {
log("Launching anvil");
let anvil: any;
if (options.launch) {
const anvilPath = options.path ?? (await getAnvilCommand());
const args = [];
if (options.port) {
args.push("--port", options.port);
}
if (options.totalAccounts) {
args.push("--accounts", options.totalAccounts);
}
if (options.mnemonic) {
args.push("--mnemonic", options.mnemonic);
}
if (options.defaultBalanceEther) {
args.push("--balance", options.defaultBalanceEther);
}
if (options.hdPath) {
args.push("--derivation-path", options.hdPath);
}
if (options.silent) {
args.push("--silent", options.silent);
}
if (options.blockTime) {
args.push("--block-time", options.blockTime);
}
if (options.gasLimit) {
args.push("--gas-limit", options.gasLimit);
}
if (options.gasPrice) {
if (options.gasPrice !== "auto") {
args.push("--gas-price", options.gasPrice);
}
}
if (options.chainId) {
args.push("--chain-id", options.chainId);
}
if (options.forkurl) {
args.push("--fork-url", options.forkurl);
if (options.forkBlockNumber) {
args.push("--fork-block-number", options.forkBlockNumber);
}
}
if (options.noStorageCaching) {
args.push("--no-storage-caching");
}
if (options.hardfork) {
if (options.hardfork !== "arrowGlacier") {
args.push("--hardfork", options.hardfork);
}
}
const opts = inherit ? { stdio: "inherit" } : {};
anvil = spawn(anvilPath, args, opts as any);
anvil.on("close", (code: any) => {
log(`anvil child process exited with code ${code}`);
});
process.on("exit", function () {
anvil.kill();
});
if (!inherit) {
let serverReady = false;
anvil.stdout.on("data", (data: any) => {
const output = data.toString();
if (output.includes("Listening")) {
serverReady = true;
}
log(`${data}`);
});
anvil.stderr.on("data", (data: any) => {
log(`${data}`);
});
// wait until server ready
const retries = 30; // 3secs
for (let i = 0; i < retries; i++) {
if (serverReady) {
log("anvil server ready");
break;
}
await new Promise((resolve) => setTimeout(resolve, 100));
}
}
}
return new AnvilServer(options, anvil);
}
public kill() {
this._anvil?.kill();
}
public async waitUntilClosed(): Promise<void> {
return new Promise((resolve) => {
this._anvil.once("close", resolve);
});
}
}