@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
@@ -1,9 +1,11 @@
1
+ import { STAGING_TESTS, stagingViemChain } from '../../core/test/stagingRedirect';
1
2
  import { Encryptable, FheTypes, type CofheClient } from '@/core';
2
- import { arbSepolia as cofheArbSepolia, getChainById } from '@/chains';
3
+ import { arbSepolia as cofheArbSepolia, 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
 
@@ -28,6 +30,9 @@ const VIEM_CHAINS: Record<number, Chain> = {
28
30
  11155111: sepolia,
29
31
  };
30
32
 
33
+ const testViemChain = STAGING_TESTS ? stagingViemChain : arbitrumSepolia;
34
+ const testCofheChain = STAGING_TESTS ? stagingCofhe : cofheArbSepolia;
35
+
31
36
  describe('@cofhe/web - Inherited Client Tests', () => {
32
37
  let cofheClient: CofheClient;
33
38
  let publicClient: PublicClient;
@@ -36,18 +41,18 @@ describe('@cofhe/web - Inherited Client Tests', () => {
36
41
 
37
42
  beforeAll(() => {
38
43
  publicClient = createPublicClient({
39
- chain: arbitrumSepolia,
44
+ chain: testViemChain,
40
45
  transport: http(),
41
46
  });
42
47
 
43
48
  bobWalletClient = createWalletClient({
44
- chain: arbitrumSepolia,
49
+ chain: testViemChain,
45
50
  transport: http(),
46
51
  account: bobAccount,
47
52
  });
48
53
 
49
54
  aliceWalletClient = createWalletClient({
50
- chain: arbitrumSepolia,
55
+ chain: testViemChain,
51
56
  transport: http(),
52
57
  account: aliceAccount,
53
58
  });
@@ -55,7 +60,7 @@ describe('@cofhe/web - Inherited Client Tests', () => {
55
60
 
56
61
  beforeEach(() => {
57
62
  const config = createCofheConfig({
58
- supportedChains: [cofheArbSepolia],
63
+ supportedChains: [testCofheChain],
59
64
  });
60
65
  cofheClient = createCofheClient(config);
61
66
  });
@@ -72,7 +77,7 @@ describe('@cofhe/web - Inherited Client Tests', () => {
72
77
  expect(typeof cofheClient.decryptForTx).toBe('function');
73
78
  expect(typeof cofheClient.getSnapshot).toBe('function');
74
79
  expect(typeof cofheClient.subscribe).toBe('function');
75
- expect(cofheClient.permits).toBeDefined();
80
+ expect(cofheClient.acp).toBeDefined();
76
81
  });
77
82
  });
78
83
 
@@ -84,7 +89,7 @@ describe('@cofhe/web - Inherited Client Tests', () => {
84
89
 
85
90
  const snapshot = cofheClient.getSnapshot();
86
91
  expect(snapshot.connected).toBe(true);
87
- expect(snapshot.chainId).toBe(cofheArbSepolia.id);
92
+ expect(snapshot.chainId).toBe(testCofheChain.id);
88
93
  expect(snapshot.account).toBe(bobAccount.address);
89
94
  }, 30000);
90
95
  });
@@ -93,81 +98,85 @@ describe('@cofhe/web - Inherited Client Tests', () => {
93
98
  it('should encrypt a uint128 value', async () => {
94
99
  await cofheClient.connect(publicClient, bobWalletClient);
95
100
 
96
- const encrypted = await cofheClient.encryptInputs([Encryptable.uint128(100n)]).execute();
101
+ const encrypted = await cofheClient
102
+ .encryptInputs([Encryptable.uint128(100n)])
103
+ .setConsumingContract(bobAccount.address)
104
+ .execute();
97
105
 
106
+ // [hash, signature] - one hash per input, followed by the shared batch signature.
98
107
  expect(encrypted).toBeDefined();
99
- expect(encrypted.length).toBe(1);
100
- expect(encrypted[0].utype).toBe(FheTypes.Uint128);
101
- expect(encrypted[0].ctHash).toBeDefined();
102
- expect(typeof encrypted[0].ctHash).toBe('bigint');
103
- expect(encrypted[0].signature).toBeDefined();
104
- expect(typeof encrypted[0].signature).toBe('string');
105
- expect(encrypted[0].securityZone).toBe(0);
106
- }, 60000);
108
+ expect(encrypted.length).toBe(2);
109
+
110
+ const [hash, signature] = encrypted;
111
+ expect(typeof hash).toBe('string');
112
+ expect(hash).toMatch(/^0x[0-9a-fA-F]+$/);
113
+ expect(typeof signature).toBe('string');
114
+ expect(signature).toMatch(/^0x[0-9a-fA-F]+$/);
115
+ }, 120000);
107
116
  });
108
117
 
109
- describe('Self Permit', () => {
110
- it('should create a self permit', async () => {
118
+ describe('Self ACP', () => {
119
+ it('should create a self acp', async () => {
111
120
  await cofheClient.connect(publicClient, bobWalletClient);
112
121
 
113
- const permit = await cofheClient.permits.createSelf({
122
+ const acp = await cofheClient.acp.createSelf({
114
123
  issuer: bobAccount.address,
115
- name: 'Test Self Permit',
124
+ name: 'Test Self ACP',
116
125
  });
117
126
 
118
- expect(permit).toBeDefined();
119
- expect(permit.type).toBe('self');
120
- expect(permit.name).toBe('Test Self Permit');
121
- expect(permit.issuer).toBe(bobAccount.address);
122
- expect(permit.issuerSignature).not.toBe('0x');
123
- expect(permit.sealingPair).toBeDefined();
124
- expect(permit.sealingPair.publicKey).toBeDefined();
125
-
126
- const activePermit = cofheClient.permits.getActivePermit();
127
- expect(activePermit).toBeDefined();
128
- expect(activePermit!.hash).toBe(permit.hash);
127
+ expect(acp).toBeDefined();
128
+ expect(acp.type).toBe('self');
129
+ expect(acp.name).toBe('Test Self ACP');
130
+ expect(acp.issuer).toBe(bobAccount.address);
131
+ expect(acp.issuerSignature).not.toBe('0x');
132
+ expect(acp.sealingPrivateKey).toBeDefined();
133
+ expect(acp.sealingKey).toBeDefined();
134
+
135
+ const activeACP = cofheClient.acp.getActiveACP();
136
+ expect(activeACP).toBeDefined();
137
+ expect(activeACP!.hash).toBe(acp.hash);
129
138
  }, 30000);
130
139
  });
131
140
 
132
- describe('Sharing Permit', () => {
133
- it('should create a sharing permit, export it, and import it as another user', async () => {
141
+ describe('Sharing ACP', () => {
142
+ it('should create a sharing acp, export it, and import it as another user', async () => {
134
143
  await cofheClient.connect(publicClient, bobWalletClient);
135
144
 
136
- const sharingPermit = await cofheClient.permits.createSharing({
145
+ const sharingACP = await cofheClient.acp.createSharing({
137
146
  issuer: bobAccount.address,
138
147
  recipient: aliceAccount.address,
139
- name: 'Test Sharing Permit',
148
+ name: 'Test Sharing ACP',
140
149
  });
141
150
 
142
- expect(sharingPermit).toBeDefined();
143
- expect(sharingPermit.type).toBe('sharing');
144
- expect(sharingPermit.issuer).toBe(bobAccount.address);
145
- expect(sharingPermit.recipient).toBe(aliceAccount.address);
146
- expect(sharingPermit.issuerSignature).not.toBe('0x');
151
+ expect(sharingACP).toBeDefined();
152
+ expect(sharingACP.type).toBe('sharing');
153
+ expect(sharingACP.issuer).toBe(bobAccount.address);
154
+ expect(sharingACP.recipient).toBe(aliceAccount.address);
155
+ expect(sharingACP.issuerSignature).not.toBe('0x');
147
156
 
148
- const exported = cofheClient.permits.export(sharingPermit);
157
+ const exported = cofheClient.acp.export(sharingACP);
149
158
  expect(exported).toBeDefined();
150
159
  const parsed = JSON.parse(exported);
151
160
  expect(parsed.type).toBe('sharing');
152
161
  expect(parsed.issuer).toBe(bobAccount.address);
153
162
  expect(parsed.recipient).toBe(aliceAccount.address);
154
163
  expect(parsed.issuerSignature).toBeDefined();
155
- expect(parsed).not.toHaveProperty('sealingPair');
164
+ expect(parsed).not.toHaveProperty('sealingPrivateKey');
156
165
 
157
166
  const aliceConfig = createCofheConfig({
158
- supportedChains: [cofheArbSepolia],
167
+ supportedChains: [testCofheChain],
159
168
  });
160
169
  const aliceClient = createCofheClient(aliceConfig);
161
170
  await aliceClient.connect(publicClient, aliceWalletClient);
162
171
 
163
- const importedPermit = await aliceClient.permits.importShared(exported);
172
+ const importedACP = await aliceClient.acp.importShared(exported);
164
173
 
165
- expect(importedPermit).toBeDefined();
166
- expect(importedPermit.type).toBe('recipient');
167
- expect(importedPermit.issuer).toBe(bobAccount.address);
168
- expect(importedPermit.recipient).toBe(aliceAccount.address);
169
- expect(importedPermit.recipientSignature).not.toBe('0x');
170
- expect(importedPermit.sealingPair).toBeDefined();
174
+ expect(importedACP).toBeDefined();
175
+ expect(importedACP.type).toBe('recipient');
176
+ expect(importedACP.issuer).toBe(bobAccount.address);
177
+ expect(importedACP.recipient).toBe(aliceAccount.address);
178
+ expect(importedACP.recipientSignature).not.toBe('0x');
179
+ expect(importedACP.sealingPrivateKey).toBeDefined();
171
180
  }, 30000);
172
181
  });
173
182
 
@@ -182,15 +191,16 @@ describe('@cofhe/web - Inherited Client Tests', () => {
182
191
  let publicValue: bigint;
183
192
 
184
193
  beforeAll(() => {
185
- if (!isPrimaryTestChainReady(primaryTestChainRegistry)) {
186
- throw new Error('Primary test chain registry not initialized. Run `pnpm test:setup` first.');
194
+ const reg = STAGING_TESTS
195
+ ? (stagingTestChainRegistry as typeof primaryTestChainRegistry)
196
+ : primaryTestChainRegistry;
197
+ if (!isPrimaryTestChainReady(reg)) {
198
+ throw new Error('Test chain registry not initialized. Run `pnpm test:setup` first.');
187
199
  }
188
-
189
- const reg = primaryTestChainRegistry;
190
- const viemChain = VIEM_CHAINS[reg.chainId];
200
+ const viemChain = STAGING_TESTS ? stagingViemChain : VIEM_CHAINS[reg.chainId];
191
201
  if (!viemChain) throw new Error(`No viem chain mapping for chain ${reg.chainId}`);
192
202
 
193
- const cofheChain = getChainById(reg.chainId);
203
+ const cofheChain = STAGING_TESTS ? stagingCofhe : getChainById(reg.chainId);
194
204
  if (!cofheChain) throw new Error(`No cofhe chain config for chain ${reg.chainId}`);
195
205
 
196
206
  privateCtHash = reg.privateValue.ctHash as `0x${string}`;
@@ -205,37 +215,37 @@ describe('@cofhe/web - Inherited Client Tests', () => {
205
215
  decryptClient = createCofheClient(config);
206
216
  });
207
217
 
208
- it('decryptForView — private value with permit', async () => {
218
+ it('decryptForView — private value with acp', async () => {
209
219
  await decryptClient.connect(decryptPublicClient, decryptWalletClient);
210
220
 
211
- await decryptClient.permits.createSelf({
221
+ await decryptClient.acp.createSelf({
212
222
  issuer: bobAccount.address,
213
- name: 'Decrypt View Permit',
223
+ name: 'Decrypt View ACP',
214
224
  });
215
225
 
216
226
  const result = await decryptClient.decryptForView(privateCtHash, FheTypes.Uint32).execute();
217
227
  expect(result).toBe(privateValue);
218
228
  }, 180000);
219
229
 
220
- it('decryptForTx — public value without permit', async () => {
230
+ it('decryptForTx — public value without acp', async () => {
221
231
  await decryptClient.connect(decryptPublicClient, decryptWalletClient);
222
232
 
223
- const result = await decryptClient.decryptForTx(publicCtHash).withoutPermit().execute();
233
+ const result = await decryptClient.decryptForTx(publicCtHash).withoutACP().execute();
224
234
 
225
235
  expect(BigInt(result.ctHash)).toBe(BigInt(publicCtHash));
226
236
  expect(result.decryptedValue).toBe(publicValue);
227
237
  expect(result.signature).toMatch(/^0x[0-9a-fA-F]+$/);
228
238
  }, 180000);
229
239
 
230
- it('decryptForTx — private value with permit', async () => {
240
+ it('decryptForTx — private value with acp', async () => {
231
241
  await decryptClient.connect(decryptPublicClient, decryptWalletClient);
232
242
 
233
- const permit = await decryptClient.permits.createSelf({
243
+ const acp = await decryptClient.acp.createSelf({
234
244
  issuer: bobAccount.address,
235
- name: 'Decrypt Tx Permit',
245
+ name: 'Decrypt Tx ACP',
236
246
  });
237
247
 
238
- const result = await decryptClient.decryptForTx(privateCtHash).withPermit(permit).execute();
248
+ const result = await decryptClient.decryptForTx(privateCtHash).withACP(acp).execute();
239
249
 
240
250
  expect(BigInt(result.ctHash)).toBe(BigInt(privateCtHash));
241
251
  expect(result.decryptedValue).toBe(privateValue);
@@ -1,4 +1,5 @@
1
- import { arbSepolia as cofheArbSepolia } from '@/chains';
1
+ import { STAGING_TESTS, stagingViemChain } from '../../core/test/stagingRedirect';
2
+ import { arbSepolia as cofheArbSepolia, stagingCofhe } from '@/chains';
2
3
  import { Encryptable, type CofheClient } from '@/core';
3
4
 
4
5
  import { describe, it, expect, beforeAll, beforeEach } from 'vitest';
@@ -11,6 +12,9 @@ import { createCofheClient, createCofheConfig } from '../index.js';
11
12
  // Real test setup - runs in browser with real tfhe
12
13
  const TEST_PRIVATE_KEY = '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80';
13
14
 
15
+ const testViemChain = STAGING_TESTS ? stagingViemChain : viemArbitrumSepolia;
16
+ const testCofheChain = STAGING_TESTS ? stagingCofhe : cofheArbSepolia;
17
+
14
18
  // Logs per-step durations using the built-in `context.duration` provided by the SDK.
15
19
  // Each encryption run is a separate entry so multi-encrypt tests show per-run breakdowns.
16
20
  function makeStepLogger(testName: string) {
@@ -48,25 +52,27 @@ describe('@cofhe/web - TFHE Initialization Browser Tests', () => {
48
52
  let cofheClient: CofheClient;
49
53
  let publicClient: PublicClient;
50
54
  let walletClient: WalletClient;
55
+ let consumingContract: `0x${string}`;
51
56
 
52
57
  beforeAll(() => {
53
58
  // Create real viem clients
54
59
  publicClient = createPublicClient({
55
- chain: viemArbitrumSepolia,
60
+ chain: testViemChain,
56
61
  transport: http(),
57
62
  });
58
63
 
59
64
  const account = privateKeyToAccount(TEST_PRIVATE_KEY);
60
65
  walletClient = createWalletClient({
61
- chain: viemArbitrumSepolia,
66
+ chain: testViemChain,
62
67
  transport: http(),
63
68
  account,
64
69
  });
70
+ consumingContract = account.address;
65
71
  });
66
72
 
67
73
  beforeEach(() => {
68
74
  const config = createCofheConfig({
69
- supportedChains: [cofheArbSepolia],
75
+ supportedChains: [testCofheChain],
70
76
  });
71
77
  cofheClient = createCofheClient(config);
72
78
  });
@@ -81,6 +87,7 @@ describe('@cofhe/web - TFHE Initialization Browser Tests', () => {
81
87
  // This will trigger real TFHE initialization in browser
82
88
  const result = await cofheClient
83
89
  .encryptInputs([Encryptable.uint128(100n)])
90
+ .setConsumingContract(consumingContract)
84
91
  .onStep((step, context) => {
85
92
  logger.onStep(step, context);
86
93
  if (step === 'initTfhe' && context?.isEnd) {
@@ -95,7 +102,7 @@ describe('@cofhe/web - TFHE Initialization Browser Tests', () => {
95
102
  expect(result).toBeDefined();
96
103
  expect(initTfheContext).toBeDefined();
97
104
  expect(initTfheContext?.tfheInitializationExecuted).toBe(true);
98
- }, 60000); // Longer timeout for real operations
105
+ }, 120000); // Longer timeout for real operations
99
106
 
100
107
  it('should handle multiple encryptions without re-initializing', async () => {
101
108
  await cofheClient.connect(publicClient, walletClient);
@@ -106,6 +113,7 @@ describe('@cofhe/web - TFHE Initialization Browser Tests', () => {
106
113
  // First encryption
107
114
  const firstResult = await cofheClient
108
115
  .encryptInputs([Encryptable.uint128(100n)])
116
+ .setConsumingContract(consumingContract)
109
117
  .onStep((step, context) => {
110
118
  logger.onStep(step, context);
111
119
  if (step === 'initTfhe' && context?.isEnd) {
@@ -119,6 +127,7 @@ describe('@cofhe/web - TFHE Initialization Browser Tests', () => {
119
127
  // Second encryption should reuse initialization
120
128
  const secondResult = await cofheClient
121
129
  .encryptInputs([Encryptable.uint64(50n)])
130
+ .setConsumingContract(consumingContract)
122
131
  .onStep((step, context) => {
123
132
  logger.onStep(step, context);
124
133
  if (step === 'initTfhe' && context?.isEnd) {
@@ -1,4 +1,5 @@
1
- import { arbSepolia as cofheArbSepolia } from '@/chains';
1
+ import { STAGING_TESTS, stagingViemChain } from '../../core/test/stagingRedirect';
2
+ import { arbSepolia as cofheArbSepolia, stagingCofhe } from '@/chains';
2
3
  import { Encryptable } from '@/core';
3
4
 
4
5
  import { describe, it, expect, beforeAll } from 'vitest';
@@ -10,28 +11,33 @@ import { createCofheClient, createCofheConfig, createCofheClientWithCustomWorker
10
11
 
11
12
  const TEST_PRIVATE_KEY = '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80';
12
13
 
14
+ const testViemChain = STAGING_TESTS ? stagingViemChain : viemArbitrumSepolia;
15
+ const testCofheChain = STAGING_TESTS ? stagingCofhe : cofheArbSepolia;
16
+
13
17
  describe('@cofhe/sdk/web - Worker Configuration Tests', () => {
14
18
  let publicClient: PublicClient;
15
19
  let walletClient: WalletClient;
20
+ let consumingContract: `0x${string}`;
16
21
 
17
22
  beforeAll(() => {
18
23
  publicClient = createPublicClient({
19
- chain: viemArbitrumSepolia,
24
+ chain: testViemChain,
20
25
  transport: http(),
21
26
  });
22
27
 
23
28
  const account = privateKeyToAccount(TEST_PRIVATE_KEY);
24
29
  walletClient = createWalletClient({
25
- chain: viemArbitrumSepolia,
30
+ chain: testViemChain,
26
31
  transport: http(),
27
32
  account,
28
33
  });
34
+ consumingContract = account.address;
29
35
  });
30
36
 
31
37
  describe('useWorkers config flag', () => {
32
38
  it('should use workers by default (useWorkers: true)', async () => {
33
39
  const config = createCofheConfig({
34
- supportedChains: [cofheArbSepolia],
40
+ supportedChains: [testCofheChain],
35
41
  // useWorkers defaults to true
36
42
  });
37
43
 
@@ -44,6 +50,7 @@ describe('@cofhe/sdk/web - Worker Configuration Tests', () => {
44
50
  let proveContext: any;
45
51
  const result = await client
46
52
  .encryptInputs([Encryptable.uint128(100n)])
53
+ .setConsumingContract(consumingContract)
47
54
  .onStep((step, context) => {
48
55
  if (step === 'prove' && context?.isEnd) {
49
56
  proveContext = context;
@@ -68,11 +75,11 @@ describe('@cofhe/sdk/web - Worker Configuration Tests', () => {
68
75
  console.log('Worker fallback occurred (expected in test env):', proveContext.workerFailedError);
69
76
  expect(proveContext.workerFailedError).toBeDefined();
70
77
  }
71
- }, 60000);
78
+ }, 120000);
72
79
 
73
80
  it('should disable workers when useWorkers: false', async () => {
74
81
  const config = createCofheConfig({
75
- supportedChains: [cofheArbSepolia],
82
+ supportedChains: [testCofheChain],
76
83
  useWorkers: false,
77
84
  });
78
85
 
@@ -85,6 +92,7 @@ describe('@cofhe/sdk/web - Worker Configuration Tests', () => {
85
92
  let proveContext: any;
86
93
  const result = await client
87
94
  .encryptInputs([Encryptable.uint128(100n)])
95
+ .setConsumingContract(consumingContract)
88
96
  .onStep((step, context) => {
89
97
  if (step === 'prove' && context?.isEnd) {
90
98
  proveContext = context;
@@ -98,13 +106,13 @@ describe('@cofhe/sdk/web - Worker Configuration Tests', () => {
98
106
  expect(proveContext).toBeDefined();
99
107
  expect(proveContext.useWorker).toBe(false);
100
108
  expect(proveContext.usedWorker).toBe(false);
101
- }, 60000);
109
+ }, 120000);
102
110
  });
103
111
 
104
112
  describe('setUseWorker() method', () => {
105
113
  it('should override config with setUseWorker(false)', async () => {
106
114
  const config = createCofheConfig({
107
- supportedChains: [cofheArbSepolia],
115
+ supportedChains: [testCofheChain],
108
116
  useWorkers: true, // Config says true
109
117
  });
110
118
 
@@ -115,6 +123,7 @@ describe('@cofhe/sdk/web - Worker Configuration Tests', () => {
115
123
  let proveContext: any;
116
124
  const result = await client
117
125
  .encryptInputs([Encryptable.uint128(100n)])
126
+ .setConsumingContract(consumingContract)
118
127
  .setUseWorker(false) // Override to false
119
128
  .onStep((step, context) => {
120
129
  if (step === 'prove' && context?.isEnd) {
@@ -128,11 +137,11 @@ describe('@cofhe/sdk/web - Worker Configuration Tests', () => {
128
137
  // Should respect the override
129
138
  expect(proveContext.useWorker).toBe(false);
130
139
  expect(proveContext.usedWorker).toBe(false);
131
- }, 60000);
140
+ }, 120000);
132
141
 
133
142
  it('should override config with setUseWorker(true)', async () => {
134
143
  const config = createCofheConfig({
135
- supportedChains: [cofheArbSepolia],
144
+ supportedChains: [testCofheChain],
136
145
  useWorkers: false, // Config says false
137
146
  });
138
147
 
@@ -143,6 +152,7 @@ describe('@cofhe/sdk/web - Worker Configuration Tests', () => {
143
152
  let proveContext: any;
144
153
  const result = await client
145
154
  .encryptInputs([Encryptable.uint128(100n)])
155
+ .setConsumingContract(consumingContract)
146
156
  .setUseWorker(true) // Override to true
147
157
  .onStep((step, context) => {
148
158
  if (step === 'prove' && context?.isEnd) {
@@ -155,13 +165,13 @@ describe('@cofhe/sdk/web - Worker Configuration Tests', () => {
155
165
 
156
166
  // Should use worker since we overrode to true
157
167
  expect(proveContext.useWorker).toBe(true);
158
- }, 60000);
168
+ }, 120000);
159
169
  });
160
170
 
161
171
  describe('Step callback worker context', () => {
162
172
  it('should include worker debug info in prove step', async () => {
163
173
  const config = createCofheConfig({
164
- supportedChains: [cofheArbSepolia],
174
+ supportedChains: [testCofheChain],
165
175
  });
166
176
 
167
177
  const client = createCofheClient(config);
@@ -170,6 +180,7 @@ describe('@cofhe/sdk/web - Worker Configuration Tests', () => {
170
180
  let proveContext: any;
171
181
  const result = await client
172
182
  .encryptInputs([Encryptable.uint128(100n)])
183
+ .setConsumingContract(consumingContract)
173
184
  .onStep((step, context) => {
174
185
  if (step === 'prove' && context?.isEnd) {
175
186
  proveContext = context;
@@ -191,13 +202,13 @@ describe('@cofhe/sdk/web - Worker Configuration Tests', () => {
191
202
  expect(proveContext).toHaveProperty('workerFailedError');
192
203
  expect(typeof proveContext.workerFailedError).toBe('string');
193
204
  }
194
- }, 60000);
205
+ }, 120000);
195
206
  });
196
207
 
197
208
  describe('Worker fallback behavior', () => {
198
209
  it('should fallback to main thread when worker fails', async () => {
199
210
  const config = createCofheConfig({
200
- supportedChains: [cofheArbSepolia],
211
+ supportedChains: [testCofheChain],
201
212
  useWorkers: true,
202
213
  });
203
214
 
@@ -214,6 +225,7 @@ describe('@cofhe/sdk/web - Worker Configuration Tests', () => {
214
225
  let proveContext: any;
215
226
  const result = await client
216
227
  .encryptInputs([Encryptable.uint128(100n)])
228
+ .setConsumingContract(consumingContract)
217
229
  .onStep((step, context) => {
218
230
  if (step === 'prove' && context?.isEnd) {
219
231
  proveContext = context;
@@ -223,18 +235,18 @@ describe('@cofhe/sdk/web - Worker Configuration Tests', () => {
223
235
 
224
236
  // Verify encryption succeeded via fallback to main thread
225
237
  expect(result).toBeDefined();
226
- expect(result.length).toBe(1);
238
+ expect(result.length).toBe(2); // 1 ctHash + shared signature
227
239
 
228
240
  // Verify worker was attempted but failed, triggering fallback
229
241
  expect(proveContext).toBeDefined();
230
242
  expect(proveContext.useWorker).toBe(true); // Worker was requested
231
243
  expect(proveContext.usedWorker).toBe(false); // But it failed
232
244
  expect(proveContext.workerFailedError).toBe('Worker failed intentionally');
233
- }, 60000);
245
+ }, 120000);
234
246
 
235
247
  it('should fallback when encrypting multiple values', async () => {
236
248
  const config = createCofheConfig({
237
- supportedChains: [cofheArbSepolia],
249
+ supportedChains: [testCofheChain],
238
250
  useWorkers: true,
239
251
  });
240
252
 
@@ -249,6 +261,7 @@ describe('@cofhe/sdk/web - Worker Configuration Tests', () => {
249
261
  let proveContext: any;
250
262
  const result = await client
251
263
  .encryptInputs([Encryptable.uint128(100n), Encryptable.uint64(50n), Encryptable.bool(true)])
264
+ .setConsumingContract(consumingContract)
252
265
  .onStep((step, context) => {
253
266
  if (step === 'prove' && context?.isEnd) {
254
267
  proveContext = context;
@@ -258,17 +271,17 @@ describe('@cofhe/sdk/web - Worker Configuration Tests', () => {
258
271
 
259
272
  // All values should encrypt successfully via fallback
260
273
  expect(result).toBeDefined();
261
- expect(result.length).toBe(3);
274
+ expect(result.length).toBe(4); // 3 ctHashes + shared signature
262
275
 
263
276
  // Verify fallback occurred
264
277
  expect(proveContext.useWorker).toBe(true);
265
278
  expect(proveContext.usedWorker).toBe(false);
266
279
  expect(proveContext.workerFailedError).toBe('Worker unavailable');
267
- }, 60000);
280
+ }, 120000);
268
281
 
269
282
  it('should handle async worker errors gracefully', async () => {
270
283
  const config = createCofheConfig({
271
- supportedChains: [cofheArbSepolia],
284
+ supportedChains: [testCofheChain],
272
285
  useWorkers: true,
273
286
  });
274
287
 
@@ -284,6 +297,7 @@ describe('@cofhe/sdk/web - Worker Configuration Tests', () => {
284
297
  let proveContext: any;
285
298
  const result = await client
286
299
  .encryptInputs([Encryptable.uint8(42n)])
300
+ .setConsumingContract(consumingContract)
287
301
  .onStep((step, context) => {
288
302
  if (step === 'prove' && context?.isEnd) {
289
303
  proveContext = context;
@@ -296,11 +310,11 @@ describe('@cofhe/sdk/web - Worker Configuration Tests', () => {
296
310
  expect(proveContext.useWorker).toBe(true);
297
311
  expect(proveContext.usedWorker).toBe(false);
298
312
  expect(proveContext.workerFailedError).toBe('Async worker failure');
299
- }, 60000);
313
+ }, 120000);
300
314
 
301
315
  it('should work without worker when explicitly disabled', async () => {
302
316
  const config = createCofheConfig({
303
- supportedChains: [cofheArbSepolia],
317
+ supportedChains: [testCofheChain],
304
318
  useWorkers: true, // Config says use workers
305
319
  });
306
320
 
@@ -310,6 +324,7 @@ describe('@cofhe/sdk/web - Worker Configuration Tests', () => {
310
324
  let proveContext: any;
311
325
  const result = await client
312
326
  .encryptInputs([Encryptable.uint8(42n)])
327
+ .setConsumingContract(consumingContract)
313
328
  .setUseWorker(false) // But override to disable worker
314
329
  .onStep((step, context) => {
315
330
  if (step === 'prove' && context?.isEnd) {
@@ -324,6 +339,6 @@ describe('@cofhe/sdk/web - Worker Configuration Tests', () => {
324
339
  expect(proveContext.useWorker).toBe(false);
325
340
  expect(proveContext.usedWorker).toBe(false);
326
341
  expect(proveContext.workerFailedError).toBeUndefined();
327
- }, 60000);
342
+ }, 120000);
328
343
  });
329
344
  });