Skip to content

Commit ac5c280

Browse files
authored
Merge branch 'v-next' into test-solidity-no-compile
2 parents fd98482 + 7e815f5 commit ac5c280

40 files changed

+1095
-730
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import type { SensitiveString } from "../../../../types/config.js";
2+
3+
export interface DefaultHDAccountsConfigParams {
4+
initialIndex: number;
5+
count: number;
6+
path: string;
7+
passphrase: SensitiveString;
8+
}
9+
10+
export const DEFAULT_HD_ACCOUNTS_CONFIG_PARAMS: DefaultHDAccountsConfigParams =
11+
{
12+
initialIndex: 0,
13+
count: 20,
14+
path: "m/44'/60'/0'/0",
15+
passphrase: "",
16+
};

v-next/hardhat/src/internal/builtin-plugins/network-manager/accounts/derive-private-keys.ts

+6-12
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,18 @@
11
import { HardhatError } from "@ignored/hardhat-vnext-errors";
2+
import { bytesToHexString } from "@ignored/hardhat-vnext-utils/bytes";
23
import { mnemonicToSeedSync } from "ethereum-cryptography/bip39";
34
import { HDKey } from "ethereum-cryptography/hdkey";
45

56
const HD_PATH_REGEX = /^m(:?\/\d+'?)+\/?$/;
67

7-
export const DEFAULT_HD_ACCOUNTS_CONFIG_PARAMS = {
8-
initialIndex: 0,
9-
count: 20,
10-
path: "m/44'/60'/0'/0",
11-
passphrase: "",
12-
};
13-
148
export function derivePrivateKeys(
159
mnemonic: string,
1610
hdpath: string,
1711
initialIndex: number,
1812
count: number,
1913
passphrase: string,
20-
): Buffer[] {
21-
if (hdpath.match(HD_PATH_REGEX) === null) {
14+
): string[] {
15+
if (!HD_PATH_REGEX.test(hdpath)) {
2216
throw new HardhatError(HardhatError.ERRORS.NETWORK.INVALID_HD_PATH, {
2317
path: hdpath,
2418
});
@@ -28,7 +22,7 @@ export function derivePrivateKeys(
2822
hdpath += "/";
2923
}
3024

31-
const privateKeys: Buffer[] = [];
25+
const privateKeys: string[] = [];
3226

3327
for (let i = initialIndex; i < initialIndex + count; i++) {
3428
const privateKey = deriveKeyFromMnemonicAndPath(
@@ -54,7 +48,7 @@ function deriveKeyFromMnemonicAndPath(
5448
mnemonic: string,
5549
hdPath: string,
5650
passphrase: string,
57-
): Buffer | undefined {
51+
): string | undefined {
5852
// NOTE: If mnemonic has space or newline at the beginning or end, it will be trimmed.
5953
// This is because mnemonic containing them may generate different private keys.
6054
const trimmedMnemonic = mnemonic.trim();
@@ -66,5 +60,5 @@ function deriveKeyFromMnemonicAndPath(
6660

6761
return derived.privateKey === null
6862
? undefined
69-
: Buffer.from(derived.privateKey);
63+
: bytesToHexString(derived.privateKey);
7064
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import type {
2+
EthereumProvider,
3+
JsonRpcRequest,
4+
JsonRpcResponse,
5+
RequestArguments,
6+
SuccessfulJsonRpcResponse,
7+
} from "../../../types/providers.js";
8+
9+
import EventEmitter from "node:events";
10+
import util from "node:util";
11+
12+
import { ensureError } from "@ignored/hardhat-vnext-utils/error";
13+
14+
export abstract class BaseProvider
15+
extends EventEmitter
16+
implements EthereumProvider
17+
{
18+
public abstract request(
19+
requestArguments: RequestArguments,
20+
): Promise<SuccessfulJsonRpcResponse["result"]>;
21+
public abstract close(): Promise<void>;
22+
23+
public send(
24+
method: string,
25+
params?: unknown[],
26+
): Promise<SuccessfulJsonRpcResponse["result"]> {
27+
return this.request({ method, params });
28+
}
29+
30+
public sendAsync(
31+
jsonRpcRequest: JsonRpcRequest,
32+
callback: (error: any, jsonRpcResponse: JsonRpcResponse) => void,
33+
): void {
34+
const handleJsonRpcRequest = async () => {
35+
let jsonRpcResponse: JsonRpcResponse;
36+
try {
37+
const result = await this.request({
38+
method: jsonRpcRequest.method,
39+
params: jsonRpcRequest.params,
40+
});
41+
jsonRpcResponse = {
42+
jsonrpc: "2.0",
43+
id: jsonRpcRequest.id,
44+
result,
45+
};
46+
} catch (error) {
47+
ensureError(error);
48+
49+
if (!("code" in error) || error.code === undefined) {
50+
throw error;
51+
}
52+
53+
/* eslint-disable-next-line @typescript-eslint/restrict-template-expressions
54+
-- Allow string interpolation of unknown `error.code`. It will be converted
55+
to a number, and we will handle NaN cases appropriately afterwards. */
56+
const errorCode = parseInt(`${error.code}`, 10);
57+
jsonRpcResponse = {
58+
jsonrpc: "2.0",
59+
id: jsonRpcRequest.id,
60+
error: {
61+
code: !isNaN(errorCode) ? errorCode : -1,
62+
message: error.message,
63+
data: {
64+
stack: error.stack,
65+
name: error.name,
66+
},
67+
},
68+
};
69+
}
70+
71+
return jsonRpcResponse;
72+
};
73+
74+
util.callbackify(handleJsonRpcRequest)(callback);
75+
}
76+
}

v-next/hardhat/src/internal/builtin-plugins/network-manager/config-resolution.ts

+41-29
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type {
2-
ConfigurationResolver,
2+
ConfigurationVariableResolver,
33
EdrNetworkAccountsConfig,
44
EdrNetworkAccountsUserConfig,
55
EdrNetworkChainConfig,
@@ -22,21 +22,21 @@ import {
2222
normalizeHexString,
2323
} from "@ignored/hardhat-vnext-utils/hex";
2424

25-
import { DEFAULT_HD_ACCOUNTS_CONFIG_PARAMS } from "./accounts/derive-private-keys.js";
25+
import { DEFAULT_HD_ACCOUNTS_CONFIG_PARAMS } from "./accounts/constants.js";
2626
import {
2727
DEFAULT_EDR_NETWORK_HD_ACCOUNTS_CONFIG_PARAMS,
2828
EDR_NETWORK_DEFAULT_COINBASE,
2929
} from "./edr/edr-provider.js";
30-
import { HardforkName } from "./edr/types/hardfork.js";
31-
import { isHdAccountsConfig } from "./type-validation.js";
30+
import { HardforkName, LATEST_HARDFORK } from "./edr/types/hardfork.js";
31+
import { isHdAccountsUserConfig } from "./type-validation.js";
3232

3333
export function resolveGasConfig(value: GasUserConfig = "auto"): GasConfig {
3434
return value === "auto" ? value : BigInt(value);
3535
}
3636

3737
export function resolveHttpNetworkAccounts(
3838
accounts: HttpNetworkAccountsUserConfig | undefined = "remote",
39-
resolveConfigurationVariable: ConfigurationResolver,
39+
resolveConfigurationVariable: ConfigurationVariableResolver,
4040
): HttpNetworkAccountsConfig {
4141
if (Array.isArray(accounts)) {
4242
return accounts.map((acc) => {
@@ -48,10 +48,16 @@ export function resolveHttpNetworkAccounts(
4848
});
4949
}
5050

51-
if (isHdAccountsConfig(accounts)) {
51+
if (isHdAccountsUserConfig(accounts)) {
52+
const { passphrase: defaultPassphrase, ...defaultHdAccountRest } =
53+
DEFAULT_HD_ACCOUNTS_CONFIG_PARAMS;
54+
const { mnemonic, passphrase, ...hdAccountRest } = accounts;
55+
5256
return {
53-
...DEFAULT_HD_ACCOUNTS_CONFIG_PARAMS,
54-
...accounts,
57+
...defaultHdAccountRest,
58+
...hdAccountRest,
59+
mnemonic: resolveConfigurationVariable(mnemonic),
60+
passphrase: resolveConfigurationVariable(passphrase ?? defaultPassphrase),
5561
};
5662
}
5763

@@ -62,49 +68,55 @@ export function resolveEdrNetworkAccounts(
6268
accounts:
6369
| EdrNetworkAccountsUserConfig
6470
| undefined = DEFAULT_EDR_NETWORK_HD_ACCOUNTS_CONFIG_PARAMS,
71+
resolveConfigurationVariable: ConfigurationVariableResolver,
6572
): EdrNetworkAccountsConfig {
6673
if (Array.isArray(accounts)) {
67-
return accounts.map(({ privateKey, balance }) => ({
68-
privateKey: normalizeHexString(privateKey),
69-
balance: BigInt(balance),
70-
}));
74+
return accounts.map(({ privateKey, balance }) => {
75+
if (typeof privateKey === "string") {
76+
privateKey = normalizeHexString(privateKey);
77+
}
78+
79+
return {
80+
privateKey: resolveConfigurationVariable(privateKey),
81+
balance: BigInt(balance),
82+
};
83+
});
7184
}
7285

86+
const {
87+
mnemonic: defaultMnemonic,
88+
accountsBalance: defaultAccountsBalance,
89+
passphrase: defaultPassphrase,
90+
...defaultHdAccountRest
91+
} = DEFAULT_EDR_NETWORK_HD_ACCOUNTS_CONFIG_PARAMS;
92+
const { mnemonic, passphrase, accountsBalance, ...hdAccountRest } = accounts;
7393
return {
74-
...DEFAULT_EDR_NETWORK_HD_ACCOUNTS_CONFIG_PARAMS,
75-
...accounts,
76-
accountsBalance: BigInt(
77-
accounts.accountsBalance ??
78-
DEFAULT_EDR_NETWORK_HD_ACCOUNTS_CONFIG_PARAMS.accountsBalance,
79-
),
94+
...defaultHdAccountRest,
95+
...hdAccountRest,
96+
mnemonic: resolveConfigurationVariable(mnemonic ?? defaultMnemonic),
97+
accountsBalance: BigInt(accountsBalance ?? defaultAccountsBalance),
98+
passphrase: resolveConfigurationVariable(passphrase ?? defaultPassphrase),
8099
};
81100
}
82101

83102
export function resolveForkingConfig(
84103
forkingUserConfig: EdrNetworkForkingUserConfig | undefined,
85104
cacheDir: string,
105+
resolveConfigurationVariable: ConfigurationVariableResolver,
86106
): EdrNetworkForkingConfig | undefined {
87107
if (forkingUserConfig === undefined) {
88108
return undefined;
89109
}
90110

91-
const httpHeaders =
92-
forkingUserConfig.httpHeaders !== undefined
93-
? Object.entries(forkingUserConfig.httpHeaders).map(([name, value]) => ({
94-
name,
95-
value,
96-
}))
97-
: undefined;
98-
99111
return {
100112
enabled: forkingUserConfig.enabled ?? true,
101-
url: forkingUserConfig.url,
113+
url: resolveConfigurationVariable(forkingUserConfig.url),
102114
cacheDir: path.join(cacheDir, "edr-fork-cache"),
103115
blockNumber:
104116
forkingUserConfig.blockNumber !== undefined
105117
? BigInt(forkingUserConfig.blockNumber)
106118
: undefined,
107-
httpHeaders,
119+
httpHeaders: forkingUserConfig.httpHeaders,
108120
};
109121
}
110122

@@ -274,7 +286,7 @@ export function resolveHardfork(
274286
}
275287

276288
if (enableTransientStorage === true) {
277-
return HardforkName.CANCUN;
289+
return LATEST_HARDFORK;
278290
} else {
279291
return HardforkName.SHANGHAI;
280292
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import {
2+
EdrContext,
3+
GENERIC_CHAIN_TYPE,
4+
genericChainProviderFactory,
5+
L1_CHAIN_TYPE,
6+
l1ProviderFactory,
7+
OPTIMISM_CHAIN_TYPE,
8+
optimismProviderFactory,
9+
} from "@ignored/edr-optimism";
10+
11+
let _globalEdrContext: EdrContext | undefined;
12+
13+
export async function getGlobalEdrContext(): Promise<EdrContext> {
14+
if (_globalEdrContext === undefined) {
15+
_globalEdrContext = new EdrContext();
16+
await _globalEdrContext.registerProviderFactory(
17+
GENERIC_CHAIN_TYPE,
18+
genericChainProviderFactory(),
19+
);
20+
await _globalEdrContext.registerProviderFactory(
21+
L1_CHAIN_TYPE,
22+
l1ProviderFactory(),
23+
);
24+
await _globalEdrContext.registerProviderFactory(
25+
OPTIMISM_CHAIN_TYPE,
26+
optimismProviderFactory(),
27+
);
28+
}
29+
30+
return _globalEdrContext;
31+
}

0 commit comments

Comments
 (0)