@cofhe/hardhat-plugin 0.2.0 → 0.3.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/src/index.ts CHANGED
@@ -6,32 +6,25 @@ import { extendConfig, extendEnvironment, task, types } from 'hardhat/config';
6
6
  import { TASK_TEST, TASK_NODE } from 'hardhat/builtin-tasks/task-names';
7
7
  import { HardhatEthersSigner } from '@nomicfoundation/hardhat-ethers/signers';
8
8
  import {
9
+ type CofheClient,
10
+ type CofheConfig,
11
+ type CofheInputConfig,
9
12
  MOCKS_ZK_VERIFIER_SIGNER_ADDRESS,
10
- type CofhesdkClient,
11
- type CofhesdkConfig,
12
- type CofhesdkInputConfig,
13
13
  } from '@cofhe/sdk';
14
- import { createCofhesdkClient, createCofhesdkConfig } from '@cofhe/sdk/node';
14
+ import { createCofheClient, createCofheConfig } from '@cofhe/sdk/node';
15
15
  import { HardhatSignerAdapter } from '@cofhe/sdk/adapters';
16
16
 
17
17
  import { localcofheFundAccount } from './fund.js';
18
18
  import { TASK_COFHE_MOCKS_DEPLOY, TASK_COFHE_MOCKS_SET_LOG_OPS, TASK_COFHE_USE_FAUCET } from './consts.js';
19
19
  import { deployMocks, type DeployMocksArgs } from './deploy.js';
20
20
  import { mock_setLoggingEnabled, mock_withLogs } from './logging.js';
21
- import { mock_expectPlaintext } from './utils.js';
21
+ import { getFixedMockContract, mock_expectPlaintext } from './utils.js';
22
22
  import { mock_getPlaintext } from './utils.js';
23
23
  import type { Contract } from 'ethers';
24
- import {
25
- MockACLArtifact,
26
- MockQueryDecrypterArtifact,
27
- MockTaskManagerArtifact,
28
- MockZkVerifierArtifact,
29
- TestBedArtifact,
30
- } from '@cofhe/mock-contracts';
31
24
  import { hardhat } from '@cofhe/sdk/chains';
