@cofhe/sdk 0.4.0 → 0.5.1

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 (95) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/adapters/{ethers5.test.ts → test/ethers5.test.ts} +2 -2
  3. package/adapters/{ethers6.test.ts → test/ethers6.test.ts} +2 -2
  4. package/adapters/{hardhat.hh2.test.ts → test/hardhat.hh2.test.ts} +2 -2
  5. package/adapters/{index.test.ts → test/index.test.ts} +1 -1
  6. package/adapters/{wagmi.test.ts → test/wagmi.test.ts} +1 -1
  7. package/chains/{chains.test.ts → test/chains.test.ts} +1 -1
  8. package/core/client.ts +11 -1
  9. package/core/clientTypes.ts +3 -1
  10. package/core/consts.ts +9 -0
  11. package/core/decrypt/cofheMocksDecryptForTx.ts +14 -3
  12. package/core/decrypt/decryptForTxBuilder.ts +16 -2
  13. package/core/decrypt/decryptForViewBuilder.ts +14 -7
  14. package/core/decrypt/polling.ts +14 -0
  15. package/core/decrypt/tnDecryptV2.ts +250 -110
  16. package/core/decrypt/tnSealOutputV2.ts +245 -104
  17. package/core/decrypt/verifyDecryptResult.ts +65 -0
  18. package/core/encrypt/cofheMocksZkVerifySign.ts +6 -6
  19. package/core/encrypt/zkPackProveVerify.ts +10 -19
  20. package/core/fetchKeys.ts +0 -2
  21. package/core/index.ts +9 -1
  22. package/core/keyStore.ts +5 -2
  23. package/core/permits.ts +5 -0
  24. package/core/{client.test.ts → test/client.test.ts} +7 -7
  25. package/core/{config.test.ts → test/config.test.ts} +1 -1
  26. package/core/test/decrypt.test.ts +252 -0
  27. package/core/test/decryptBuilders.test.ts +390 -0
  28. package/core/{encrypt → test}/encryptInputsBuilder.test.ts +61 -6
  29. package/core/{fetchKeys.test.ts → test/fetchKeys.test.ts} +3 -3
  30. package/core/{keyStore.test.ts → test/keyStore.test.ts} +5 -3
  31. package/core/{permits.test.ts → test/permits.test.ts} +42 -1
  32. package/core/test/pollCallbacks.test.ts +563 -0
  33. package/core/types.ts +13 -0
  34. package/dist/chains.d.cts +2 -2
  35. package/dist/chains.d.ts +2 -2
  36. package/dist/chunk-4FP4V35O.js +13 -0
  37. package/dist/{chunk-NWDKXBIP.js → chunk-MRCKUMOS.js} +62 -22
  38. package/dist/{chunk-MXND5SVN.js → chunk-S7OKGLFD.js} +485 -207
  39. package/dist/{clientTypes-kkrRdawm.d.ts → clientTypes-BSbwairE.d.cts} +23 -6
  40. package/dist/{clientTypes-ACVWbrXL.d.cts → clientTypes-DDmcgZ0a.d.ts} +23 -6
  41. package/dist/core.cjs +561 -244
  42. package/dist/core.d.cts +24 -6
  43. package/dist/core.d.ts +24 -6
  44. package/dist/core.js +3 -2
  45. package/dist/node.cjs +566 -246
  46. package/dist/node.d.cts +3 -3
  47. package/dist/node.d.ts +3 -3
  48. package/dist/node.js +14 -7
  49. package/dist/{permit-MZ502UBl.d.cts → permit-DnVMDT5h.d.cts} +34 -4
  50. package/dist/{permit-MZ502UBl.d.ts → permit-DnVMDT5h.d.ts} +34 -4
  51. package/dist/permits.cjs +66 -29
  52. package/dist/permits.d.cts +18 -13
  53. package/dist/permits.d.ts +18 -13
  54. package/dist/permits.js +2 -1
  55. package/dist/web.cjs +604 -256
  56. package/dist/web.d.cts +8 -4
  57. package/dist/web.d.ts +8 -4
  58. package/dist/web.js +49 -14
  59. package/dist/zkProve.worker.cjs +72 -64
  60. package/dist/zkProve.worker.js +71 -64
  61. package/node/index.ts +13 -4
  62. package/node/test/client.test.ts +25 -0
  63. package/node/test/config.test.ts +16 -0
  64. package/node/test/inherited.test.ts +244 -0
  65. package/node/test/tfheinit.test.ts +56 -0
  66. package/package.json +24 -22
  67. package/permits/permit.ts +31 -5
  68. package/permits/sealing.ts +1 -1
  69. package/permits/{localstorage.test.ts → test/localstorage.test.ts} +2 -2
  70. package/permits/{permit.test.ts → test/permit.test.ts} +35 -1
  71. package/permits/{sealing.test.ts → test/sealing.test.ts} +1 -1
  72. package/permits/{store.test.ts → test/store.test.ts} +2 -2
  73. package/permits/{validation.test.ts → test/validation.test.ts} +82 -6
  74. package/permits/types.ts +1 -1
  75. package/permits/validation.ts +42 -2
  76. package/web/const.ts +2 -0
  77. package/web/index.ts +40 -11
  78. package/web/storage.ts +18 -3
  79. package/web/{client.web.test.ts → test/client.web.test.ts} +13 -1
  80. package/web/test/config.web.test.ts +16 -0
  81. package/web/test/inherited.web.test.ts +245 -0
  82. package/web/test/tfheinit.web.test.ts +62 -0
  83. package/web/{worker.config.web.test.ts → test/worker.config.web.test.ts} +1 -1
  84. package/web/{worker.output.web.test.ts → test/worker.output.web.test.ts} +1 -1
  85. package/web/{workerManager.test.ts → test/workerManager.test.ts} +1 -1
  86. package/web/{workerManager.web.test.ts → test/workerManager.web.test.ts} +1 -1
  87. package/web/zkProve.worker.ts +94 -84
  88. package/node/client.test.ts +0 -147
  89. package/node/config.test.ts +0 -68
  90. package/node/encryptInputs.test.ts +0 -155
  91. package/web/config.web.test.ts +0 -69
  92. package/web/encryptInputs.web.test.ts +0 -172
  93. package/web/worker.builder.web.test.ts +0 -148
  94. /package/dist/{types-YiAC4gig.d.cts → types-C07FK-cL.d.cts} +0 -0
  95. /package/dist/{types-YiAC4gig.d.ts → types-C07FK-cL.d.ts} +0 -0
