Skip to content

Commit baaf72a

Browse files
authored
Merge branch 'main' into 7511-hardhat-test-should-set-node_env-to-test
2 parents e465625 + 58fcc83 commit baaf72a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+3877
-5
lines changed

.changeset/purple-wasps-jump.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"hardhat": patch
3+
---
4+
5+
Validate initialBaseFeePerGas against hardfork only for L1 chain type

.changeset/shiny-pigs-give.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@nomicfoundation/hardhat-errors": patch
3+
---
4+
5+
Ported the `@nomicfoundation/hardhat-ledger` plugin to Hardhat 3 ([#5646](https://github.com/NomicFoundation/hardhat/issues/5646))

package.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,16 @@
1818
"prelint:fix": "pnpm build",
1919
"lint:fix": "pnpm run --recursive --if-present lint:fix",
2020
"version-for-release": "pnpm changeset version && pnpm -w install --lockfile-only"
21+
},
22+
"pnpm": {
23+
"onlyBuiltDependencies": [
24+
"node-hid"
25+
],
26+
"ignoredBuiltDependencies": [
27+
"esbuild",
28+
"keccak",
29+
"unrs-resolver",
30+
"usb"
31+
]
2132
}
2233
}

pnpm-lock.yaml

Lines changed: 593 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

v-next/example-project/hardhat.config.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import hardhatChaiMatchersPlugin from "@nomicfoundation/hardhat-ethers-chai-matc
1515
import hardhatTypechain from "@nomicfoundation/hardhat-typechain";
1616
import hardhatIgnitionViem from "@nomicfoundation/hardhat-ignition-viem";
1717
import hardhatVerify from "@nomicfoundation/hardhat-verify";
18+
import hardhatLedger from "@nomicfoundation/hardhat-ledger";
1819
import { ArgumentType } from "hardhat/types/arguments";
1920

