@cofhe/sdk 0.6.0 → 0.7.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.
Files changed (114) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/acps/acp.ts +411 -0
  3. package/acps/index.ts +70 -0
  4. package/{permits → acps}/onchain-utils.ts +49 -24
  5. package/acps/sealing.ts +90 -0
  6. package/acps/signature.ts +89 -0
  7. package/acps/store.ts +172 -0
  8. package/acps/test/acp.test.ts +615 -0
  9. package/acps/test/localstorage.test.ts +105 -0
  10. package/acps/test/sealing.test.ts +77 -0
  11. package/acps/test/store.test.ts +88 -0
  12. package/acps/test/validation.test.ts +361 -0
  13. package/acps/test-utils.ts +32 -0
  14. package/acps/types.ts +252 -0
  15. package/acps/validation.ts +392 -0
  16. package/adapters/test/ethers5.test.ts +4 -1
  17. package/adapters/test/ethers6.test.ts +4 -1
  18. package/adapters/test/wagmi.test.ts +5 -2
  19. package/chains/chains/stagingCofhe.ts +21 -0
  20. package/chains/index.ts +3 -1
  21. package/chains/test/chains.test.ts +2 -1
  22. package/core/acps.ts +625 -0
  23. package/core/client.ts +136 -39
  24. package/core/clientTypes.ts +52 -41
  25. package/core/config.ts +66 -5
  26. package/core/debug.ts +72 -0
  27. package/core/decrypt/MockThresholdNetworkAbi.ts +20 -11
  28. package/core/decrypt/apiError.ts +104 -0
  29. package/core/decrypt/cofheMocksDecryptForTx.ts +11 -11
  30. package/core/decrypt/cofheMocksDecryptForView.ts +7 -7
  31. package/core/decrypt/decryptForTxBuilder.ts +102 -102
  32. package/core/decrypt/decryptForViewBuilder.ts +90 -90
  33. package/core/decrypt/submitRetry.ts +38 -30
  34. package/core/decrypt/tnDecryptV1.ts +5 -5
  35. package/core/decrypt/tnDecryptV2.ts +45 -34
  36. package/core/decrypt/tnSealOutputV1.ts +4 -3
  37. package/core/decrypt/tnSealOutputV2.ts +44 -31
  38. package/core/encrypt/cofheMocksZkVerifySign.ts +59 -74
  39. package/core/encrypt/encryptInputsBuilder.ts +86 -52
  40. package/core/encrypt/zkPackProveVerify.ts +25 -18
  41. package/core/error.ts +34 -6
  42. package/core/index.ts +14 -14
  43. package/core/test/acpDefaults.test.ts +52 -0
  44. package/core/test/acps.test.ts +596 -0
  45. package/core/test/apiError.test.ts +130 -0
  46. package/core/test/client.test.ts +22 -19
  47. package/core/test/config.test.ts +25 -5
  48. package/core/test/decrypt.test.ts +40 -35
  49. package/core/test/decryptBuilders.test.ts +68 -68
  50. package/core/test/decryptErrorCodes.test.ts +217 -0
  51. package/core/test/encryptInputsBuilder.test.ts +72 -41
  52. package/core/test/pollCallbacks.test.ts +89 -18
  53. package/core/test/stagingRedirect.ts +18 -0
  54. package/core/test/submitRetry.test.ts +182 -0
  55. package/core/types.ts +9 -69
  56. package/dist/acp-Wi6isVQI.d.cts +407 -0
  57. package/dist/acp-Wi6isVQI.d.ts +407 -0
  58. package/dist/acps.cjs +1081 -0
  59. package/dist/acps.d.cts +480 -0
  60. package/dist/acps.d.ts +480 -0
  61. package/dist/acps.js +2 -0
  62. package/dist/chains.cjs +14 -1
  63. package/dist/chains.d.cts +30 -1
  64. package/dist/chains.d.ts +30 -1
  65. package/dist/chains.js +1 -1
  66. package/dist/{chunk-PE5V5CCV.js → chunk-43USWPEH.js} +1000 -604
  67. package/dist/{chunk-MTRAXQXC.js → chunk-N6IDQRRU.js} +14 -2
  68. package/dist/chunk-Q7CBWGQX.js +1029 -0
  69. package/dist/{clientTypes-CyUvRRzA.d.ts → clientTypes-BN3nbzYM.d.ts} +342 -165
  70. package/dist/{clientTypes-BDy1qIBu.d.cts → clientTypes-CYZjFznO.d.cts} +342 -165
  71. package/dist/core.cjs +1431 -1026
  72. package/dist/core.d.cts +55 -10
  73. package/dist/core.d.ts +55 -10
  74. package/dist/core.js +3 -3
  75. package/dist/node.cjs +1356 -976
  76. package/dist/node.d.cts +2 -2
  77. package/dist/node.d.ts +2 -2
  78. package/dist/node.js +3 -3
  79. package/dist/web.cjs +1356 -976
  80. package/dist/web.d.cts +2 -2
  81. package/dist/web.d.ts +2 -2
  82. package/dist/web.js +3 -3
  83. package/node/test/inherited.test.ts +75 -65
  84. package/node/test/tfheinit.test.ts +23 -8
  85. package/package.json +6 -6
  86. package/web/test/client.web.test.ts +5 -1
  87. package/web/test/inherited.web.test.ts +75 -65
  88. package/web/test/tfheinit.web.test.ts +14 -5
  89. package/web/test/worker.config.web.test.ts +38 -23
  90. package/web/test/worker.output.web.test.ts +25 -24
  91. package/core/encrypt/encryptUtils.ts +0 -67
  92. package/core/permits.ts +0 -206
  93. package/core/test/permits.test.ts +0 -534
  94. package/dist/chunk-VB62WYPL.js +0 -978
  95. package/dist/permit-DnVMDT5h.d.cts +0 -376
  96. package/dist/permit-DnVMDT5h.d.ts +0 -376
  97. package/dist/permits.cjs +0 -1026
  98. package/dist/permits.d.cts +0 -353
  99. package/dist/permits.d.ts +0 -353
  100. package/dist/permits.js +0 -2
  101. package/permits/index.ts +0 -68
  102. package/permits/permit.ts +0 -385
  103. package/permits/sealing.ts +0 -131
  104. package/permits/signature.ts +0 -79
  105. package/permits/store.ts +0 -157
  106. package/permits/test/localstorage.test.ts +0 -113
  107. package/permits/test/permit.test.ts +0 -557
  108. package/permits/test/sealing.test.ts +0 -84
  109. package/permits/test/store.test.ts +0 -88
  110. package/permits/test/validation.test.ts +0 -361
  111. package/permits/test-utils.ts +0 -28
  112. package/permits/types.ts +0 -204
  113. package/permits/validation.ts +0 -327
  114. /package/{permits → acps}/utils.ts +0 -0
