@cofhe/sdk 0.5.1 → 0.6.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 (47) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/adapters/test/ethers5.test.ts +1 -1
  3. package/adapters/test/ethers6.test.ts +1 -1
  4. package/adapters/test/wagmi.test.ts +1 -1
  5. package/chains/chains/hardhat.ts +3 -3
  6. package/core/consts.ts +0 -3
  7. package/core/decrypt/decryptForTxBuilder.ts +21 -0
  8. package/core/decrypt/decryptForViewBuilder.ts +19 -0
  9. package/core/decrypt/submitRetry.ts +126 -0
  10. package/core/decrypt/tnDecryptV2.ts +48 -53
  11. package/core/decrypt/tnSealOutputV2.ts +48 -54
  12. package/core/encrypt/cofheMocksZkVerifySign.ts +2 -2
  13. package/core/encrypt/encryptInputsBuilder.ts +46 -11
  14. package/core/encrypt/zkPackProveVerify.ts +3 -3
  15. package/core/index.ts +13 -1
  16. package/core/test/decryptBuilders.test.ts +28 -0
  17. package/core/test/encryptInputsBuilder.test.ts +35 -0
  18. package/core/test/pollCallbacks.test.ts +226 -0
  19. package/core/types.ts +65 -5
  20. package/dist/chains.cjs +3 -3
  21. package/dist/chains.js +1 -1
  22. package/dist/{chunk-4FP4V35O.js → chunk-ESMZCFJY.js} +1 -2
  23. package/dist/{chunk-TBLR7NNE.js → chunk-MTRAXQXC.js} +3 -3
  24. package/dist/{chunk-S7OKGLFD.js → chunk-PE5V5CCV.js} +288 -153
  25. package/dist/{chunk-MRCKUMOS.js → chunk-VB62WYPL.js} +1 -1
  26. package/dist/{clientTypes-BSbwairE.d.cts → clientTypes-BDy1qIBu.d.cts} +78 -11
  27. package/dist/{clientTypes-DDmcgZ0a.d.ts → clientTypes-CyUvRRzA.d.ts} +78 -11
  28. package/dist/core.cjs +288 -155
  29. package/dist/core.d.cts +3 -5
  30. package/dist/core.d.ts +3 -5
  31. package/dist/core.js +4 -4
  32. package/dist/node.cjs +243 -108
  33. package/dist/node.d.cts +1 -1
  34. package/dist/node.d.ts +1 -1
  35. package/dist/node.js +4 -4
  36. package/dist/permits.d.cts +10 -6
  37. package/dist/permits.d.ts +10 -6
  38. package/dist/permits.js +2 -2
  39. package/dist/web.cjs +243 -108
  40. package/dist/web.d.cts +1 -1
  41. package/dist/web.d.ts +1 -1
  42. package/dist/web.js +4 -4
  43. package/dist/zkProve.worker.js +1 -1
  44. package/package.json +2 -2
  45. package/permits/store.ts +1 -0
  46. package/web/test/ssr.test.ts +23 -0
  47. package/web/test/tfheinit.web.test.ts +81 -5
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cofhe/sdk",
3
- "version": "0.5.1",
3
+ "version": "0.6.0",
4
4
  "type": "module",
5
5
  "description": "SDK for Fhenix COFHE coprocessor interaction",
6
6
  "main": "./dist/core.cjs",
@@ -64,7 +64,7 @@
64
64
  "tweetnacl": "1.0.3",
65
65
  "viem": "2.38.6",
66
66
  "zod": "4.0.0",
67
- "zustand": "5.0.1"
67
+ "zustand": "5.0.13"
68
68
  },