2021
util.inspect.defaultOptions.depth = null;
@@ -139,6 +140,10 @@ const config: HardhatUserConfig = {
139140
forking: {
140141
url: "https://mainnet.optimism.io",
141142
},
143+
ledgerAccounts: [
144+
// Set your ledger address here
145+
// "0x070Da0697e6B82F0ab3f5D0FD9210EAdF2Ba1516",
146+
],
142147
},
143148
opSepolia: {
144149
type: "http",
@@ -175,6 +180,7 @@ const config: HardhatUserConfig = {
175180
hardhatChaiMatchersPlugin,
176181
hardhatTypechain,
177182
hardhatIgnitionViem,
183+
hardhatLedger,
178184
],
179185
paths: {
180186
tests: {

v-next/example-project/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
"@nomicfoundation/ignition-core": "workspace:^3.0.0",
3232
"@nomicfoundation/hardhat-ignition-viem": "workspace:^3.0.0",
3333
"@nomicfoundation/hardhat-keystore": "workspace:^3.0.0",
34+
"@nomicfoundation/hardhat-ledger": "workspace:^1.2.0",
3435
"@nomicfoundation/hardhat-mocha": "workspace:^3.0.0",
3536
"@nomicfoundation/hardhat-network-helpers": "workspace:^3.0.1",
3637
"@nomicfoundation/hardhat-node-test-runner": "workspace:^3.0.0",
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
import hre from "hardhat";
2+
import assert from "node:assert";
3+
4+
const BALANCE_TO_SEND = 1000000000000000000n;
5+
6+
const { provider, ethers } = await hre.network.connect("edrOp");
7+
8+
const signers = await ethers.getSigners();
9+
10+
const hardhatSigner = signers[0];
11+
const hardhatAddress = hardhatSigner.address;
12+
// Ledger accounts are returned at the end
13+
const ledgerSigner = signers[signers.length - 1];
14+
const ledgerAddress = ledgerSigner.address;
15+
16+
// Be sure that the ledger account has some ETH
17+
await hardhatSigner.sendTransaction({
18+
to: ledgerAddress,
19+
value: BALANCE_TO_SEND,
20+
});
21+
22+
// Uncomment the RPC method you want to test
23+
24+
await ethSendTransaction();
25+
26+
// await ethSign();
27+
28+
// await personalSign();
29+
30+
// await ethSignTypedDataV4();
31+
32+
async function ethSendTransaction() {
33+
const txParams = {
34+
// Shared properties
35+
to: hardhatAddress,
36+
value: 10000000n,
37+
gas: 310000n,
38+
39+
// Enable the properties that you need for a specific transaction type
40+
// and comment out the ones that you don't need
41+
42+
// eip1559
43+
maxFeePerGas: 1000000000n,
44+
maxPriorityFeePerGas: 1000000000n,
45+
46+
// eip2930
47+
//gasPrice: 999999345n,
48+
//accessList: [],
49+
50+
// legacy
51+
// gasPrice: 999999345n,
52+
};
53+
54+
await ledgerSigner.sendTransaction(txParams);
55+
}
56+
57+
async function ethSign() {
58+
const msg = ethers.toUtf8Bytes("Hello eth_sign");
59+
const hexMsg = ethers.hexlify(msg);
60+
61+
const sig = await provider.request({
62+
method: "eth_sign",
63+
params: [ledgerAddress, hexMsg],
64+
});
65+
66+
const verifiedAddress = ethers.verifyMessage("Hello eth_sign", sig);
67+
68+
assert.equal(verifiedAddress, ledgerAddress);
69+
}
70+
71+
async function personalSign() {
72+
const message = "Hello personal_sign";
73+
74+
const sig = await provider.request({
75+
method: "personal_sign",
76+
params: [ethers.hexlify(ethers.toUtf8Bytes(message)), ledgerAddress],
77+
});
78+
79+
const recovered = ethers.verifyMessage(message, sig);
80+
81+
assert.equal(recovered, ledgerAddress);
82+
}
83+
84+
async function ethSignTypedDataV4() {
85+
const chainId = Number((await ethers.provider.getNetwork()).chainId);
86+
87+
// EIP‑712 domain separator
88+
const domain = {
89+
name: "MyDApp",
90+
version: "1",
91+
chainId,
92+
verifyingContract: "0x0000000000000000000000000000000000000000",
93+
};
94+
95+
const mailTypes = {
96+
Mail: [
97+
{ name: "from", type: "address" },
98+
{ name: "to", type: "address" },
99+
{ name: "contents", type: "string" },
100+
],
101+
};
102+
103+
const types = {
104+
EIP712Domain: [
105+
{ name: "name", type: "string" },
106+
{ name: "version", type: "string" },
107+
{ name: "chainId", type: "uint256" },
108+
{ name: "verifyingContract", type: "address" },
109+
],
110+
...mailTypes,
111+
};
112+
113+
const message = {
114+
from: ledgerAddress,
115+
to: hardhatAddress,
116+
contents: "Hello typed data",
117+
};
118+
119+
const json = JSON.stringify({
120+
domain,
121+
types,
122+
primaryType: "Mail",
123+
message,
124+
});
125+
126+
const sig = await provider.request({
127+
method: "eth_signTypedData_v4",
128+
params: [ledgerAddress, json],
129+
});
130+
131+
const digest = ethers.TypedDataEncoder.hash(domain, mailTypes, message);
132+
const recovered = ethers.recoverAddress(digest, sig);
133+
134+
assert.equal(recovered, ledgerAddress);
135+
}

v-next/example-project/tsconfig.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@
4242
},
4343
{
4444
"path": "../hardhat-ignition-viem"
45+
},
46+
{
47+
"path": "../hardhat-ledger"
4548
}
4649
]
4750
}

v-next/hardhat-errors/src/descriptors.ts

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,24 @@ export const ERROR_CATEGORIES: {
302302
},
303303
},
304304
},
305+
HARDHAT_LEDGER: {
306+
min: 90000,
307+
max: 90999,
308+
pluginId: "hardhat-ledger",
309+
websiteTitle: "Hardhat Ledger",
310+
CATEGORIES: {
311+
GENERAL: {
312+
min: 90000,
313+
max: 90099,
314+
websiteSubTitle: "General errors",
315+
},
316+
VALIDATION: {
317+
min: 90100,
318+
max: 90199,
319+
websiteSubTitle: "Validation errors",
320+
},
321+
},
322+
},
305323
};
306324

