@cofhe/hardhat-3-plugin 0.7.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -2,7 +2,7 @@ import { HardhatPlugin } from 'hardhat/types/plugins';
2
2
  import { PublicClient, WalletClient } from 'viem';
3
3
  import { CofheInputConfig, CofheConfig, CofheClient } from '@cofhe/sdk';
4
4
  import { ArtifactManager } from 'hardhat/types/artifacts';
5
- import { MockTaskManagerArtifact, MockACLArtifact, MockZkVerifierArtifact, MockThresholdNetworkArtifact } from '@cofhe/mock-contracts';
5
+ import { MockCoFHEAddressBookArtifact, MockTaskManagerArtifact, MockACLArtifact, MockZkVerifierArtifact, MockThresholdNetworkArtifact } from '@cofhe/mock-contracts';
6
6
 
7
7
  /**
8
8
  * Controls deploy-mocks console output.
@@ -13,6 +13,7 @@ import { MockTaskManagerArtifact, MockACLArtifact, MockZkVerifierArtifact, MockT
13
13
  type LogMocksDeploy = '' | 'v' | 'vv';
14
14
  /** Keyed map of deployed mock contract addresses returned by `deployMocks`. */
15
15
  type DeployedMockContracts = {
16
+ MockCoFHEAddressBook: `0x${string}`;
16
17
  MockTaskManager: `0x${string}`;
17
18
  MockACL: `0x${string}`;
18
19
  ACPTimestampRevoker: `0x${string}`;
@@ -31,6 +32,47 @@ type DeployContext = {
31
32
  };
32
33
  declare function deployMocks(ctx: DeployContext, options?: DeployMocksArgs): Promise<DeployedMockContracts>;
33
34
 
35
+ declare const MOCK_GAS_CONSUMED_EVENT: {
36
+ readonly name: "MockGasConsumed";
37
+ readonly type: "event";
38
+ readonly inputs: readonly [{
39
+ readonly type: "uint256";
40
+ readonly name: "gas";
41
+ }];
42
+ };
43
+ declare const MOCK_GAS_CONSUMED_TOPIC: `0x${string}`;
44
+ type AdjustableGasReceipt = {
45
+ gasUsed: bigint | number | string;
46
+ logs?: ReadonlyArray<{
47
+ address: string;
48
+ topics: ReadonlyArray<string>;
49
+ data: string;
50
+ }>;
51
+ };
52
+ type AdjustedGasBreakdown = {
53
+ /** Raw gas used by the transaction (includes mock overhead). */
54
+ gasUsed: bigint;
55
+ /** Gas consumed by mock-only work (FHE op replication, decrypt-task storage, mock logging). */
56
+ mockGas: bigint;
57
+ /** gasUsed - mockGas: an estimate of what the transaction would cost on a real CoFHE network. */
58
+ adjustedGasUsed: bigint;
59
+ /** Number of MockGasConsumed events - roughly the number of mock-only blocks executed. */
60
+ mockGasEvents: number;
61
+ };
62
+ declare const mock_getAdjustedGasBreakdown: (receipt: AdjustableGasReceipt) => AdjustedGasBreakdown;
63
+ declare const mock_getAdjustedGasUsed: (receipt: AdjustableGasReceipt) => bigint;
64
+ type MockGasSummaryRow = {
65
+ contract: string;
66
+ method: string;
67
+ calls: number;
68
+ totalGasUsed: string;
69
+ totalMockGas: string;
70
+ };
71
+ declare const collectMockGasRows: (publicClient: PublicClient, artifacts: ArtifactManager, fromBlock?: bigint) => Promise<MockGasSummaryRow[]>;
72
+ declare const registerGasSummaryConnection: (publicClient: PublicClient, artifacts: ArtifactManager, cacheDir: string, fromBlock: bigint) => void;
73
+ declare const cleanGasSummaryDir: (cacheDir: string) => void;
74
+ declare const printMockGasSummaryFromDir: (cacheDir: string) => void;
75
+
34
76
  interface CofheConnection {
35
77
  /**
36
78
  * Create a CoFHE configuration. Defaults to hardhat environment;
@@ -45,6 +87,20 @@ interface CofheConnection {
45
87
  * first account from the connection is used automatically.
46
88
  */
47
89
  createClientWithBatteries(walletClient?: WalletClient): Promise<CofheClient>;
90
+ /**
91
+ * Returns a transaction's gas usage excluding mock-only overhead (FHE op replication,
92
+ * decrypt-task storage, mock logging) - an estimate of what the transaction would cost
93
+ * on a real CoFHE network. Pure function of the receipt (sums the mock task manager's
94
+ * MockGasConsumed events from `receipt.logs`); on a real network the receipt carries no
95
+ * such events and the raw `gasUsed` is returned unchanged.
96
+ */
97
+ getAdjustedGasUsed(receipt: AdjustableGasReceipt): bigint;
98
+ /**
99
+ * Full gas breakdown of a transaction receipt: raw `gasUsed`, the mock-only `mockGas`,
100
+ * the `adjustedGasUsed` (raw minus mock), and the number of mock gas events.
101
+ * See getAdjustedGasUsed.
102
+ */
103
+ getAdjustedGasBreakdown(receipt: AdjustableGasReceipt): AdjustedGasBreakdown;
48
104
  mocks: {
49
105
  /** Deploy (or re-deploy) the mock contracts. */
50
106
  deployMocks(options?: DeployMocksArgs): Promise<void>;
@@ -58,6 +114,11 @@ interface CofheConnection {
58
114
  getPlaintext(ctHash: bigint | string): Promise<bigint>;
59
115
  /** Assert that a ciphertext hash represents the expected plaintext value. */
60
116
  expectPlaintext(ctHash: bigint | string, expectedValue: bigint): Promise<void>;
117
+ /** MockCoFHEAddressBook contract descriptor — spread into readContract / writeContract */
118
+ MockCoFHEAddressBook: {
119
+ address: `0x${string}`;
120
+ abi: typeof MockCoFHEAddressBookArtifact.abi;
121
+ };
61
122
  /** MockTaskManager contract descriptor — spread into readContract / writeContract */
62
123
  MockTaskManager: {
63
124
  address: `0x${string}`;
@@ -87,6 +148,14 @@ declare module 'hardhat/types/config' {
87
148
  logMocks?: boolean;
88
149
  /** Whether to show gas usage warnings for mock operations (default: true) */
89
150
  gasWarning?: boolean;
151
+ /**
152
+ * Print a per-method gas summary after `hardhat test`, showing raw gas next to
153
+ * adjusted gas (mock-only overhead excluded - an estimate of real-network cost).
154
+ * Collected per test worker from chain history: transactions rolled back by
155
+ * snapshots won't appear, and the table is best-effort after forced exits -
156
+ * use getAdjustedGasUsed(receipt) for exact numbers. (default: false)
157
+ */
158
+ gasSummary?: boolean;
90
159
  /**
91
160
  * Controls deploy-mocks console output.
92
161
  * - `''` — silent, no output
@@ -100,6 +169,8 @@ declare module 'hardhat/types/config' {
100
169
  cofhe: {
101
170
  logMocks: boolean;
102
171
  gasWarning: boolean;
172
+ /** Print a per-method adjusted-gas summary after `hardhat test` (default: false) */
173
+ gasSummary: boolean;
103
174
  mocksDeployVerbosity: LogMocksDeploy;
104
175
  };
105
176
  }
@@ -148,4 +219,4 @@ declare function mock_expectPlaintext(publicClient: PublicClient, ctHash: bigint
148
219
 
149
220
  declare const plugin: HardhatPlugin;
150
221
 
151
- export { type DeployContext, type DeployMocksArgs, type DeployedMockContracts, type LogMocksDeploy, TASK_COFHE_SET_LOG_OPS, TASK_COFHE_USE_FAUCET, plugin as default, deployMocks, getMockContractsNpmPaths, localcofheFundAccount, localcofheFundWalletIfNeeded, mock_expectPlaintext, mock_getPlaintext, mock_setLoggingEnabled, mock_withLogs };
222
+ export { type AdjustableGasReceipt, type AdjustedGasBreakdown, type DeployContext, type DeployMocksArgs, type DeployedMockContracts, type LogMocksDeploy, MOCK_GAS_CONSUMED_EVENT, MOCK_GAS_CONSUMED_TOPIC, type MockGasSummaryRow, TASK_COFHE_SET_LOG_OPS, TASK_COFHE_USE_FAUCET, cleanGasSummaryDir, collectMockGasRows, plugin as default, deployMocks, getMockContractsNpmPaths, localcofheFundAccount, localcofheFundWalletIfNeeded, mock_expectPlaintext, mock_getAdjustedGasBreakdown, mock_getAdjustedGasUsed, mock_getPlaintext, mock_setLoggingEnabled, mock_withLogs, printMockGasSummaryFromDir, registerGasSummaryConnection };
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  getMockContractsNpmPaths,
4
4
  mock_expectPlaintext,
5
5
  mock_getPlaintext
6
- } from "./chunk-E7DR6EGV.js";
6
+ } from "./chunk-FDCRLC5K.js";
7
7
  import {
8
8
  localcofheFundAccount,
9
9
  localcofheFundWalletIfNeeded
@@ -11,10 +11,20 @@ import {
11
11
  import {
12
12
  mock_setLoggingEnabled,
13
13
  mock_withLogs
14
- } from "./chunk-IVRNGFNF.js";
14
+ } from "./chunk-NYXXHYHW.js";
15
+ import {
16
+ MOCK_GAS_CONSUMED_EVENT,
17
+ MOCK_GAS_CONSUMED_TOPIC,
18
+ cleanGasSummaryDir,
19
+ collectMockGasRows,
20
+ mock_getAdjustedGasBreakdown,
21
+ mock_getAdjustedGasUsed,
22
+ printMockGasSummaryFromDir,
23
+ registerGasSummaryConnection
24
+ } from "./chunk-6G2MCXNM.js";
15
25
 
16
26
  // src/index.ts
17
- import { task } from "hardhat/config";
27
+ import { overrideTask, task } from "hardhat/config";
18
28
  import { ArgumentType } from "hardhat/types/arguments";
19
29
 
20
30
  // src/consts.ts
@@ -25,8 +35,8 @@ var TASK_COFHE_SET_LOG_OPS = "cofhe:set-log-ops";
25
35
  var plugin = {
26
36
  id: "@cofhe/hardhat-3-plugin",
27
37
  hookHandlers: {
28
- config: async () => import("./config-YK3LB5IH.js"),
29
- hre: async () => import("./hre-CYH6NXPG.js")
38
+ config: async () => import("./config-VUCAYBHC.js"),
39
+ hre: async () => import("./hre-T3TPXWIY.js")
30
40
  },
31
41
  tasks: [
32
42
  task(TASK_COFHE_USE_FAUCET, "Fund an account via the localcofhe faucet").addOption({
@@ -35,20 +45,30 @@ var plugin = {
35
45
  type: ArgumentType.STRING_WITHOUT_DEFAULT,
36
46
  defaultValue: void 0
37
47
  }).setAction(async () => import("./use-faucet-O732FNWJ.js")).build(),
38
- task(TASK_COFHE_SET_LOG_OPS, "Enable or disable CoFHE mock contract logging").addFlag({ name: "enable", description: "Whether to enable logging" }).setAction(async () => import("./set-log-ops-GVEQWMZP.js")).build()
48
+ task(TASK_COFHE_SET_LOG_OPS, "Enable or disable CoFHE mock contract logging").addFlag({ name: "enable", description: "Whether to enable logging" }).setAction(async () => import("./set-log-ops-2OIBBSDL.js")).build(),
49
+ // Prints the adjusted-gas summary after `hardhat test` when cofhe.gasSummary is enabled.
50
+ overrideTask("test").setAction(async () => import("./test-gas-summary-WK6CULNO.js")).build()
39
51
  ]
40
52
  };
41
53
  var index_default = plugin;
42
54
  export {
55
+ MOCK_GAS_CONSUMED_EVENT,
56
+ MOCK_GAS_CONSUMED_TOPIC,
43
57
  TASK_COFHE_SET_LOG_OPS,
44
58
  TASK_COFHE_USE_FAUCET,
59
+ cleanGasSummaryDir,
60
+ collectMockGasRows,
45
61
  index_default as default,
46
62
  deployMocks,
47
63
  getMockContractsNpmPaths,
48
64
  localcofheFundAccount,
49
65
  localcofheFundWalletIfNeeded,
50
66
  mock_expectPlaintext,
67
+ mock_getAdjustedGasBreakdown,
68
+ mock_getAdjustedGasUsed,
51
69
  mock_getPlaintext,
52
70
  mock_setLoggingEnabled,
53
- mock_withLogs
71
+ mock_withLogs,
72
+ printMockGasSummaryFromDir,
73
+ registerGasSummaryConnection
54
74
  };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  mock_setLoggingEnabled
3
- } from "./chunk-IVRNGFNF.js";
3
+ } from "./chunk-NYXXHYHW.js";
4
4
 
5
5
  // src/tasks/set-log-ops.ts
6
6
  import { createPublicClient, createWalletClient, custom } from "viem";
@@ -0,0 +1,19 @@
1
+ import {
2
+ cleanGasSummaryDir,
3
+ printMockGasSummaryFromDir
4
+ } from "./chunk-6G2MCXNM.js";
5
+
6
+ // src/tasks/test-gas-summary.ts
7
+ var action = async (args, hre, runSuper) => {
8
+ if (!hre.config.cofhe.gasSummary) {
9
+ return runSuper(args);
10
+ }
11
+ cleanGasSummaryDir(hre.config.paths.cache);
12
+ const result = await runSuper(args);
13
+ printMockGasSummaryFromDir(hre.config.paths.cache);
14
+ return result;
15
+ };
16
+ var test_gas_summary_default = action;
17
+ export {
18
+ test_gas_summary_default as default
19
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cofhe/hardhat-3-plugin",
3
- "version": "0.7.0",
3
+ "version": "0.8.0",
4
4
  "description": "Hardhat 3 plugin for CoFHE — deploys mock contracts and wires up the hre.cofhe interface",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -28,8 +28,8 @@
28
28
  "dependencies": {
29
29
  "chalk": "4.1.2",
30
30
  "viem": "2.38.6",
31
- "@cofhe/mock-contracts": "0.7.0",
32
- "@cofhe/sdk": "0.7.0"
31
+ "@cofhe/mock-contracts": "0.8.0",
32
+ "@cofhe/sdk": "0.8.0"
33
33
  },
34
34
  "devDependencies": {
35
35
  "@types/node": "20.19.15",
package/src/config.ts CHANGED
@@ -59,6 +59,7 @@ export function resolvePluginConfig(userConfig: HardhatUserConfig, resolvedConfi
59
59
  resolvedConfig.cofhe = {
60
60
  logMocks: userConfig.cofhe?.logMocks ?? false,
61
61
  gasWarning: userConfig.cofhe?.gasWarning ?? false,
62
+ gasSummary: userConfig.cofhe?.gasSummary ?? false,
62
63
  mocksDeployVerbosity: (userConfig.cofhe?.mocksDeployVerbosity ?? 'v') as LogMocksDeploy,
63
64
  };
64
65
  }
package/src/deploy.ts CHANGED
@@ -4,9 +4,16 @@ import { createTestClient, custom } from 'viem';
4
4
  import chalk from 'chalk';
5
5
  import { privateKeyToAccount } from 'viem/accounts';
6
6
 
7
- import { MockACLArtifact, MockTaskManagerArtifact, MockThresholdNetworkArtifact } from '@cofhe/mock-contracts';
8
7
  import {
9
- TASK_MANAGER_ADDRESS,
8
+ MockACLArtifact,
9
+ MockCoFHEAddressBookArtifact,
10
+ MockTaskManagerArtifact,
11
+ MockThresholdNetworkArtifact,
12
+ } from '@cofhe/mock-contracts';
13
+ import {
14
+ COFHE_ADDRESS_BOOK_ADDRESS,
15
+ TASK_MANAGER_ID,
16
+ MOCKS_TASK_MANAGER_ADDRESS,
10
17
  MOCKS_ZK_VERIFIER_ADDRESS,
11
18
  MOCKS_ZK_VERIFIER_SIGNER_ADDRESS,
12
19
  MOCKS_ZK_VERIFIER_SIGNER_PRIVATE_KEY,
@@ -24,6 +31,7 @@ export type LogMocksDeploy = '' | 'v' | 'vv';
24
31
 
25
32
  /** Keyed map of deployed mock contract addresses returned by `deployMocks`. */
26
33
  export type DeployedMockContracts = {
34
+ MockCoFHEAddressBook: `0x${string}`;
27
35
  MockTaskManager: `0x${string}`;
28
36
  MockACL: `0x${string}`;
29
37
  ACPTimestampRevoker: `0x${string}`;
@@ -71,14 +79,18 @@ export async function deployMocks(ctx: DeployContext, options: DeployMocksArgs =
71
79
 
72
80
  log('vv', chalk.bold('cofhe-hardhat-3-plugin :: deploy mocks'), 0);
73
81
 
82
+ // 0. Deploy CoFHEAddressBook to the address FHE.sol resolves the TaskManager through
83
+ await deployFixed(ctx.publicClient, 'MockCoFHEAddressBook', COFHE_ADDRESS_BOOK_ADDRESS, ctx.artifacts);
84
+ logDeployment('MockCoFHEAddressBook', COFHE_ADDRESS_BOOK_ADDRESS);
85
+
74
86
  // 1. Deploy TaskManager to its fixed address
75
- await deployFixed(ctx.publicClient, 'MockTaskManager', TASK_MANAGER_ADDRESS, ctx.artifacts);
76
- logDeployment('MockTaskManager', TASK_MANAGER_ADDRESS);
87
+ await deployFixed(ctx.publicClient, 'MockTaskManager', MOCKS_TASK_MANAGER_ADDRESS, ctx.artifacts);
88
+ logDeployment('MockTaskManager', MOCKS_TASK_MANAGER_ADDRESS);
77
89
 
78
90
  // 2. Initialize TaskManager — owner = first connected account
79
91
  const [account] = await ctx.walletClient.getAddresses();
80
92
  await ctx.walletClient.writeContract({
81
- address: TASK_MANAGER_ADDRESS,
93
+ address: MOCKS_TASK_MANAGER_ADDRESS,
82
94
  abi: MockTaskManagerArtifact.abi,
83
95
  functionName: 'initialize',
84
96
  args: [account],
@@ -86,9 +98,20 @@ export async function deployMocks(ctx: DeployContext, options: DeployMocksArgs =
86
98
  chain: null,
87
99
  });
88
100
 
101
+ // 2b. Register TaskManager in the CoFHEAddressBook
102
+ await ctx.walletClient.writeContract({
103
+ address: COFHE_ADDRESS_BOOK_ADDRESS,
104
+ abi: MockCoFHEAddressBookArtifact.abi,
105
+ functionName: 'setTm',
106
+ args: [TASK_MANAGER_ID, MOCKS_TASK_MANAGER_ADDRESS],
107
+ account,
108
+ chain: null,
109
+ });
110
+ log('vv', 'TaskManager registered in CoFHEAddressBook', 2);
111
+
89
112
  // 3. Configure security zones
90
113
  await ctx.walletClient.writeContract({
91
- address: TASK_MANAGER_ADDRESS,
114
+ address: MOCKS_TASK_MANAGER_ADDRESS,
92
115
  abi: MockTaskManagerArtifact.abi,
93
116
  functionName: 'setSecurityZones',
94
117
  args: [0, 1],
@@ -102,7 +125,7 @@ export async function deployMocks(ctx: DeployContext, options: DeployMocksArgs =
102
125
 
103
126
  // 5. Link ACL into TaskManager
104
127
  await ctx.walletClient.writeContract({
105
- address: TASK_MANAGER_ADDRESS,
128
+ address: MOCKS_TASK_MANAGER_ADDRESS,
106
129
  abi: MockTaskManagerArtifact.abi,
107
130
  functionName: 'setACLContract',
108
131
  args: [aclAddress],
@@ -111,6 +134,17 @@ export async function deployMocks(ctx: DeployContext, options: DeployMocksArgs =
111
134
  });
112
135
  log('vv', 'ACL address set in TaskManager', 2);
113
136
 
137
+ // 5a. Link TaskManager into ACL
138
+ await ctx.walletClient.writeContract({
139
+ address: aclAddress,
140
+ abi: MockACLArtifact.abi,
141
+ functionName: 'setTaskManager',
142
+ args: [MOCKS_TASK_MANAGER_ADDRESS],
143
+ account,
144
+ chain: null,
145
+ });
146
+ log('vv', 'TaskManager address set in ACL', 2);
147
+
114
148
  // 5b. ACP (ACP V3): default revoker (verification is inherited by the ACL)
115
149
  const acpRevokerAddress = await deployVariable(ctx, 'ACPTimestampRevoker', []);
116
150
  logDeployment('ACPTimestampRevoker', acpRevokerAddress);
@@ -140,7 +174,7 @@ export async function deployMocks(ctx: DeployContext, options: DeployMocksArgs =
140
174
  // 6. Set ZkVerifier signer (the key is well-known and shared with the SDK)
141
175
  const verifierSigner = privateKeyToAccount(MOCKS_ZK_VERIFIER_SIGNER_PRIVATE_KEY);
142
176
  await ctx.walletClient.writeContract({
143
- address: TASK_MANAGER_ADDRESS,
177
+ address: MOCKS_TASK_MANAGER_ADDRESS,
144
178
  abi: MockTaskManagerArtifact.abi,
145
179
  functionName: 'setVerifierSigner',
146
180
  args: [verifierSigner.address],
@@ -152,7 +186,7 @@ export async function deployMocks(ctx: DeployContext, options: DeployMocksArgs =
152
186
  // 7. Set decrypt result signer
153
187
  const decryptSigner = privateKeyToAccount(MOCKS_DECRYPT_RESULT_SIGNER_PRIVATE_KEY);
154
188
  await ctx.walletClient.writeContract({
155
- address: TASK_MANAGER_ADDRESS,
189
+ address: MOCKS_TASK_MANAGER_ADDRESS,
156
190
  abi: MockTaskManagerArtifact.abi,
157
191
  functionName: 'setDecryptResultSigner',
158
192
  args: [decryptSigner.address],
@@ -187,7 +221,7 @@ export async function deployMocks(ctx: DeployContext, options: DeployMocksArgs =
187
221
  address: MockThresholdNetworkArtifact.fixedAddress as `0x${string}`,
188
222
  abi: MockThresholdNetworkArtifact.abi,
189
223
  functionName: 'initialize',
190
- args: [TASK_MANAGER_ADDRESS, aclAddress],
224
+ args: [MOCKS_TASK_MANAGER_ADDRESS, aclAddress],
191
225
  account,
192
226
  chain: null,
193
227
  });
@@ -197,8 +231,8 @@ export async function deployMocks(ctx: DeployContext, options: DeployMocksArgs =
197
231
  if (gasWarning) {
198
232
  logEmpty('v');
199
233
  logWarning(
200
- 'When using mocks, FHE operations report a higher gas price due to on-chain mocking logic. ' +
201
- 'Deploy your contracts on a testnet to check true gas costs.\n' +
234
+ 'When using mocks, FHE operations consume extra gas replicating off-chain CoFHE work on-chain. ' +
235
+ "Use conn.cofhe.getAdjustedGasUsed(receipt) or set 'cofhe.gasSummary: true' to see gas numbers with that overhead excluded.\n" +
202
236
  "(Disable this warning by setting 'cofhe.gasWarning: false' in your Hardhat config)",
203
237
  0
204
238
  );
@@ -207,7 +241,8 @@ export async function deployMocks(ctx: DeployContext, options: DeployMocksArgs =
207
241
  logEmpty('v');
208
242
 
209
243
  return {
210
- MockTaskManager: TASK_MANAGER_ADDRESS,
244
+ MockCoFHEAddressBook: COFHE_ADDRESS_BOOK_ADDRESS,
245
+ MockTaskManager: MOCKS_TASK_MANAGER_ADDRESS,
211
246
  MockACL: aclAddress,
212
247
  ACPTimestampRevoker: acpRevokerAddress,
213
248
  ACPShareRegistry: acpShareRegistryAddress,