@@ -6,6 +6,7 @@
6
6
  /// <reference lib="webworker" />
7
7
  /* eslint-disable no-undef */
8
8
 
9
+ import { TFHE_RS_SAFE_SERIALIZATION_SIZE_LIMIT } from '../core/consts';
9
10
  import type { ZkProveWorkerRequest, ZkProveWorkerResponse } from '../core/encrypt/zkPackProveVerify.js';
10
11
 
11
12
  // TFHE module (will be initialized on first use)
@@ -41,93 +42,102 @@ function fromHexString(hexString: string): Uint8Array {
41
42
  return new Uint8Array(arr.map((byte) => parseInt(byte, 16)));
42
43
  }
43
44
 
44
- /**
45
- * Main message handler
46
- */
47
- self.onmessage = async (event: MessageEvent) => {
48
- const { id, type, fheKeyHex, crsHex, items, metadata } = event.data as ZkProveWorkerRequest;
49
-
50
- if (type !== 'zkProve') {
51
- self.postMessage({
52
- id,
53
- type: 'error',
54
- error: 'Invalid message type',
55
- } as ZkProveWorkerResponse);
56
- return;
57
- }
58
-
59
- try {
60
- // Initialize TFHE if needed
61
- await initTfhe();
62
-
63
- if (!tfheModule) {
64
- throw new Error('TFHE module not initialized');
45
+ // Guard the top-level `self` references so this file is safe to evaluate in
46
+ // non-worker contexts (e.g. when bundlers like webpack pull the worker chunk
47
+ // into the server bundle for SSR). The body is dead code anywhere `self` is
48
+ // undefined, so skipping it is harmless.
49
+ if (typeof self !== 'undefined') {
50
+ /**
51
+ * Main message handler
52
+ */
53
+ self.onmessage = async (event: MessageEvent) => {
54
+ const { id, type, fheKeyHex, crsHex, items, metadata } = event.data as ZkProveWorkerRequest;
55
+
56
+ if (type !== 'zkProve') {
57
+ self.postMessage({
58
+ id,
59
+ type: 'error',
60
+ error: 'Invalid message type',
61
+ } as ZkProveWorkerResponse);
62
+ return;
65
63
  }
66
64
 
67
- // Deserialize FHE public key and CRS from hex strings
68
- const fheKeyBytes = fromHexString(fheKeyHex);
69
- const crsBytes = fromHexString(crsHex);
70
-
71
- const fheKey = tfheModule.TfheCompactPublicKey.deserialize(fheKeyBytes);
72
- const crs = tfheModule.CompactPkeCrs.deserialize(crsBytes);
73
-
74
- // Create builder
75
- const builder = tfheModule.ProvenCompactCiphertextList.builder(fheKey);
76
-
77
- // Pack all items (duplicate of zkPack logic)
78
- for (const item of items) {
79
- switch (item.utype) {
80
- case 'bool':
81
- builder.push_boolean(Boolean(item.data));
82
- break;
83
- case 'uint8':
84
- builder.push_u8(Number(item.data));
85
- break;
86
- case 'uint16':
87
- builder.push_u16(Number(item.data));
88
- break;
89
- case 'uint32':
90
- builder.push_u32(Number(item.data));
91
- break;
92
- case 'uint64':
93
- builder.push_u64(BigInt(item.data));
94
- break;
95
- case 'uint128':
96
- builder.push_u128(BigInt(item.data));
97
- break;
98
- case 'uint160':
99
- builder.push_u160(BigInt(item.data));
100
- break;
101
- default:
102
- throw new Error(`Unsupported type: ${item.utype}`);
103
- }
104
- }
65
+ try {
66
+ // Initialize TFHE if needed
67
+ await initTfhe();
105
68
 
106
- // THE HEAVY OPERATION - but in worker thread!
107
- const metadataBytes = new Uint8Array(metadata);
108
- const compactList = builder.build_with_proof_packed(crs, metadataBytes, 1);
69
+ if (!tfheModule) {
70
+ throw new Error('TFHE module not initialized');
71
+ }
109
72
 
110
- // Serialize result
111
- const result = compactList.serialize();
73
+ // Deserialize FHE public key and CRS from hex strings
74
+ const fheKeyBytes = fromHexString(fheKeyHex);
75
+ const crsBytes = fromHexString(crsHex);
76
+
77
+ const fheKey = tfheModule.TfheCompactPublicKey.safe_deserialize(
78
+ fheKeyBytes,
79
+ TFHE_RS_SAFE_SERIALIZATION_SIZE_LIMIT
80
+ );
81
+ const crs = tfheModule.CompactPkeCrs.safe_deserialize(crsBytes, TFHE_RS_SAFE_SERIALIZATION_SIZE_LIMIT);
82
+
83
+ // Create builder
84
+ const builder = tfheModule.ProvenCompactCiphertextList.builder(fheKey);
85
+
86
+ // Pack all items (duplicate of zkPack logic)
87
+ for (const item of items) {
88
+ switch (item.utype) {
89
+ case 'bool':
90
+ builder.push_boolean(Boolean(item.data));
91
+ break;
92
+ case 'uint8':
93
+ builder.push_u8(Number(item.data));
94
+ break;
95
+ case 'uint16':
96
+ builder.push_u16(Number(item.data));
97
+ break;
98
+ case 'uint32':
99
+ builder.push_u32(Number(item.data));
100
+ break;
101
+ case 'uint64':
102
+ builder.push_u64(BigInt(item.data));
103
+ break;
104
+ case 'uint128':
105
+ builder.push_u128(BigInt(item.data));
106
+ break;
107
+ case 'uint160':
108
+ builder.push_u160(BigInt(item.data));
109
+ break;
110
+ default:
111
+ throw new Error(`Unsupported type: ${item.utype}`);
112
+ }
113
+ }
112
114
 
113
- // Send success response
114
- self.postMessage({
115
- id,
116
- type: 'success',
117
- result: Array.from(result),
118
- } as ZkProveWorkerResponse);
119
- } catch (error) {
120
- // Send error response
121
- self.postMessage({
122
- id,
123
- type: 'error',
124
- error: error instanceof Error ? error.message : String(error),
125
- } as ZkProveWorkerResponse);
126
- }
127
- };
115
+ // THE HEAVY OPERATION - but in worker thread!
116
+ const metadataBytes = new Uint8Array(metadata);
117
+ const compactList = builder.build_with_proof_packed(crs, metadataBytes, 1);
118
+
119
+ // Serialize result
120
+ const result = compactList.safe_serialize(TFHE_RS_SAFE_SERIALIZATION_SIZE_LIMIT);
121
+
122
+ // Send success response
123
+ self.postMessage({
124
+ id,
125
+ type: 'success',
126
+ result: Array.from(result),
127
+ } as ZkProveWorkerResponse);
128
+ } catch (error) {
129
+ // Send error response
130
+ self.postMessage({
131
+ id,
132
+ type: 'error',
133
+ error: error instanceof Error ? error.message : String(error),
134
+ } as ZkProveWorkerResponse);
135
+ }
136
+ };
128
137
 
129
- // Signal ready - send proper message format
130
- self.postMessage({
131
- id: 'init',
132
- type: 'ready',
133
- } as ZkProveWorkerResponse);
138
+ // Signal ready - send proper message format
139
+ self.postMessage({
140
+ id: 'init',
141
+ type: 'ready',
142
+ } as ZkProveWorkerResponse);
143
+ }
@@ -1,147 +0,0 @@
1
- import { type CofheClient, CofheError, CofheErrorCode } from '@/core';
2
- import { arbSepolia as cofheArbSepolia } from '@/chains';
3
-
4
- import { describe, it, expect, beforeAll, beforeEach, vi } from 'vitest';
5
- import type { PublicClient, WalletClient } from 'viem';
6
- import { createPublicClient, createWalletClient, http } from 'viem';
7
- import { privateKeyToAccount } from 'viem/accounts';
8
- import { arbitrumSepolia as viemArbitrumSepolia } from 'viem/chains';
9
- import { createCofheClient, createCofheConfig } from './index.js';
10
-
11
- // Real test setup - no mocks
12
- const TEST_PRIVATE_KEY = '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80';
13
- const TEST_ACCOUNT = privateKeyToAccount(TEST_PRIVATE_KEY).address;
14
-
15
- describe('@cofhe/node - Client Integration Tests', () => {
16
- let cofheClient: CofheClient;
17
- let publicClient: PublicClient;
18
- let walletClient: WalletClient;
19
-
20
- beforeAll(() => {
21
- // Create real viem clients
22
- publicClient = createPublicClient({
23
- chain: viemArbitrumSepolia,
24
- transport: http(),
25
- });
26
-
27
- const account = privateKeyToAccount(TEST_PRIVATE_KEY);
28
- walletClient = createWalletClient({
29
- chain: viemArbitrumSepolia,
30
- transport: http(),
31
- account,
32
- });
33
- });
34
-
35
- beforeEach(() => {
36
- const config = createCofheConfig({
37
- supportedChains: [cofheArbSepolia],
38
- });
39
- cofheClient = createCofheClient(config);
40
- });
41
-
42
- describe('Real Client Initialization', () => {
43
- it('should create a client with real node-tfhe', () => {
44
- expect(cofheClient).toBeDefined();
45
- expect(cofheClient.config).toBeDefined();
46
- expect(cofheClient.connected).toBe(false);
47
- });
48
-
49
- it('should automatically use filesystem storage as default', () => {
50
- expect(cofheClient.config.fheKeyStorage).toBeDefined();
51
- expect(cofheClient.config.fheKeyStorage).not.toBeNull();
52
- });
53
-
54
- it('should have all expected methods', () => {
55
- expect(typeof cofheClient.connect).toBe('function');
56
- expect(typeof cofheClient.encryptInputs).toBe('function');
57
- expect(typeof cofheClient.decryptForView).toBe('function');
58
- expect(typeof cofheClient.getSnapshot).toBe('function');
59
- expect(typeof cofheClient.subscribe).toBe('function');
60
- });
61
- });
62
-
63
- describe('Environment', () => {
64
- it('should have the correct environment', () => {
65
- expect(cofheClient.config.environment).toBe('node');
66
- });
67
- });
68
-
69
- describe('Real Connection', () => {
70
- it('should connect to real chain', async () => {
71
- await cofheClient.connect(publicClient, walletClient);
72
-
73
- expect(cofheClient.connected).toBe(true);
74
-
75
- const snapshot = cofheClient.getSnapshot();
76
- expect(snapshot.connected).toBe(true);
77
- expect(snapshot.chainId).toBe(cofheArbSepolia.id);
78
- expect(snapshot.account).toBe(TEST_ACCOUNT);
79
- }, 30000);
80
-
81
- it('should handle real network errors', async () => {
82
- try {
83
- await cofheClient.connect(
84
- {
85
- getChainId: vi.fn().mockRejectedValue(new Error('Network error')),
86
- } as unknown as PublicClient,
87
- walletClient
88
- );
89
- } catch (error) {
90
- expect(error).toBeInstanceOf(CofheError);
91
- expect((error as CofheError).code).toBe(CofheErrorCode.PublicWalletGetChainIdFailed);
92
- }
93
- }, 30000);
94
- });
95
-
96
- describe('State Management', () => {
97
- it('should track connection state changes', async () => {
98
- const states: any[] = [];
99
- const unsubscribe = cofheClient.subscribe((snapshot) => {
100
- states.push({ ...snapshot });
101
- });
102
-
103
- await cofheClient.connect(publicClient, walletClient);
104
-
105
- unsubscribe();
106
-
107
- expect(states.length).toBeGreaterThan(0);
108
-
109
- // First state should be connecting
110
- const firstState = states.find((s) => s.connecting);
111
- expect(firstState).toBeDefined();
112
- expect(firstState?.connecting).toBe(true);
113
- expect(firstState?.connected).toBe(false);
114
-
115
- // Last state should be connected
116
- const lastState = states[states.length - 1];
117
- expect(lastState.connected).toBe(true);
118
- expect(lastState.connecting).toBe(false);
119
- expect(lastState.chainId).toBe(cofheArbSepolia.id);
120
- }, 30000);
121
- });
122
-
123
- describe('Builder Creation', () => {
124
- it('should create encrypt builder after connection', async () => {
125
- await cofheClient.connect(publicClient, walletClient);
126
-
127
- const builder = cofheClient.encryptInputs([{ data: 100n, utype: 2, securityZone: 0 }]);
128
-
129
- expect(builder).toBeDefined();
130
- expect(typeof builder.setChainId).toBe('function');
131
- expect(typeof builder.setAccount).toBe('function');
132
- expect(typeof builder.setSecurityZone).toBe('function');
133
- expect(typeof builder.execute).toBe('function');
134
- }, 30000);
135
-
136
- it('should create decrypt builder after connection', async () => {
137
- await cofheClient.connect(publicClient, walletClient);
138
-
139
- const builder = cofheClient.decryptForView('0x123', 2);
140
-
141
- expect(builder).toBeDefined();
142
- expect(typeof builder.setChainId).toBe('function');
143
- expect(typeof builder.setAccount).toBe('function');
144
- expect(typeof builder.execute).toBe('function');
145
- }, 30000);
146
- });
147
- });
@@ -1,68 +0,0 @@
1
- import { arbSepolia } from '@/chains';
2
-
3
- import { describe, it, expect } from 'vitest';
4
- import { createCofheConfig, createCofheClient } from './index.js';
5
-
6
- describe('@cofhe/node - Config', () => {
7
- describe('createCofheConfig', () => {
8
- it('should automatically inject filesystem storage as default', () => {
9
- const config = createCofheConfig({
10
- supportedChains: [arbSepolia],
11
- });
12
-
13
- expect(config.fheKeyStorage).toBeDefined();
14
- expect(config.fheKeyStorage).not.toBeNull();
15
- expect(config.supportedChains).toEqual([arbSepolia]);
16
- });
17
-
18
- it('should allow overriding storage', async () => {
19
- const customStorage = {
20
- getItem: () => Promise.resolve(10),
21
- setItem: () => Promise.resolve(),
22
- removeItem: () => Promise.resolve(),
23
- };
24
- const config = createCofheConfig({
25
- supportedChains: [arbSepolia],
26
- fheKeyStorage: customStorage,
27
- });
28
-
29
- expect(await config.fheKeyStorage!.getItem('test')).toBe(10);
30
- });
31
-
32
- it('should allow null storage', () => {
33
- const config = createCofheConfig({
34
- supportedChains: [arbSepolia],
35
- fheKeyStorage: null,
36
- });
37
-
38
- expect(config.fheKeyStorage).toBeNull();
39
- });
40
-
41
- it('should preserve all other config options', () => {
42
- const config = createCofheConfig({
43
- supportedChains: [arbSepolia],
44
- mocks: {
45
- decryptDelay: 0,
46
- },
47
- });
48
-
49
- expect(config.supportedChains).toEqual([arbSepolia]);
50
- expect(config.mocks.decryptDelay).toBe(0);
51
- expect(config.fheKeyStorage).toBeDefined();
52
- });
53
- });
54
-
55
- describe('createCofheClient with config', () => {
56
- it('should create client with validated config', () => {
57
- const config = createCofheConfig({
58
- supportedChains: [arbSepolia],
59
- });
60
-
61
- const client = createCofheClient(config);
62
-
63
- expect(client).toBeDefined();
64
- expect(client.config).toBe(config);
65
- expect(client.config.fheKeyStorage).toBeDefined();
66
- });
67
- });
68
- });
@@ -1,155 +0,0 @@
1
- import { Encryptable, FheTypes, type CofheClient, CofheErrorCode, CofheError } from '@/core';
2
- import { arbSepolia as cofheArbSepolia } from '@/chains';
3
-
4
- import { describe, it, expect, beforeAll, beforeEach } from 'vitest';
5
- import type { PublicClient, WalletClient } from 'viem';
6
- import { createPublicClient, createWalletClient, http } from 'viem';
7
- import { privateKeyToAccount } from 'viem/accounts';
8
- import { arbitrumSepolia as viemArbitrumSepolia } from 'viem/chains';
9
- import { createCofheClient, createCofheConfig } from './index.js';
10
-
11
- // Real test setup - using actual node-tfhe
12
- const TEST_PRIVATE_KEY = '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80';
13
-
14
- describe('@cofhe/node - Encrypt Inputs', () => {
15
- let cofheClient: CofheClient;
16
- let publicClient: PublicClient;
17
- let walletClient: WalletClient;
18
-
19
- beforeAll(() => {
20
- // Create real viem clients
21
- publicClient = createPublicClient({
22
- chain: viemArbitrumSepolia,
23
- transport: http(),
24
- });
25
-
26
- const account = privateKeyToAccount(TEST_PRIVATE_KEY);
27
- walletClient = createWalletClient({
28
- chain: viemArbitrumSepolia,
29
- transport: http(),
30
- account,
31
- });
32
- });
33
-
34
- beforeEach(() => {
35
- const config = createCofheConfig({
36
- supportedChains: [cofheArbSepolia],
37
- });
38
- cofheClient = createCofheClient(config);
39
- });
40
-
41
- describe('Real TFHE Initialization', () => {
42
- it('should initialize node-tfhe on first encryption', async () => {
43
- await cofheClient.connect(publicClient, walletClient);
44
-
45
- // This will trigger real TFHE initialization
46
- const encrypted = await cofheClient.encryptInputs([Encryptable.uint128(100n)]).execute();
47
-
48
- // If we get here, TFHE was initialized successfully
49
- expect(encrypted).toBeDefined();
50
- }, 60000); // Longer timeout for real operations
51
-
52
- it('should handle multiple encryptions without re-initializing', async () => {
53
- await cofheClient.connect(publicClient, walletClient);
54
-
55
- // First encryption
56
- await cofheClient.encryptInputs([Encryptable.uint128(100n)]).execute();
57
-
58
- // Second encryption should reuse initialization
59
- await cofheClient.encryptInputs([Encryptable.uint64(50n)]).execute();
60
- }, 120000);
61
- });
62
-
63
- describe('Real Encryption', () => {
64
- it('should encrypt a bool with real TFHE', async () => {
65
- await cofheClient.connect(publicClient, walletClient);
66
-
67
- const encrypted = await cofheClient.encryptInputs([Encryptable.bool(true)]).execute();
68
-
69
- expect(encrypted.length).toBe(1);
70
- expect(encrypted[0].utype).toBe(FheTypes.Bool);
71
- expect(encrypted[0].ctHash).toBeDefined();
72
- expect(typeof encrypted[0].ctHash).toBe('bigint');
73
- expect(encrypted[0].signature).toBeDefined();
74
- expect(typeof encrypted[0].signature).toBe('string');
75
- expect(encrypted[0].securityZone).toBe(0);
76
- }, 60000);
77
-
78
- it('should encrypt all supported types together', async () => {
79
- await cofheClient.connect(publicClient, walletClient);
80
-
81
- const inputs = [
82
- Encryptable.bool(false),
83
- Encryptable.uint8(1n),
84
- Encryptable.uint16(2n),
85
- Encryptable.uint32(3n),
86
- Encryptable.uint64(4n),
87
- Encryptable.uint128(5n),
88
- Encryptable.address('0x742d35Cc6634C0532925a3b844D16faC4c175E99'),
89
- ];
90
-
91
- const encrypted = await cofheClient.encryptInputs(inputs).execute();
92
-
93
- expect(encrypted.length).toBe(7);
94
- // Verify each type
95
- expect(encrypted[0].utype).toBe(FheTypes.Bool);
96
- expect(encrypted[1].utype).toBe(FheTypes.Uint8);
97
- expect(encrypted[2].utype).toBe(FheTypes.Uint16);
98
- expect(encrypted[3].utype).toBe(FheTypes.Uint32);
99
- expect(encrypted[4].utype).toBe(FheTypes.Uint64);
100
- expect(encrypted[5].utype).toBe(FheTypes.Uint128);
101
- expect(encrypted[6].utype).toBe(FheTypes.Uint160);
102
- }, 90000); // Longer timeout for multiple encryptions
103
- });
104
-
105
- describe('Real Builder Pattern', () => {
106
- it('should support chaining builder methods with real encryption', async () => {
107
- await cofheClient.connect(publicClient, walletClient);
108
-
109
- const snapshot = cofheClient.getSnapshot();
110
- const encrypted = await cofheClient
111
- .encryptInputs([Encryptable.uint128(100n)])
112
- .setChainId(snapshot.chainId!)
113
- .setAccount(snapshot.account!)
114
- .setSecurityZone(0)
115
- .execute();
116
-
117
- expect(encrypted.length).toBe(1);
118
- expect(encrypted[0].utype).toBe(FheTypes.Uint128);
119
- }, 60000);
120
- });
121
-
122
- describe('Real Error Handling', () => {
123
- it('should fail gracefully when not connected', async () => {
124
- // Don't connect the client
125
- try {
126
- await cofheClient.encryptInputs([Encryptable.uint128(100n)]).execute();
127
- } catch (error) {
128
- expect(error).toBeInstanceOf(CofheError);
129
- expect((error as CofheError).code).toBe(CofheErrorCode.NotConnected);
130
- }
131
- }, 30000);
132
-
133
- it('should handle invalid CoFHE URL', async () => {
134
- const badConfig = createCofheConfig({
135
- supportedChains: [
136
- {
137
- ...cofheArbSepolia,
138
- coFheUrl: 'http://invalid-cofhe-url.local',
139
- verifierUrl: 'http://invalid-verifier-url.local',
140
- },
141
- ],
142
- });
143
-
144
- const badClient = createCofheClient(badConfig);
145
- await badClient.connect(publicClient, walletClient);
146
-
147
- try {
148
- await badClient.encryptInputs([Encryptable.uint128(100n)]).execute();
149
- } catch (error) {
150
- expect(error).toBeInstanceOf(CofheError);
151
- expect((error as CofheError).code).toBe(CofheErrorCode.ZkVerifyFailed);
152
- }
153
- }, 60000);
154
- });
155
- });
@@ -1,69 +0,0 @@
1
- import { arbSepolia } from '@/chains';
2
-
3
- import { describe, it, expect } from 'vitest';
4
- import { createCofheConfig, createCofheClient } from './index.js';
5
-
6
- describe('@cofhe/web - Config', () => {
7
- describe('createCofheConfig', () => {
8
- it('should automatically inject IndexedDB storage as default', () => {
9
- const config = createCofheConfig({
10
- supportedChains: [arbSepolia],
11
- });
12
-
13
- expect(config.fheKeyStorage).toBeDefined();
14
- expect(config.fheKeyStorage).not.toBeNull();
15
- expect(config.supportedChains).toEqual([arbSepolia]);
16
- });
17
-
18
- it('should allow overriding storage', async () => {
19
- const customStorage = {
20
- getItem: () => Promise.resolve(10),
21
- setItem: () => Promise.resolve(),
22
- removeItem: () => Promise.resolve(),
23
- };
24
-
25
- const config = createCofheConfig({
26
- supportedChains: [arbSepolia],
27
- fheKeyStorage: customStorage,
28
- });
29
-
30
- expect(await config.fheKeyStorage!.getItem('test')).toBe(10);
31
- });
32
-
33
- it('should allow null storage', () => {
34
- const config = createCofheConfig({
35
- supportedChains: [arbSepolia],
36
- fheKeyStorage: null,
37
- });
38
-
39
- expect(config.fheKeyStorage).toBeNull();
40
- });
41
-
42
- it('should preserve all other config options', () => {
43
- const config = createCofheConfig({
44
- supportedChains: [arbSepolia],
45
- mocks: {
46
- decryptDelay: 500,
47
- },
48
- });
49
-
50
- expect(config.supportedChains).toEqual([arbSepolia]);
51
- expect(config.mocks.decryptDelay).toBe(500);
52
- expect(config.fheKeyStorage).toBeDefined();
53
- });
54
- });
55
-
56
- describe('createCofheClient with config', () => {
57
- it('should create client with validated config', () => {
58
- const config = createCofheConfig({
59
- supportedChains: [arbSepolia],
60
- });
61
-
62
- const client = createCofheClient(config);
63
-
64
- expect(client).toBeDefined();
65
- expect(client.config).toBe(config);
66
- expect(client.config.fheKeyStorage).toBeDefined();
67
- });
68
- });
69
- });