307325
export const ERRORS = {
@@ -2782,4 +2800,78 @@ export default { lib1: "0x...", lib2: "0x...", ... };
27822800
},
27832801
},
27842802
},
2803+
HARDHAT_LEDGER: {
2804+
GENERAL: {
2805+
INVALID_LEDGER_ADDRESS: {
2806+
number: 90000,
2807+
messageTemplate: `The ledger address "{address}" in the Hardhat configuration file is invalid.`,
2808+
websiteTitle: "Invalid ledger address",
2809+
websiteDescription: `The ledger address in the Hardhat configuration file is invalid.`,
2810+
},
2811+
UNOWNED_LEDGER_ADDRESS: {
2812+
number: 90001,
2813+
messageTemplate: `Transaction attempted from address "{address}", which is not listed in the Hardhat configuration file.`,
2814+
websiteTitle: "Unknown ledger address",
2815+
websiteDescription: `Transaction attempted from an address which is not listed in the Hardhat configuration file.`,
2816+
},
2817+
CONNECTION_ERROR: {
2818+
number: 90002,
2819+
messageTemplate: `There was an error trying to establish a connection to the Ledger wallet: {error}.{transportId}
2820+
2821+
Make sure your Ledger is connected and unlocked, and that the Ethereum app is open.`,
2822+
websiteTitle: "Ledger connection error",
2823+
websiteDescription: `There was an error trying to establish a connection to the Ledger wallet.
2824+
2825+
Make sure your Ledger is connected and unlocked, and that the Ethereum app is open.`,
2826+
},
2827+
ERROR_WHILE_DERIVING_PATH: {
2828+
number: 90003,
2829+
messageTemplate: `There was an error trying to derive path "{path}": "{message}". The wallet might be connected but locked or in the wrong app.`,
2830+
websiteTitle: "Error while deriving path",
2831+
websiteDescription: `There was an error trying to derivate the path. The wallet might be connected but locked or in the wrong app.`,
2832+
},
2833+
CANNOT_FIND_VALID_DERIVATION_PATH: {
2834+
number: 90004,
2835+
messageTemplate: `Cannot find a valid derivation path for address "{address}". Paths from {pathStart} to {pathEnd} were searched.`,
2836+
websiteTitle: "Cannot find valid derivation path",
2837+
websiteDescription: `Cannot find a valid derivation path for the address`,
2838+
},
2839+
PERSONAL_SIGN_MISSING_ADDRESS_PARAM: {
2840+
number: 90005,
2841+
messageTemplate: `Missing address parameter when calling personal_sign.`,
2842+
websiteTitle: "Missing address parameter when calling personal_sign",
2843+
websiteDescription: `You called "personal_sign" with incorrect parameters.
2844+
2845+
Please check that you are sending an "address" parameter.`,
2846+
},
2847+
ETH_SIGN_MISSING_DATA_PARAM: {
2848+
number: 90006,
2849+
messageTemplate: `Missing "data" param when calling eth_sign.`,
2850+
websiteTitle: `Missing "data" param when calling eth_sign.`,
2851+
websiteDescription: `You called "eth_sign" with incorrect parameters.
2852+
2853+
Please check that you are sending a "data" parameter.`,
2854+
},
2855+
ETH_SIGN_TYPED_DATA_V4_INVALID_DATA_PARAM: {
2856+
number: 90007,
2857+
messageTemplate: `Invalid "data" param when calling eth_signTypedData_v4.`,
2858+
websiteTitle: `Invalid "data" param when calling eth_signTypedData_v4.`,
2859+
websiteDescription: `You called "eth_signTypedData_v4" with incorrect parameters.
2860+
2861+
Please check that you are sending a "data" parameter with a JSON string or object conforming to EIP712 TypedData schema.`,
2862+
},
2863+
LOCKED_DEVICE: {
2864+
number: 90008,
2865+
messageTemplate: `The ledger device is locked. Please unlock it and try again.`,
2866+
websiteTitle: `The ledger device is locked`,
2867+
websiteDescription: `The ledger device is locked. Please unlock it and try again.`,
2868+
},
2869+
EIP_7702_TX_CURRENTLY_NOT_SUPPORTED: {
2870+
number: 90009,
2871+
messageTemplate: `EIP-7702 transactions are currently not supported.`,
2872+
websiteTitle: `EIP-7702 transactions are currently not supported`,
2873+
websiteDescription: `EIP-7702 transactions are currently not supported.`,
2874+
},
2875+
},
2876+
},
27852877
} as const;

v-next/hardhat-ledger/.gitignore

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Node modules
2+
/node_modules
3+
4+
# Compilation output
5+
/dist
6+
7+
# pnpm deploy output
8+
/bundle
9+
10+
# test coverage output
11+
coverage
12+
13+
# all the tmp folders in the fixture projects
14+
/test/fixture-projects/tmp/

0 commit comments

Comments
 (0)