32
- export {
25
+ import {
33
26
  MockACLArtifact,
34
- MockQueryDecrypterArtifact,
27
+ MockThresholdNetworkArtifact,
35
28
  MockTaskManagerArtifact,
36
29
  MockZkVerifierArtifact,
37
30
  TestBedArtifact,
@@ -43,7 +36,7 @@ export {
43
36
  */
44
37
  declare module 'hardhat/types/config' {
45
38
  interface HardhatUserConfig {
46
- cofhesdk?: {
39
+ cofhe?: {
47
40
  /** Whether to log mock operations (default: true) */
48
41
  logMocks?: boolean;
49
42
  /** Whether to show gas usage warnings for mock operations (default: true) */
@@ -52,7 +45,7 @@ declare module 'hardhat/types/config' {
52
45
  }
53
46
 
54
47
  interface HardhatConfig {
55
- cofhesdk: {
48
+ cofhe: {
56
49
  /** Whether to log mock operations (default: true) */
57
50
  logMocks: boolean;
58
51
  /** Whether to show gas usage warnings for mock operations (default: true) */
@@ -112,9 +105,9 @@ extendConfig((config, userConfig) => {
112
105
  }
113
106
 
114
107
  // Add cofhe config
115
- config.cofhesdk = {
116
- logMocks: userConfig.cofhesdk?.logMocks ?? true,
117
- gasWarning: userConfig.cofhesdk?.gasWarning ?? true,
108
+ config.cofhe = {
109
+ logMocks: userConfig.cofhe?.logMocks ?? true,
110
+ gasWarning: userConfig.cofhe?.gasWarning ?? true,
118
111
  };
119
112
  });
120
113
 
@@ -155,24 +148,41 @@ task(TASK_COFHE_MOCKS_DEPLOY, 'Deploys the mock contracts on the Hardhat network
155
148
  .setAction(async ({ deployTestBed, silent }: DeployMocksArgs, hre) => {
156
149
  await deployMocks(hre, {
157
150
  deployTestBed: deployTestBed ?? true,
158
- gasWarning: hre.config.cofhesdk.gasWarning ?? true,
151
+ gasWarning: hre.config.cofhe.gasWarning ?? true,
159
152
  silent: silent ?? false,
160
153
  });
161
154
  });
162
155
 
156
+ // Hardhat plugin auto-deploys mocks for every hardhat test run by overriding TASK_TEST and calling deployMocks(...) before runSuper()
163
157
  task(TASK_TEST, 'Deploy mock contracts on hardhat').setAction(async ({}, hre, runSuper) => {
164
- await deployMocks(hre, {
165
- deployTestBed: true,
166
- gasWarning: hre.config.cofhesdk.gasWarning ?? true,
167
- });
158
+ const skipAutoDeploy = (() => {
159
+ const raw = process.env.COFHE_SKIP_MOCKS_DEPLOY ?? '';
160
+ const normalized = raw.trim().toLowerCase();
161
+ return normalized === '1' || normalized === 'true' || normalized === 'yes';
162
+ })();
163
+
164
+ if (!skipAutoDeploy) {
165
+ await deployMocks(hre, {
166
+ deployTestBed: true,
167
+ gasWarning: hre.config.cofhe.gasWarning ?? true,
168
+ });
169
+ }
168
170
  return runSuper();
169
171
  });
170
172
 
171
173
  task(TASK_NODE, 'Deploy mock contracts on hardhat').setAction(async ({}, hre, runSuper) => {
172
- await deployMocks(hre, {
173
- deployTestBed: true,
174
- gasWarning: hre.config.cofhesdk.gasWarning ?? true,
175
- });
174
+ const skipAutoDeploy = (() => {
175
+ const raw = process.env.COFHE_SKIP_MOCKS_DEPLOY ?? '';
176
+ const normalized = raw.trim().toLowerCase();
177
+ return normalized === '1' || normalized === 'true' || normalized === 'yes';
178
+ })();
179
+
180
+ if (!skipAutoDeploy) {
181
+ await deployMocks(hre, {
182
+ deployTestBed: true,
183
+ gasWarning: hre.config.cofhe.gasWarning ?? true,
184
+ });
185
+ }
176
186
  return runSuper();
177
187
  });
178
188
 
@@ -186,6 +196,7 @@ task(TASK_COFHE_MOCKS_SET_LOG_OPS, 'Set logging for the Mock CoFHE contracts')
186
196
 
187
197
  // MOCK UTILS
188
198
 
199
+ export * from './consts.js';
189
200
  export * from './utils.js';
190
201
  export * from './fund.js';
191
202
  export * from './logging.js';
@@ -197,21 +208,21 @@ export * from './deploy.js';
197
208
  */
198
209
  declare module 'hardhat/types/runtime' {
199
210
  export interface HardhatRuntimeEnvironment {
200
- cofhesdk: {
211
+ cofhe: {
201
212
  /**
202
- * Create a CoFHE SDK configuration for use with cofhesdk.createCofhesdkClient(...)
203
- * @param {CofhesdkInputConfig} config - The CoFHE SDK input configuration
204
- * @returns {CofhesdkConfig} The CoFHE SDK configuration
213
+ * Create a CoFHE configuration for use with hre.cofhe.createClient(...)
214
+ * @param {CofheInputConfig} config - The CoFHE input configuration
215
+ * @returns {CofheConfig} The CoFHE configuration
205
216
  */
206
- createCofhesdkConfig: (config: CofhesdkInputConfig) => Promise<CofhesdkConfig>;
217
+ createConfig: (config: CofheInputConfig) => Promise<CofheConfig>;
207
218
  /**
208
- * Create a CoFHE SDK client instance
209
- * @param {CofhesdkConfig} config - The CoFHE SDK configuration (use createCofhesdkConfig to create with Node.js defaults)
210
- * @returns {Promise<CofhesdkClient>} The CoFHE SDK client instance
219
+ * Create a CoFHE client instance
220
+ * @param {CofheConfig} config - The CoFHE configuration (use createCofheConfig to create with Node.js defaults)
221
+ * @returns {Promise<CofheClient>} The CoFHE client instance
211
222
  */
212
- createCofhesdkClient: (config: CofhesdkConfig) => CofhesdkClient;
223
+ createClient: (config: CofheConfig) => CofheClient;
213
224
  /**
214
- * Create viem clients from a Hardhat ethers signer, to be used with `cofhesdkClient.connect(...)`
225
+ * Create viem clients from a Hardhat ethers signer, to be used with `cofheClient.connect(...)`
215
226
  * @param {HardhatEthersSigner} signer - The Hardhat ethers signer to use
216
227
  * @returns {Promise<{ publicClient: PublicClient; walletClient: WalletClient }>} The viem clients
217
228
  */
@@ -219,20 +230,20 @@ declare module 'hardhat/types/runtime' {
219
230
  signer: HardhatEthersSigner
220
231
  ) => Promise<{ publicClient: PublicClient; walletClient: WalletClient }>;
221
232
  /**
222
- * Connect a CoFHE SDK client with a Hardhat ethers signer
223
- * @param {CofhesdkClient} client - The CoFHE SDK client to connect
233
+ * Connect a CoFHE client with a Hardhat ethers signer
234
+ * @param {CofheClient} client - The CoFHE client to connect
224
235
  * @param {HardhatEthersSigner} signer - The Hardhat ethers signer to use
225
236
  * @returns {Promise<void>}
226
237
  */
227
- connectWithHardhatSigner: (client: CofhesdkClient, signer: HardhatEthersSigner) => Promise<void>;
238
+ connectWithHardhatSigner: (client: CofheClient, signer: HardhatEthersSigner) => Promise<void>;
228
239
  /**
229
240
  * Create and connect to a batteries included client.
230
241
  * Also generates a self-usage a permit for the signer.
231
- * If customization is needed, use createCofhesdkClient and connectWithHardhatSigner.
242
+ * If customization is needed, use createCofheClient and connectWithHardhatSigner.
232
243
  * @param {HardhatEthersSigner} signer - The Hardhat ethers signer to use (optional - defaults to first signer)
233
- * @returns {Promise<CofhesdkClient>} The CoFHE SDK client instance
244
+ * @returns {Promise<CofheClient>} The CoFHE client instance
234
245
  */
235
- createBatteriesIncludedCofhesdkClient: (signer?: HardhatEthersSigner) => Promise<CofhesdkClient>;
246
+ createClientWithBatteries: (signer?: HardhatEthersSigner) => Promise<CofheClient>;
236
247
 
237
248
  mocks: {
238
249
  /**
@@ -245,7 +256,7 @@ declare module 'hardhat/types/runtime' {
245
256
  * Example usage:
246
257
  *
247
258
  * ```ts
248
- * await hre.cofhesdk.mocks.withLogs("counter.increment()", async () => {
259
+ * await hre.cofhe.mocks.withLogs("counter.increment()", async () => {
249
260
  * await counter.increment();
250
261
  * });
251
262
  * ```
@@ -319,10 +330,10 @@ declare module 'hardhat/types/runtime' {
319
330
  getMockACL: () => Promise<Contract>;
320
331
 
321
332
  /**
322
- * Get the MockQueryDecrypter contract
323
- * @returns {Promise<Contract>} The MockQueryDecrypter contract
333
+ * Get the MockThresholdNetwork contract
334
+ * @returns {Promise<Contract>} The MockThresholdNetwork contract
324
335
  */
325
- getMockQueryDecrypter: () => Promise<Contract>;
336
+ getMockThresholdNetwork: () => Promise<Contract>;
326
337
 
327
338
  /**
328
339
  * Get the MockZkVerifier contract
@@ -340,53 +351,69 @@ declare module 'hardhat/types/runtime' {
340
351
  }
341
352
  }
342
353
 
354
+ /**
355
+ * Builds the mocks config for the hardhat plugin.
356
+ * Defaults `encryptDelay` to `0` so tests run without artificial wait times,
357
+ * unless the user has explicitly provided a value.
358
+ */
359
+ export function buildHardhatPluginMocksConfig(
360
+ mocksConfig: CofheInputConfig['mocks']
361
+ ): NonNullable<CofheInputConfig['mocks']> {
362
+ return {
363
+ ...mocksConfig,
364
+ encryptDelay: mocksConfig?.encryptDelay ?? 0,
365
+ };
366
+ }
367
+
343
368
  extendEnvironment((hre) => {
344
- hre.cofhesdk = {
345
- createCofhesdkConfig: async (config: CofhesdkInputConfig) => {
369
+ hre.cofhe = {
370
+ createConfig: async (config: CofheInputConfig) => {
346
371
  // Create zkv wallet client
347
372
  // This wallet interacts with the MockZkVerifier contract so that the user's connected wallet doesn't have to
348
373
  const zkvHhSigner = await hre.ethers.getImpersonatedSigner(MOCKS_ZK_VERIFIER_SIGNER_ADDRESS);
349
374
  const { walletClient: zkvWalletClient } = await HardhatSignerAdapter(zkvHhSigner);
350
375
 
351
376
  // Inject zkv wallet client into config
377
+ // Set encryptDelay to 0 on hardhat to avoid waiting for delays during tests
352
378
  const configWithZkvWalletClient = {
353
379
  environment: 'hardhat' as const,
354
380
  ...config,
381
+ mocks: buildHardhatPluginMocksConfig(config.mocks),
355
382
  _internal: {
356
383
  ...config._internal,
357
384
  zkvWalletClient,
358
385
  },
359
386
  };
360
387
 
361
- return createCofhesdkConfig(configWithZkvWalletClient);
388
+ return createCofheConfig(configWithZkvWalletClient);
362
389
  },
363
- createCofhesdkClient: (config: CofhesdkConfig) => {
364
- return createCofhesdkClient(config);
390
+ createClient: (config: CofheConfig) => {
391
+ return createCofheClient(config);
365
392
  },
366
393
  hardhatSignerAdapter: async (signer: HardhatEthersSigner) => {
367
394
  return HardhatSignerAdapter(signer);
368
395
  },
369
- connectWithHardhatSigner: async (client: CofhesdkClient, signer: HardhatEthersSigner) => {
396
+ connectWithHardhatSigner: async (client: CofheClient, signer: HardhatEthersSigner) => {
370
397
  const { publicClient, walletClient } = await HardhatSignerAdapter(signer);
371
398
  return client.connect(publicClient, walletClient);
372
399
  },
373
- createBatteriesIncludedCofhesdkClient: async (signer?: HardhatEthersSigner) => {
400
+ createClientWithBatteries: async (signer?: HardhatEthersSigner) => {
374
401
  // Get signer if not provided
375
402
  if (!signer) {
376
403
  [signer] = await hre.ethers.getSigners();
377
404
  }
378
405
 
379
406
  // Create config
380
- const config = await hre.cofhesdk.createCofhesdkConfig({
407
+ const config = await hre.cofhe.createConfig({
381
408
  environment: 'hardhat',
382
409
  supportedChains: [hardhat],
383
410
  });
384
411
 
385
412
  // Create client
386
- const client = hre.cofhesdk.createCofhesdkClient(config);
413
+ const client = hre.cofhe.createClient(config);
387
414
 
388
415
  // Connect client
389
- await hre.cofhesdk.connectWithHardhatSigner(client, signer);
416
+ await hre.cofhe.connectWithHardhatSigner(client, signer);
390
417
 
391
418
  // Create self-usage permit
392
419
  await client.permits.createSelf({
@@ -417,23 +444,15 @@ extendEnvironment((hre) => {
417
444
  const [signer] = await hre.ethers.getSigners();
418
445
  return mock_expectPlaintext(signer.provider, ctHash, expectedValue);
419
446
  },
420
- getMockTaskManager: async () => {
421
- return await hre.ethers.getContractAt(MockTaskManagerArtifact.abi, MockTaskManagerArtifact.fixedAddress);
422
- },
447
+ getMockTaskManager: async () => getFixedMockContract(hre, MockTaskManagerArtifact),
423
448
  getMockACL: async () => {
424
- const tm = await hre.ethers.getContractAt(MockTaskManagerArtifact.abi, MockTaskManagerArtifact.fixedAddress);
425
- const aclAddress = await tm.acl();
426
- return await hre.ethers.getContractAt(MockACLArtifact.abi, aclAddress);
427
- },
428
- getMockQueryDecrypter: async () => {
429
- return await hre.ethers.getContractAt(MockQueryDecrypterArtifact.abi, MockQueryDecrypterArtifact.fixedAddress);
430
- },
431
- getMockZkVerifier: async () => {
432
- return await hre.ethers.getContractAt(MockZkVerifierArtifact.abi, MockZkVerifierArtifact.fixedAddress);
433
- },
434
- getTestBed: async () => {
435
- return await hre.ethers.getContractAt(TestBedArtifact.abi, TestBedArtifact.fixedAddress);
449
+ const taskManager = await getFixedMockContract(hre, MockTaskManagerArtifact);
450
+ const aclAddress = await taskManager.acl();
451
+ return hre.ethers.getContractAt(MockACLArtifact.abi, aclAddress);
436
452
  },
453
+ getMockThresholdNetwork: async () => getFixedMockContract(hre, MockThresholdNetworkArtifact),
454
+ getMockZkVerifier: async () => getFixedMockContract(hre, MockZkVerifierArtifact),
455
+ getTestBed: async () => getFixedMockContract(hre, TestBedArtifact),
437
456
  },
438
457
  };
439
458
  });
package/src/logging.ts CHANGED
@@ -1,23 +1,17 @@
1
1
  import chalk from 'chalk';
2
2
  import { type HardhatRuntimeEnvironment } from 'hardhat/types';
3
- import { TASK_MANAGER_ADDRESS } from './consts';
3
+ import { getFixedMockContract } from './utils';
4
4
  import { MockTaskManagerArtifact } from '@cofhe/mock-contracts';
5
5
 
6
- const getDeployedMockTaskManager = async (hre: HardhatRuntimeEnvironment) => {
7
- // Fetch the deployed MockTaskManager
8
- const taskManager = await hre.ethers.getContractAt(MockTaskManagerArtifact.abi, TASK_MANAGER_ADDRESS);
9
-
10
- return taskManager;
11
- };
12
-
13
- const getLoggingEnabled = async (hre: HardhatRuntimeEnvironment) => {
14
- const taskManager = await getDeployedMockTaskManager(hre);
15
- return await taskManager.logOps();
6
+ const getLoggingEnabled = async (hre: HardhatRuntimeEnvironment): Promise<boolean> => {
7
+ const taskManager = await getFixedMockContract(hre, MockTaskManagerArtifact);
8
+ return taskManager.logOps();
16
9
  };
17
10
 
18
11
  const setLoggingEnabled = async (hre: HardhatRuntimeEnvironment, enabled: boolean) => {
19
- const taskManager = await getDeployedMockTaskManager(hre);
20
- await taskManager.setLogOps(enabled);
12
+ const taskManager = await getFixedMockContract(hre, MockTaskManagerArtifact);
13
+ const tx = await taskManager.setLogOps(enabled);
14
+ await tx.wait();
21
15
  };
22
16
 
23
17
  // prettier-ignore
package/src/utils.ts CHANGED
@@ -1,7 +1,38 @@
1
- import { TASK_MANAGER_ADDRESS, MOCKS_ZK_VERIFIER_ADDRESS } from './consts.js';
1
+ import { TASK_MANAGER_ADDRESS, MOCKS_ZK_VERIFIER_ADDRESS } from '@cofhe/sdk';
2
2
  import { expect } from 'chai';
3
- import { ethers } from 'ethers';
3
+ import { Contract, ethers } from 'ethers';
4
4
  import { type HardhatEthersProvider } from '@nomicfoundation/hardhat-ethers/internal/hardhat-ethers-provider';
5
+ import type { MockArtifact } from '@cofhe/mock-contracts';
6
+ import type { HardhatRuntimeEnvironment } from 'hardhat/types';
7
+
8
+ // Deployment utils
9
+
10
+ /// Deploys a mock contract from a pre-built artifact from the mock-contracts package
11
+ /// If the mock contract should be deployed to a fixed address, `hardhat_setCode` op is used to set the code at the fixed address
12
+ /// Otherwise, we deploy the contract using ethers.js to a non-fixed address
13
+ export const deployMockContractFromArtifact = async (hre: HardhatRuntimeEnvironment, artifact: MockArtifact) => {
14
+ // Use hardhat_setCode to deploy to fixed address
15
+ if (artifact.isFixed) {
16
+ await hre.network.provider.send('hardhat_setCode', [artifact.fixedAddress, artifact.deployedBytecode]);
17
+ return getFixedMockContract(hre, artifact);
18
+ }
19
+
20
+ // Use ethers.js to deploy to variable address
21
+ const [signer] = await hre.ethers.getSigners();
22
+ const factory = new hre.ethers.ContractFactory(artifact.abi, artifact.bytecode, signer);
23
+ const contract = await factory.deploy(/* constructor args */);
24
+ await contract.waitForDeployment();
25
+ return contract as Contract;
26
+ };
27
+
28
+ export const getFixedMockContract = async (hre: HardhatRuntimeEnvironment, artifact: MockArtifact) => {
29
+ if (!artifact.isFixed) {
30
+ throw new Error('Artifact is not fixed');
31
+ }
32
+ return await hre.ethers.getContractAt(artifact.abi, artifact.fixedAddress);
33
+ };
34
+
35
+ // Testing utils
5
36
 
6
37
  const mock_checkIsTestnet = async (fnName: string, provider: HardhatEthersProvider | ethers.JsonRpcProvider) => {
7
38
  // Testnet is checked by testing if MockZkVerifier is deployed