@@ -0,0 +1,130 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { mapApiErrorCodeToCofheErrorCode, parseApiErrorResponseBody } from '../decrypt/apiError.js';
3
+ import { CofheErrorCode } from '../error.js';
4
+
5
+ const makeResponse = (opts: { status?: number; statusText?: string; json: () => Promise<unknown> }): Response => {
6
+ return {
7
+ status: opts.status ?? 500,
8
+ statusText: opts.statusText ?? '',
9
+ json: opts.json,
10
+ } as unknown as Response;
11
+ };
12
+
13
+ describe('mapApiErrorCodeToCofheErrorCode', () => {
14
+ const cases: Array<[string, CofheErrorCode]> = [
15
+ ['bad_request', CofheErrorCode.BadRequest],
16
+ ['unknown_chain', CofheErrorCode.UnknownChain],
17
+ ['acp_malformed', CofheErrorCode.ACPMalformed],
18
+ ['acp_denied', CofheErrorCode.ACPDenied],
19
+ ['acp_expired', CofheErrorCode.ACPExpired],
20
+ ['acp_invalid', CofheErrorCode.ACPInvalid],
21
+ ['not_publicly_allowed', CofheErrorCode.NotPubliclyAllowed],
22
+ ['ct_not_found', CofheErrorCode.CtNotFound],
23
+ ['unsupported_security_zone', CofheErrorCode.UnsupportedSecurityZone],
24
+ ['unsupported_type', CofheErrorCode.UnsupportedType],
25
+ ['internal_error', CofheErrorCode.InternalError],
26
+ ['signing_failed', CofheErrorCode.SigningFailed],
27
+ ['ct_source_error', CofheErrorCode.CtSourceError],
28
+ ['acp_verifier_error', CofheErrorCode.ACPVerifierError],
29
+ ['ct_source_timeout', CofheErrorCode.CtSourceTimeout],
30
+ ['acp_verifier_timeout', CofheErrorCode.ACPVerifierTimeout],
31
+ ['acp_required', CofheErrorCode.ACPRequired],
32
+ ['seal_failed', CofheErrorCode.SealFailed],
33
+ ];
34
+
35
+ it.each(cases)('maps %s to %s', (apiErrorCode, expected) => {
36
+ expect(mapApiErrorCodeToCofheErrorCode(apiErrorCode, CofheErrorCode.DecryptFailed)).toBe(expected);
37
+ });
38
+
39
+ it('falls back for an unrecognized code', () => {
40
+ expect(mapApiErrorCodeToCofheErrorCode('some_future_code', CofheErrorCode.DecryptFailed)).toBe(
41
+ CofheErrorCode.DecryptFailed
42
+ );
43
+ });
44
+
45
+ it('falls back for an undefined code', () => {
46
+ expect(mapApiErrorCodeToCofheErrorCode(undefined, CofheErrorCode.SealOutputFailed)).toBe(
47
+ CofheErrorCode.SealOutputFailed
48
+ );
49
+ });
50
+ });
51
+
52
+ describe('parseApiErrorResponseBody', () => {
53
+ it('reads error and error_message from a well-formed body', async () => {
54
+ const response = makeResponse({
55
+ status: 401,
56
+ json: async () => ({ error: 'acp_expired', error_message: 'acp has expired' }),
57
+ });
58
+
59
+ await expect(parseApiErrorResponseBody(response)).resolves.toEqual({
60
+ apiErrorCode: 'acp_expired',
61
+ errorMessage: 'acp has expired',
62
+ });
63
+ });
64
+
65
+ it('falls back to message when error_message is absent', async () => {
66
+ const response = makeResponse({
67
+ status: 500,
68
+ json: async () => ({ error: 'internal_error', message: 'boom' }),
69
+ });
70
+
71
+ await expect(parseApiErrorResponseBody(response)).resolves.toEqual({
72
+ apiErrorCode: 'internal_error',
73
+ errorMessage: 'boom',
74
+ });
75
+ });
76
+
77
+ it('falls back to HTTP <status> when body has neither error_message nor message', async () => {
78
+ const response = makeResponse({
79
+ status: 400,
80
+ json: async () => ({ error: 'bad_request' }),
81
+ });
82
+
83
+ await expect(parseApiErrorResponseBody(response)).resolves.toEqual({
84
+ apiErrorCode: 'bad_request',
85
+ errorMessage: 'HTTP 400',
86
+ });
87
+ });
88
+
89
+ it('falls back to statusText when the body is not JSON (framework rejection)', async () => {
90
+ const response = makeResponse({
91
+ status: 415,
92
+ statusText: 'Unsupported Media Type',
93
+ json: async () => {
94
+ throw new Error('Unexpected token in JSON');
95
+ },
96
+ });
97
+
98
+ await expect(parseApiErrorResponseBody(response)).resolves.toEqual({
99
+ apiErrorCode: undefined,
100
+ errorMessage: 'Unsupported Media Type',
101
+ });
102
+ });
103
+
104
+ it('falls back to HTTP <status> when the body is not JSON and statusText is empty', async () => {
105
+ const response = makeResponse({
106
+ status: 405,
107
+ statusText: '',
108
+ json: async () => {
109
+ throw new Error('Unexpected token in JSON');
110
+ },
111
+ });
112
+
113
+ await expect(parseApiErrorResponseBody(response)).resolves.toEqual({
114
+ apiErrorCode: undefined,
115
+ errorMessage: 'HTTP 405',
116
+ });
117
+ });
118
+
119
+ it('ignores a non-object JSON body', async () => {
120
+ const response = makeResponse({
121
+ status: 500,
122
+ json: async () => 'just a string',
123
+ });
124
+
125
+ await expect(parseApiErrorResponseBody(response)).resolves.toEqual({
126
+ apiErrorCode: undefined,
127
+ errorMessage: 'HTTP 500',
128
+ });
129
+ });
130
+ });
@@ -383,7 +383,10 @@ describe('createCofheClientBase', () => {
383
383
  describe('encryptInputs', () => {
384
384
  it('should throw if not connected', async () => {
385
385
  try {
386
- await client.encryptInputs([Encryptable.uint8(1n), Encryptable.uint8(2n), Encryptable.uint8(3n)]).execute();
386
+ await client
387
+ .encryptInputs([Encryptable.uint8(1n), Encryptable.uint8(2n), Encryptable.uint8(3n)])
388
+ .setConsumingContract('0xbeefbeefbeefbeefbeefbeefbeefbeefbeefbeef')
389
+ .execute();
387
390
  } catch (error) {
388
391
  expect(error).toBeInstanceOf(CofheError);
389
392
  expect((error as CofheError).code).toBe(CofheErrorCode.NotConnected);
@@ -406,24 +409,24 @@ describe('createCofheClientBase', () => {
406
409
  });
407
410
  });
408
411
 
409
- describe('permits', () => {
410
- it('should expose permits', () => {
411
- expect(client.permits).toBeDefined();
412
- expect(client.permits).toHaveProperty('getSnapshot');
413
- expect(client.permits).toHaveProperty('subscribe');
414
- expect(client.permits).toHaveProperty('createSelf');
415
- expect(client.permits).toHaveProperty('createSharing');
416
- expect(client.permits).toHaveProperty('importShared');
417
- expect(client.permits).toHaveProperty('getHash');
418
- expect(client.permits).toHaveProperty('serialize');
419
- expect(client.permits).toHaveProperty('deserialize');
420
- expect(client.permits).toHaveProperty('getPermit');
421
- expect(client.permits).toHaveProperty('getPermits');
422
- expect(client.permits).toHaveProperty('getActivePermit');
423
- expect(client.permits).toHaveProperty('getActivePermitHash');
424
- expect(client.permits).toHaveProperty('removePermit');
425
- expect(client.permits).toHaveProperty('selectActivePermit');
426
- expect(client.permits).toHaveProperty('removeActivePermit');
412
+ describe('acps', () => {
413
+ it('should expose acps', () => {
414
+ expect(client.acp).toBeDefined();
415
+ expect(client.acp).toHaveProperty('getSnapshot');
416
+ expect(client.acp).toHaveProperty('subscribe');
417
+ expect(client.acp).toHaveProperty('createSelf');
418
+ expect(client.acp).toHaveProperty('createSharing');
419
+ expect(client.acp).toHaveProperty('importShared');
420
+ expect(client.acp).toHaveProperty('getHash');
421
+ expect(client.acp).toHaveProperty('serialize');
422
+ expect(client.acp).toHaveProperty('deserialize');
423
+ expect(client.acp).toHaveProperty('getACP');
424
+ expect(client.acp).toHaveProperty('getACPs');
425
+ expect(client.acp).toHaveProperty('getActiveACP');
426
+ expect(client.acp).toHaveProperty('getActiveACPHash');
427
+ expect(client.acp).toHaveProperty('removeACP');
428
+ expect(client.acp).toHaveProperty('selectActiveACP');
429
+ expect(client.acp).toHaveProperty('removeActiveACP');
427
430
  });
428
431
  });
429
432
  });
@@ -72,12 +72,12 @@ describe('createCofheConfigBase', () => {
72
72
  expectValidConfigItem('supportedChains', [sepolia, hardhat], [sepolia, hardhat]);
73
73
  });
74
74
 
75
- it('defaultPermitExpiration', () => {
76
- expectInvalidConfigItem('defaultPermitExpiration', 'not-a-number');
77
- expectInvalidConfigItem('defaultPermitExpiration', null);
75
+ it('defaultACPExpiration', () => {
76
+ expectInvalidConfigItem('defaultACPExpiration', 'not-a-number');
77
+ expectInvalidConfigItem('defaultACPExpiration', null);
78
78
 
79
- expectValidConfigItem('defaultPermitExpiration', 5, 5);
80
- expectValidConfigItem('defaultPermitExpiration', undefined, 60 * 60 * 24 * 30);
79
+ expectValidConfigItem('defaultACPExpiration', 5, 5);
80
+ expectValidConfigItem('defaultACPExpiration', undefined, 60 * 60 * 24 * 30);
81
81
  });
82
82
 
83
83
  it('fheKeyStorage', async () => {
@@ -240,3 +240,23 @@ describe('Config helper functions', () => {
240
240
  });
241
241
  });
242
242
  });
243
+
244
+ describe('createCofheConfigBase - stale key rejection', () => {
245
+ const validBaseConfig: CofheInputConfig = { supportedChains: [] };
246
+
247
+ it('rejects the pre-ACP defaultPermitExpiration and names its replacement', () => {
248
+ expect(() =>
249
+ createCofheConfigBase({ ...validBaseConfig, defaultPermitExpiration: 60 } as unknown as CofheInputConfig)
250
+ ).toThrow(/`defaultPermitExpiration` is now `defaultACPExpiration`/);
251
+ });
252
+
253
+ it('rejects unknown keys instead of silently stripping them', () => {
254
+ expect(() =>
255
+ createCofheConfigBase({ ...validBaseConfig, notARealKey: true } as unknown as CofheInputConfig)
256
+ ).toThrow(/Invalid cofhe configuration/);
257
+ });
258
+
259
+ it('still accepts a valid config', () => {
260
+ expect(() => createCofheConfigBase({ ...validBaseConfig, defaultACPExpiration: 60 })).not.toThrow();
261
+ });
262
+ });
@@ -1,13 +1,15 @@
1
+ import { STAGING_TESTS, stagingViemChain } from './stagingRedirect';
1
2
  import { FheTypes, verifyDecryptResult, createCofheConfigBase, TASK_MANAGER_ADDRESS } from '@/core';
2
- import { getChainById } from '@/chains';
3
+ import { getChainById, stagingCofhe } from '@/chains';
3
4
  import {
4
5
  TEST_PRIVATE_KEY,
5
6
  PRIMARY_TEST_CHAIN,
6
7
  primaryTestChainRegistry,
8
+ stagingTestChainRegistry,
7
9
  isPrimaryTestChainReady,
8
10
  } from '@cofhe/test-setup';
9
11
 
10
- import { permits } from '../permits.js';
12
+ import { acps } from '../acps.js';
11
13
  import { DecryptForTxBuilder } from '../decrypt/decryptForTxBuilder.js';
12
14
  import { DecryptForViewBuilder } from '../decrypt/decryptForViewBuilder.js';
13
15
 
@@ -19,6 +21,8 @@ import { arbitrumSepolia, baseSepolia, sepolia } from 'viem/chains';
19
21
 
20
22
  const account = privateKeyToAccount(TEST_PRIVATE_KEY);
21
23
 
24
+ const TEST_CHAIN_ID = STAGING_TESTS ? stagingViemChain.id : PRIMARY_TEST_CHAIN;
25
+
22
26
  const VIEM_CHAINS: Record<number, Chain> = {
23
27
  421614: arbitrumSepolia,
24
28
  84532: baseSepolia,
@@ -37,17 +41,18 @@ describe('Core – Decrypt Tests', () => {
37
41
  let publicValue: bigint;
38
42
 
39
43
  beforeAll(() => {
40
- if (!isPrimaryTestChainReady(primaryTestChainRegistry)) {
41
- throw new Error('Primary test chain registry is not initialized. Run `pnpm test:setup` first.');
44
+ const reg = STAGING_TESTS
45
+ ? (stagingTestChainRegistry as typeof primaryTestChainRegistry)
46
+ : primaryTestChainRegistry;
47
+ if (!isPrimaryTestChainReady(reg)) {
48
+ throw new Error('Test chain registry is not initialized. Run `pnpm test:setup` first.');
42
49
  }
43
-
44
- const reg = primaryTestChainRegistry;
45
50
  const chainId = reg.chainId;
46
51
 
47
- const viemChain = VIEM_CHAINS[chainId];
52
+ const viemChain = STAGING_TESTS ? stagingViemChain : VIEM_CHAINS[chainId];
48
53
  if (!viemChain) throw new Error(`No viem chain mapping for chain ${chainId}`);
49
54
 
50
- const cofheChain = getChainById(chainId);
55
+ const cofheChain = STAGING_TESTS ? stagingCofhe : getChainById(chainId);
51
56
  if (!cofheChain) throw new Error(`No cofhe chain config for chain ${chainId}`);
52
57
 
53
58
  config = createCofheConfigBase({ supportedChains: [cofheChain] });
@@ -67,7 +72,7 @@ describe('Core – Decrypt Tests', () => {
67
72
  config,
68
73
  publicClient,
69
74
  walletClient,
70
- chainId: PRIMARY_TEST_CHAIN,
75
+ chainId: TEST_CHAIN_ID,
71
76
  account: account.address,
72
77
  ctHash,
73
78
  requireConnected: undefined,
@@ -79,7 +84,7 @@ describe('Core – Decrypt Tests', () => {
79
84
  config,
80
85
  publicClient,
81
86
  walletClient,
82
- chainId: PRIMARY_TEST_CHAIN,
87
+ chainId: TEST_CHAIN_ID,
83
88
  account: account.address,
84
89
  ctHash,
85
90
  utype,
@@ -87,17 +92,17 @@ describe('Core – Decrypt Tests', () => {
87
92
  });
88
93
  }
89
94
 
90
- async function createPermit() {
91
- return permits.createSelf({ issuer: account.address, name: 'Decrypt Test Permit' }, publicClient, walletClient);
95
+ async function createACP() {
96
+ return acps.createSelf({ issuer: account.address, name: 'Decrypt Test ACP' }, publicClient, walletClient);
92
97
  }
93
98
 
94
99
  // ---------------------------------------------------------------------------
95
- // decryptForTx – withoutPermit (global allowance)
100
+ // decryptForTx – withoutACP (global allowance)
96
101
  // ---------------------------------------------------------------------------
97
102
 
98
- describe('decryptForTx – withoutPermit (global allowance)', () => {
103
+ describe('decryptForTx – withoutACP (global allowance)', () => {
99
104
  it('should decrypt a publicly allowed ciphertext', async () => {
100
- const result = await txBuilder(publicCtHash).withoutPermit().execute();
105
+ const result = await txBuilder(publicCtHash).withoutACP().execute();
101
106
 
102
107
  expect(BigInt(result.ctHash)).toBe(BigInt(publicCtHash));
103
108
  expect(result.decryptedValue).toBe(publicValue);
@@ -106,25 +111,25 @@ describe('Core – Decrypt Tests', () => {
106
111
  });
107
112
 
108
113
  // ---------------------------------------------------------------------------
109
- // decryptForTx – withPermit
114
+ // decryptForTx – withACP
110
115
  // ---------------------------------------------------------------------------
111
116
 
112
- describe('decryptForTx – withPermit', () => {
113
- it('should decrypt with a self permit', async () => {
114
- const permit = await createPermit();
117
+ describe('decryptForTx – withACP', () => {
118
+ it('should decrypt with a self acp', async () => {
119
+ const acp = await createACP();
115
120
 
116
- const result = await txBuilder(privateCtHash).withPermit(permit).execute();
121
+ const result = await txBuilder(privateCtHash).withACP(acp).execute();
117
122
 
118
123
  expect(BigInt(result.ctHash)).toBe(BigInt(privateCtHash));
119
124
  expect(result.decryptedValue).toBe(privateValue);
120
125
  expect(result.signature).toBeDefined();
121
126
  }, 180000);
122
127
 
123
- it('should auto-resolve active permit', async () => {
124
- const permit = await createPermit();
125
- permits.selectActivePermit(PRIMARY_TEST_CHAIN, account.address, permit.hash);
128
+ it('should auto-resolve active acp', async () => {
129
+ const acp = await createACP();
130
+ acps.selectActiveACP(TEST_CHAIN_ID, account.address, acp.hash);
126
131
 
127
- const result = await txBuilder(privateCtHash).withPermit().execute();
132
+ const result = await txBuilder(privateCtHash).withACP().execute();
128
133
 
129
134
  expect(BigInt(result.ctHash)).toBe(BigInt(privateCtHash));
130
135
  expect(result.decryptedValue).toBe(privateValue);
@@ -137,9 +142,9 @@ describe('Core – Decrypt Tests', () => {
137
142
 
138
143
  describe('verifyDecryptResult', () => {
139
144
  it('should verify a valid decrypt result', async () => {
140
- const permit = await createPermit();
145
+ const acp = await createACP();
141
146
 
142
- const decryptResult = await txBuilder(privateCtHash).withPermit(permit).execute();
147
+ const decryptResult = await txBuilder(privateCtHash).withACP(acp).execute();
143
148
 
144
149
  const isValid = await verifyDecryptResult(
145
150
  decryptResult.ctHash,
@@ -151,9 +156,9 @@ describe('Core – Decrypt Tests', () => {
151
156
  }, 180000);
152
157
 
153
158
  it('should return false for invalid inputs', async () => {
154
- const permit = await createPermit();
159
+ const acp = await createACP();
155
160
 
156
- const decryptResult = await txBuilder(privateCtHash).withPermit(permit).execute();
161
+ const decryptResult = await txBuilder(privateCtHash).withACP(acp).execute();
157
162
 
158
163
  expect(
159
164
  await verifyDecryptResult(decryptResult.ctHash, privateValue + 1n, decryptResult.signature, publicClient)
@@ -167,17 +172,17 @@ describe('Core – Decrypt Tests', () => {
167
172
 
168
173
  describe('decryptForView', () => {
169
174
  it('should return the plaintext value', async () => {
170
- await createPermit();
175
+ await createACP();
171
176
 
172
177
  const result = await viewBuilder(privateCtHash, FheTypes.Uint32).execute();
173
178
  expect(result).toBe(privateValue);
174
179
  }, 180000);
175
180
 
176
181
  it('should agree with decryptForTx on the same handle', async () => {
177
- const permit = await createPermit();
182
+ const acp = await createACP();
178
183
 
179
184
  const viewResult = await viewBuilder(privateCtHash, FheTypes.Uint32).execute();
180
- const txResult = await txBuilder(privateCtHash).withPermit(permit).execute();
185
+ const txResult = await txBuilder(privateCtHash).withACP(acp).execute();
181
186
 
182
187
  expect(viewResult).toBe(privateValue);
183
188
  expect(BigInt(txResult.ctHash)).toBe(BigInt(privateCtHash));
@@ -187,9 +192,9 @@ describe('Core – Decrypt Tests', () => {
187
192
 
188
193
  describe('verifyDecryptResult', () => {
189
194
  it('should correctly verify a valid decrypt result', async () => {
190
- const permit = await createPermit();
195
+ const acp = await createACP();
191
196
 
192
- const decryptResult = await txBuilder(privateCtHash).withPermit(permit).execute();
197
+ const decryptResult = await txBuilder(privateCtHash).withACP(acp).execute();
193
198
 
194
199
  const isValid = await verifyDecryptResult(
195
200
  decryptResult.ctHash,
@@ -201,8 +206,8 @@ describe('Core – Decrypt Tests', () => {
201
206
  }, 180000);
202
207
 
203
208
  it('should verify identically to the on-chain TaskManager contract', async () => {
204
- const permit = await createPermit();
205
- const decryptResult = await txBuilder(privateCtHash).withPermit(permit).execute();
209
+ const acp = await createACP();
210
+ const decryptResult = await txBuilder(privateCtHash).withACP(acp).execute();
206
211
 
207
212
  const samples = [
208
213
  {