69
69
  "peerDependencies": {
70
70
  "@nomicfoundation/hardhat-ethers": "^3.0.0",
package/permits/store.ts CHANGED
@@ -19,6 +19,7 @@ export const PERMIT_STORE_DEFAULTS: PermitsStore = {
19
19
  permits: {},
20
20
  activePermitHash: {},
21
21
  };
22
+
22
23
  export const _permitStore = createStore<PermitsStore>()(
23
24
  persist(() => PERMIT_STORE_DEFAULTS, { name: 'cofhesdk-permits' })
24
25
  );
@@ -0,0 +1,23 @@
1
+ import { describe, expect, it, vi, afterEach } from 'vitest';
2
+
3
+ describe('@cofhe/sdk/web SSR smoke', () => {
4
+ afterEach(() => {
5
+ vi.restoreAllMocks();
6
+ });
7
+
8
+ it('imports and creates config in a Node SSR environment', async () => {
9
+ const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
10
+
11
+ expect((globalThis as { window?: unknown }).window).toBeUndefined();
12
+ expect((globalThis as { document?: unknown }).document).toBeUndefined();
13
+
14
+ const web = await import('../index');
15
+ const config = web.createCofheConfig({ supportedChains: [] });
16
+
17
+ expect(web.hasDOM).toBe(false);
18
+ expect(config.environment).toBe('web');
19
+ expect(config.fheKeyStorage).not.toBeNull();
20
+ expect(() => web.createCofheClient(config)).not.toThrow();
21
+ expect(warnSpy).toHaveBeenCalledWith('using no-op server-side SSR storage');
22
+ });
23
+ });
@@ -1,5 +1,5 @@
1
1
  import { arbSepolia as cofheArbSepolia } from '@/chains';
2
- import { Encryptable, FheTypes, type CofheClient, CofheErrorCode, CofheError } from '@/core';
2
+ import { Encryptable, type CofheClient } from '@/core';
3
3
 
4
4
  import { describe, it, expect, beforeAll, beforeEach } from 'vitest';
5
5
  import type { PublicClient, WalletClient } from 'viem';
@@ -11,6 +11,39 @@ import { createCofheClient, createCofheConfig } from '../index.js';
11
11
  // Real test setup - runs in browser with real tfhe
12
12
  const TEST_PRIVATE_KEY = '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80';
13
13
 
14
+ // Logs per-step durations using the built-in `context.duration` provided by the SDK.
15
+ // Each encryption run is a separate entry so multi-encrypt tests show per-run breakdowns.
16
+ function makeStepLogger(testName: string) {
17
+ const runs: Array<Record<string, number>> = [];
18
+ let current: Record<string, number> = {};
19
+
20
+ function onStep(step: string, context?: Record<string, unknown>) {
21
+ if (!context?.isEnd) return;
22
+ current[step] = (context.duration as number) ?? 0;
23
+ }
24
+
25
+ function nextRun() {
26
+ if (Object.keys(current).length > 0) runs.push(current);
27
+ current = {};
28
+ }
29
+
30
+ function log() {
31
+ if (Object.keys(current).length > 0) runs.push(current);
32
+ console.log(`\n[TFHE Timing] ${testName}`);
33
+ runs.forEach((run, i) => {
34
+ const label = runs.length > 1 ? ` run ${i + 1}` : '';
35
+ const total = Object.values(run).reduce((a, b) => a + b, 0);
36
+ for (const [step, ms] of Object.entries(run)) {
37
+ console.log(` [${label.trim() || 'run'}] ${step}: ${ms}ms`);
38
+ }
39
+ console.log(` [${label.trim() || 'run'}] total: ${total}ms`);
40
+ });
41
+ console.log('');
42
+ }
43
+
44
+ return { onStep, nextRun, log };
45
+ }
46
+
14
47
  describe('@cofhe/web - TFHE Initialization Browser Tests', () => {
15
48
  let cofheClient: CofheClient;
16
49
  let publicClient: PublicClient;
@@ -42,21 +75,64 @@ describe('@cofhe/web - TFHE Initialization Browser Tests', () => {
42
75
  it('should initialize tfhe on first encryption', async () => {
43
76
  await cofheClient.connect(publicClient, walletClient);
44
77
 
78
+ const logger = makeStepLogger('should initialize tfhe on first encryption');
79
+ let initTfheContext: Record<string, unknown> | undefined;
80
+
45
81
  // This will trigger real TFHE initialization in browser
46
- const result = await cofheClient.encryptInputs([Encryptable.uint128(100n)]).execute();
82
+ const result = await cofheClient
83
+ .encryptInputs([Encryptable.uint128(100n)])
84
+ .onStep((step, context) => {
85
+ logger.onStep(step, context);
86
+ if (step === 'initTfhe' && context?.isEnd) {
87
+ initTfheContext = context;
88
+ }
89
+ })
90
+ .execute();
91
+
92
+ logger.log();
47
93
 
48
94
  // If we get here, TFHE was initialized successfully
49
95
  expect(result).toBeDefined();
96
+ expect(initTfheContext).toBeDefined();
97
+ expect(initTfheContext?.tfheInitializationExecuted).toBe(true);
50
98
  }, 60000); // Longer timeout for real operations
51
99
 
52
100
  it('should handle multiple encryptions without re-initializing', async () => {
53
101
  await cofheClient.connect(publicClient, walletClient);
54
102
 
103
+ const logger = makeStepLogger('should handle multiple encryptions without re-initializing');
104
+ const initTfheContexts: Array<Record<string, unknown>> = [];
105
+
55
106
  // First encryption
56
- expect(cofheClient.encryptInputs([Encryptable.uint128(100n)]).execute()).resolves.not.toThrow();
107
+ const firstResult = await cofheClient
108
+ .encryptInputs([Encryptable.uint128(100n)])
109
+ .onStep((step, context) => {
110
+ logger.onStep(step, context);
111
+ if (step === 'initTfhe' && context?.isEnd) {
112
+ initTfheContexts.push(context);
113
+ }
114
+ })
115
+ .execute();
116
+
117
+ logger.nextRun();
57
118
 
58
119
  // Second encryption should reuse initialization
59
- expect(cofheClient.encryptInputs([Encryptable.uint64(50n)]).execute()).resolves.not.toThrow();
60
- }, 60000);
120
+ const secondResult = await cofheClient
121
+ .encryptInputs([Encryptable.uint64(50n)])
122
+ .onStep((step, context) => {
123
+ logger.onStep(step, context);
124
+ if (step === 'initTfhe' && context?.isEnd) {
125
+ initTfheContexts.push(context);
126
+ }
127
+ })
128
+ .execute();
129
+
130
+ logger.log();
131
+
132
+ expect(firstResult).toBeDefined();
133
+ expect(secondResult).toBeDefined();
134
+ expect(initTfheContexts).toHaveLength(2);
135
+ expect(initTfheContexts[1].tfheInitializationExecuted).toBe(false);
136
+ }, 120000); // Two full encryptions on real network; CI runners can be slow
61
137
  });
62
138
  });