Skip to content

Commit b0cd0ae

Browse files
Merge pull request #351 from BitGo/CGARD-454-fix-hpp-estimate-gas
fix: normalize eth_estimateGas for Hardhat on hpp
2 parents 70f5e6a + 616c00e commit b0cd0ae

2 files changed

Lines changed: 71 additions & 0 deletions

File tree

config/hppHardhatEstimateGasFix.ts

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/**
2+
* HPP mainnet RPC returns "contract creation code storage out of gas" for eth_estimateGas when
3+
* the request includes gasLimit / fee fields from Hardhat+ethers deploy tx shaping.
4+
* Strip those fields at the provider layer for HPP mainnet only (matches minimal curl).
5+
* hardhat-ethers uses provider.send("eth_estimateGas", [...]), not request().
6+
*/
7+
import { extendEnvironment } from 'hardhat/config';
8+
9+
/** Hardhat network name for HPP mainnet only (`thpp` testnet does not need this). */
10+
const HPP_MAINNET_HARDHAT_NETWORK = 'hpp';
11+
12+
function stripGasFieldsFromEstimateTx(
13+
tx: Record<string, unknown>
14+
): Record<string, unknown> {
15+
const out = { ...tx };
16+
delete out.gas;
17+
delete out.gasLimit;
18+
delete out.gasPrice;
19+
delete out.maxFeePerGas;
20+
delete out.maxPriorityFeePerGas;
21+
delete out.type;
22+
return out;
23+
}
24+
25+
extendEnvironment((hre) => {
26+
if (hre.network.name !== HPP_MAINNET_HARDHAT_NETWORK) {
27+
return;
28+
}
29+
const provider = hre.network.provider as {
30+
request(args: { method: string; params?: unknown[] }): Promise<unknown>;
31+
send(method: string, params?: unknown[]): Promise<unknown>;
32+
};
33+
34+
const origSend = provider.send.bind(provider);
35+
provider.send = async (method: string, params?: unknown[]) => {
36+
if (
37+
method === 'eth_estimateGas' &&
38+
Array.isArray(params) &&
39+
params[0] !== null &&
40+
typeof params[0] === 'object' &&
41+
!Array.isArray(params[0])
42+
) {
43+
const tx = stripGasFieldsFromEstimateTx(
44+
params[0] as Record<string, unknown>
45+
);
46+
return origSend(method, [tx, ...params.slice(1)]);
47+
}
48+
return origSend(method, params);
49+
};
50+
51+
const origRequest = provider.request.bind(provider);
52+
provider.request = async (args) => {
53+
if (
54+
args.method === 'eth_estimateGas' &&
55+
Array.isArray(args.params) &&
56+
args.params[0] !== null &&
57+
typeof args.params[0] === 'object' &&
58+
!Array.isArray(args.params[0])
59+
) {
60+
const tx = stripGasFieldsFromEstimateTx(
61+
args.params[0] as Record<string, unknown>
62+
);
63+
return origRequest({
64+
...args,
65+
params: [tx, ...args.params.slice(1)]
66+
});
67+
}
68+
return origRequest(args);
69+
};
70+
});

hardhat.config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import * as dotenv from 'dotenv';
22
dotenv.config();
3+
import './config/hppHardhatEstimateGasFix';
34
import { HardhatUserConfig } from 'hardhat/config';
45
import '@nomicfoundation/hardhat-toolbox';
56
import '@nomicfoundation/hardhat-verify';

0 commit comments

Comments
 (0)