@cofhe/sdk 0.4.0 → 0.5.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/CHANGELOG.md +32 -0
- package/adapters/{ethers5.test.ts → test/ethers5.test.ts} +2 -2
- package/adapters/{ethers6.test.ts → test/ethers6.test.ts} +2 -2
- package/adapters/{hardhat.hh2.test.ts → test/hardhat.hh2.test.ts} +2 -2
- package/adapters/{index.test.ts → test/index.test.ts} +1 -1
- package/adapters/{wagmi.test.ts → test/wagmi.test.ts} +1 -1
- package/chains/{chains.test.ts → test/chains.test.ts} +1 -1
- package/core/client.ts +11 -1
- package/core/clientTypes.ts +3 -1
- package/core/consts.ts +9 -0
- package/core/decrypt/cofheMocksDecryptForTx.ts +14 -3
- package/core/decrypt/decryptForTxBuilder.ts +16 -2
- package/core/decrypt/decryptForViewBuilder.ts +14 -7
- package/core/decrypt/polling.ts +14 -0
- package/core/decrypt/tnDecryptV2.ts +250 -110
- package/core/decrypt/tnSealOutputV2.ts +245 -104
- package/core/decrypt/verifyDecryptResult.ts +65 -0
- package/core/encrypt/cofheMocksZkVerifySign.ts +6 -6
- package/core/encrypt/zkPackProveVerify.ts +10 -19
- package/core/fetchKeys.ts +0 -2
- package/core/index.ts +9 -1
- package/core/keyStore.ts +5 -2
- package/core/permits.ts +5 -0
- package/core/{client.test.ts → test/client.test.ts} +7 -7
- package/core/{config.test.ts → test/config.test.ts} +1 -1
- package/core/test/decrypt.test.ts +252 -0
- package/core/test/decryptBuilders.test.ts +390 -0
- package/core/{encrypt → test}/encryptInputsBuilder.test.ts +61 -6
- package/core/{fetchKeys.test.ts → test/fetchKeys.test.ts} +3 -3
- package/core/{keyStore.test.ts → test/keyStore.test.ts} +5 -3
- package/core/{permits.test.ts → test/permits.test.ts} +42 -1
- package/core/test/pollCallbacks.test.ts +563 -0
- package/core/types.ts +13 -0
- package/dist/chains.d.cts +2 -2
- package/dist/chains.d.ts +2 -2
- package/dist/chunk-4FP4V35O.js +13 -0
- package/dist/{chunk-NWDKXBIP.js → chunk-MRCKUMOS.js} +62 -22
- package/dist/{chunk-MXND5SVN.js → chunk-S7OKGLFD.js} +485 -207
- package/dist/{clientTypes-kkrRdawm.d.ts → clientTypes-BSbwairE.d.cts} +23 -6
- package/dist/{clientTypes-ACVWbrXL.d.cts → clientTypes-DDmcgZ0a.d.ts} +23 -6
- package/dist/core.cjs +561 -244
- package/dist/core.d.cts +24 -6
- package/dist/core.d.ts +24 -6
- package/dist/core.js +3 -2
- package/dist/node.cjs +566 -246
- package/dist/node.d.cts +3 -3
- package/dist/node.d.ts +3 -3
- package/dist/node.js +14 -7
- package/dist/{permit-MZ502UBl.d.cts → permit-DnVMDT5h.d.cts} +34 -4
- package/dist/{permit-MZ502UBl.d.ts → permit-DnVMDT5h.d.ts} +34 -4
- package/dist/permits.cjs +66 -29
- package/dist/permits.d.cts +18 -13
- package/dist/permits.d.ts +18 -13
- package/dist/permits.js +2 -1
- package/dist/web.cjs +588 -251
- package/dist/web.d.cts +8 -4
- package/dist/web.d.ts +8 -4
- package/dist/web.js +34 -11
- package/dist/zkProve.worker.cjs +6 -3
- package/dist/zkProve.worker.js +5 -3
- package/node/index.ts +13 -4
- package/node/test/client.test.ts +25 -0
- package/node/test/config.test.ts +16 -0
- package/node/test/inherited.test.ts +244 -0
- package/node/test/tfheinit.test.ts +56 -0
- package/package.json +24 -22
- package/permits/permit.ts +31 -5
- package/permits/sealing.ts +1 -1
- package/permits/{localstorage.test.ts → test/localstorage.test.ts} +2 -2
- package/permits/{permit.test.ts → test/permit.test.ts} +35 -1
- package/permits/{sealing.test.ts → test/sealing.test.ts} +1 -1
- package/permits/{store.test.ts → test/store.test.ts} +2 -2
- package/permits/{validation.test.ts → test/validation.test.ts} +82 -6
- package/permits/types.ts +1 -1
- package/permits/validation.ts +42 -2
- package/web/const.ts +2 -0
- package/web/index.ts +20 -6
- package/web/storage.ts +18 -3
- package/web/{client.web.test.ts → test/client.web.test.ts} +13 -1
- package/web/test/config.web.test.ts +16 -0
- package/web/test/inherited.web.test.ts +245 -0
- package/web/test/tfheinit.web.test.ts +62 -0
- package/web/{worker.config.web.test.ts → test/worker.config.web.test.ts} +1 -1
- package/web/{worker.output.web.test.ts → test/worker.output.web.test.ts} +1 -1
- package/web/{workerManager.test.ts → test/workerManager.test.ts} +1 -1
- package/web/{workerManager.web.test.ts → test/workerManager.web.test.ts} +1 -1
- package/web/zkProve.worker.ts +4 -3
- package/node/client.test.ts +0 -147
- package/node/config.test.ts +0 -68
- package/node/encryptInputs.test.ts +0 -155
- package/web/config.web.test.ts +0 -69
- package/web/encryptInputs.web.test.ts +0 -172
- package/web/worker.builder.web.test.ts +0 -148
- /package/dist/{types-YiAC4gig.d.cts → types-C07FK-cL.d.cts} +0 -0
- /package/dist/{types-YiAC4gig.d.ts → types-C07FK-cL.d.ts} +0 -0
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
import { Encryptable, FheTypes, type CofheClient } from '@/core';
|
|
2
|
+
import { arbSepolia as cofheArbSepolia, getChainById } from '@/chains';
|
|
3
|
+
import {
|
|
4
|
+
TEST_PRIVATE_KEY,
|
|
5
|
+
PRIMARY_TEST_CHAIN,
|
|
6
|
+
primaryTestChainRegistry,
|
|
7
|
+
isPrimaryTestChainReady,
|
|
8
|
+
} from '@cofhe/test-setup';
|
|
9
|
+
|
|
10
|
+
import { createCofheClient, createCofheConfig } from '../index.js';
|
|
11
|
+
|
|
12
|
+
import { describe, it, expect, beforeAll, beforeEach } from 'vitest';
|
|
13
|
+
import type { Chain, PublicClient, WalletClient } from 'viem';
|
|
14
|
+
import { createPublicClient, createWalletClient, http } from 'viem';
|
|
15
|
+
import { privateKeyToAccount } from 'viem/accounts';
|
|
16
|
+
import { arbitrumSepolia, baseSepolia, sepolia } from 'viem/chains';
|
|
17
|
+
|
|
18
|
+
const DEFAULT_TEST_PRIVATE_KEY = '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80';
|
|
19
|
+
const BOB_PRIVATE_KEY = (TEST_PRIVATE_KEY || DEFAULT_TEST_PRIVATE_KEY) as `0x${string}`;
|
|
20
|
+
const ALICE_PRIVATE_KEY = '0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d';
|
|
21
|
+
|
|
22
|
+
const bobAccount = privateKeyToAccount(BOB_PRIVATE_KEY);
|
|
23
|
+
const aliceAccount = privateKeyToAccount(ALICE_PRIVATE_KEY);
|
|
24
|
+
|
|
25
|
+
const VIEM_CHAINS: Record<number, Chain> = {
|
|
26
|
+
421614: arbitrumSepolia,
|
|
27
|
+
84532: baseSepolia,
|
|
28
|
+
11155111: sepolia,
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
describe('@cofhe/web - Inherited Client Tests', () => {
|
|
32
|
+
let cofheClient: CofheClient;
|
|
33
|
+
let publicClient: PublicClient;
|
|
34
|
+
let bobWalletClient: WalletClient;
|
|
35
|
+
let aliceWalletClient: WalletClient;
|
|
36
|
+
|
|
37
|
+
beforeAll(() => {
|
|
38
|
+
publicClient = createPublicClient({
|
|
39
|
+
chain: arbitrumSepolia,
|
|
40
|
+
transport: http(),
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
bobWalletClient = createWalletClient({
|
|
44
|
+
chain: arbitrumSepolia,
|
|
45
|
+
transport: http(),
|
|
46
|
+
account: bobAccount,
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
aliceWalletClient = createWalletClient({
|
|
50
|
+
chain: arbitrumSepolia,
|
|
51
|
+
transport: http(),
|
|
52
|
+
account: aliceAccount,
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
beforeEach(() => {
|
|
57
|
+
const config = createCofheConfig({
|
|
58
|
+
supportedChains: [cofheArbSepolia],
|
|
59
|
+
});
|
|
60
|
+
cofheClient = createCofheClient(config);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
describe('Client Creation', () => {
|
|
64
|
+
it('should create a client with expected surface', () => {
|
|
65
|
+
expect(cofheClient).toBeDefined();
|
|
66
|
+
expect(cofheClient.config).toBeDefined();
|
|
67
|
+
expect(cofheClient.connected).toBe(false);
|
|
68
|
+
expect(typeof cofheClient.connect).toBe('function');
|
|
69
|
+
expect(typeof cofheClient.disconnect).toBe('function');
|
|
70
|
+
expect(typeof cofheClient.encryptInputs).toBe('function');
|
|
71
|
+
expect(typeof cofheClient.decryptForView).toBe('function');
|
|
72
|
+
expect(typeof cofheClient.decryptForTx).toBe('function');
|
|
73
|
+
expect(typeof cofheClient.getSnapshot).toBe('function');
|
|
74
|
+
expect(typeof cofheClient.subscribe).toBe('function');
|
|
75
|
+
expect(cofheClient.permits).toBeDefined();
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
describe('Connection', () => {
|
|
80
|
+
it('should connect to a real chain', async () => {
|
|
81
|
+
await cofheClient.connect(publicClient, bobWalletClient);
|
|
82
|
+
|
|
83
|
+
expect(cofheClient.connected).toBe(true);
|
|
84
|
+
|
|
85
|
+
const snapshot = cofheClient.getSnapshot();
|
|
86
|
+
expect(snapshot.connected).toBe(true);
|
|
87
|
+
expect(snapshot.chainId).toBe(cofheArbSepolia.id);
|
|
88
|
+
expect(snapshot.account).toBe(bobAccount.address);
|
|
89
|
+
}, 30000);
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
describe('Encrypt Input', () => {
|
|
93
|
+
it('should encrypt a uint128 value', async () => {
|
|
94
|
+
await cofheClient.connect(publicClient, bobWalletClient);
|
|
95
|
+
|
|
96
|
+
const encrypted = await cofheClient.encryptInputs([Encryptable.uint128(100n)]).execute();
|
|
97
|
+
|
|
98
|
+
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);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
describe('Self Permit', () => {
|
|
110
|
+
it('should create a self permit', async () => {
|
|
111
|
+
await cofheClient.connect(publicClient, bobWalletClient);
|
|
112
|
+
|
|
113
|
+
const permit = await cofheClient.permits.createSelf({
|
|
114
|
+
issuer: bobAccount.address,
|
|
115
|
+
name: 'Test Self Permit',
|
|
116
|
+
});
|
|
117
|
+
|
|
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);
|
|
129
|
+
}, 30000);
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
describe('Sharing Permit', () => {
|
|
133
|
+
it('should create a sharing permit, export it, and import it as another user', async () => {
|
|
134
|
+
await cofheClient.connect(publicClient, bobWalletClient);
|
|
135
|
+
|
|
136
|
+
const sharingPermit = await cofheClient.permits.createSharing({
|
|
137
|
+
issuer: bobAccount.address,
|
|
138
|
+
recipient: aliceAccount.address,
|
|
139
|
+
name: 'Test Sharing Permit',
|
|
140
|
+
});
|
|
141
|
+
|
|
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');
|
|
147
|
+
|
|
148
|
+
const exported = cofheClient.permits.export(sharingPermit);
|
|
149
|
+
expect(exported).toBeDefined();
|
|
150
|
+
const parsed = JSON.parse(exported);
|
|
151
|
+
expect(parsed.type).toBe('sharing');
|
|
152
|
+
expect(parsed.issuer).toBe(bobAccount.address);
|
|
153
|
+
expect(parsed.recipient).toBe(aliceAccount.address);
|
|
154
|
+
expect(parsed.issuerSignature).toBeDefined();
|
|
155
|
+
expect(parsed).not.toHaveProperty('sealingPair');
|
|
156
|
+
|
|
157
|
+
const aliceConfig = createCofheConfig({
|
|
158
|
+
supportedChains: [cofheArbSepolia],
|
|
159
|
+
});
|
|
160
|
+
const aliceClient = createCofheClient(aliceConfig);
|
|
161
|
+
await aliceClient.connect(publicClient, aliceWalletClient);
|
|
162
|
+
|
|
163
|
+
const importedPermit = await aliceClient.permits.importShared(exported);
|
|
164
|
+
|
|
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();
|
|
171
|
+
}, 30000);
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
describe('Decrypt (read-only, pre-stored values)', () => {
|
|
175
|
+
let decryptClient: CofheClient;
|
|
176
|
+
let decryptPublicClient: PublicClient;
|
|
177
|
+
let decryptWalletClient: WalletClient;
|
|
178
|
+
|
|
179
|
+
let privateCtHash: `0x${string}`;
|
|
180
|
+
let privateValue: bigint;
|
|
181
|
+
let publicCtHash: `0x${string}`;
|
|
182
|
+
let publicValue: bigint;
|
|
183
|
+
|
|
184
|
+
beforeAll(() => {
|
|
185
|
+
if (!isPrimaryTestChainReady(primaryTestChainRegistry)) {
|
|
186
|
+
throw new Error('Primary test chain registry not initialized. Run `pnpm test:setup` first.');
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
const reg = primaryTestChainRegistry;
|
|
190
|
+
const viemChain = VIEM_CHAINS[reg.chainId];
|
|
191
|
+
if (!viemChain) throw new Error(`No viem chain mapping for chain ${reg.chainId}`);
|
|
192
|
+
|
|
193
|
+
const cofheChain = getChainById(reg.chainId);
|
|
194
|
+
if (!cofheChain) throw new Error(`No cofhe chain config for chain ${reg.chainId}`);
|
|
195
|
+
|
|
196
|
+
privateCtHash = reg.privateValue.ctHash as `0x${string}`;
|
|
197
|
+
privateValue = BigInt(reg.privateValue.value);
|
|
198
|
+
publicCtHash = reg.publicValue.ctHash as `0x${string}`;
|
|
199
|
+
publicValue = BigInt(reg.publicValue.value);
|
|
200
|
+
|
|
201
|
+
decryptPublicClient = createPublicClient({ chain: viemChain, transport: http() });
|
|
202
|
+
decryptWalletClient = createWalletClient({ chain: viemChain, transport: http(), account: bobAccount });
|
|
203
|
+
|
|
204
|
+
const config = createCofheConfig({ supportedChains: [cofheChain] });
|
|
205
|
+
decryptClient = createCofheClient(config);
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
it('decryptForView — private value with permit', async () => {
|
|
209
|
+
await decryptClient.connect(decryptPublicClient, decryptWalletClient);
|
|
210
|
+
|
|
211
|
+
await decryptClient.permits.createSelf({
|
|
212
|
+
issuer: bobAccount.address,
|
|
213
|
+
name: 'Decrypt View Permit',
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
const result = await decryptClient.decryptForView(privateCtHash, FheTypes.Uint32).execute();
|
|
217
|
+
expect(result).toBe(privateValue);
|
|
218
|
+
}, 180000);
|
|
219
|
+
|
|
220
|
+
it('decryptForTx — public value without permit', async () => {
|
|
221
|
+
await decryptClient.connect(decryptPublicClient, decryptWalletClient);
|
|
222
|
+
|
|
223
|
+
const result = await decryptClient.decryptForTx(publicCtHash).withoutPermit().execute();
|
|
224
|
+
|
|
225
|
+
expect(BigInt(result.ctHash)).toBe(BigInt(publicCtHash));
|
|
226
|
+
expect(result.decryptedValue).toBe(publicValue);
|
|
227
|
+
expect(result.signature).toMatch(/^0x[0-9a-fA-F]+$/);
|
|
228
|
+
}, 180000);
|
|
229
|
+
|
|
230
|
+
it('decryptForTx — private value with permit', async () => {
|
|
231
|
+
await decryptClient.connect(decryptPublicClient, decryptWalletClient);
|
|
232
|
+
|
|
233
|
+
const permit = await decryptClient.permits.createSelf({
|
|
234
|
+
issuer: bobAccount.address,
|
|
235
|
+
name: 'Decrypt Tx Permit',
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
const result = await decryptClient.decryptForTx(privateCtHash).withPermit(permit).execute();
|
|
239
|
+
|
|
240
|
+
expect(BigInt(result.ctHash)).toBe(BigInt(privateCtHash));
|
|
241
|
+
expect(result.decryptedValue).toBe(privateValue);
|
|
242
|
+
expect(result.signature).toBeDefined();
|
|
243
|
+
}, 180000);
|
|
244
|
+
});
|
|
245
|
+
});
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { arbSepolia as cofheArbSepolia } from '@/chains';
|
|
2
|
+
import { Encryptable, FheTypes, type CofheClient, CofheErrorCode, CofheError } from '@/core';
|
|
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 - runs in browser with real tfhe
|
|
12
|
+
const TEST_PRIVATE_KEY = '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80';
|
|
13
|
+
|
|
14
|
+
describe('@cofhe/web - TFHE Initialization Browser Tests', () => {
|
|
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('Browser TFHE Initialization', () => {
|
|
42
|
+
it('should initialize tfhe on first encryption', async () => {
|
|
43
|
+
await cofheClient.connect(publicClient, walletClient);
|
|
44
|
+
|
|
45
|
+
// This will trigger real TFHE initialization in browser
|
|
46
|
+
const result = await cofheClient.encryptInputs([Encryptable.uint128(100n)]).execute();
|
|
47
|
+
|
|
48
|
+
// If we get here, TFHE was initialized successfully
|
|
49
|
+
expect(result).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
|
+
expect(cofheClient.encryptInputs([Encryptable.uint128(100n)]).execute()).resolves.not.toThrow();
|
|
57
|
+
|
|
58
|
+
// Second encryption should reuse initialization
|
|
59
|
+
expect(cofheClient.encryptInputs([Encryptable.uint64(50n)]).execute()).resolves.not.toThrow();
|
|
60
|
+
}, 60000);
|
|
61
|
+
});
|
|
62
|
+
});
|
|
@@ -6,7 +6,7 @@ import type { PublicClient, WalletClient } from 'viem';
|
|
|
6
6
|
import { createPublicClient, createWalletClient, http } from 'viem';
|
|
7
7
|
import { privateKeyToAccount } from 'viem/accounts';
|
|
8
8
|
import { arbitrumSepolia as viemArbitrumSepolia } from 'viem/chains';
|
|
9
|
-
import { createCofheClient, createCofheConfig, createCofheClientWithCustomWorker } from '
|
|
9
|
+
import { createCofheClient, createCofheConfig, createCofheClientWithCustomWorker } from '../index.js';
|
|
10
10
|
|
|
11
11
|
const TEST_PRIVATE_KEY = '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80';
|
|
12
12
|
|
|
@@ -6,7 +6,7 @@ import type { PublicClient, WalletClient } from 'viem';
|
|
|
6
6
|
import { createPublicClient, createWalletClient, http } from 'viem';
|
|
7
7
|
import { privateKeyToAccount } from 'viem/accounts';
|
|
8
8
|
import { arbitrumSepolia as viemArbitrumSepolia } from 'viem/chains';
|
|
9
|
-
import { createCofheClient, createCofheConfig } from '
|
|
9
|
+
import { createCofheClient, createCofheConfig } from '../index.js';
|
|
10
10
|
|
|
11
11
|
const TEST_PRIVATE_KEY = '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80';
|
|
12
12
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { describe, it, expect, afterEach } from 'vitest';
|
|
2
|
-
import { getWorkerManager, terminateWorker, areWorkersAvailable } from '
|
|
2
|
+
import { getWorkerManager, terminateWorker, areWorkersAvailable } from '../workerManager.js';
|
|
3
3
|
|
|
4
4
|
describe('WorkerManager', () => {
|
|
5
5
|
afterEach(() => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { describe, it, expect, afterEach } from 'vitest';
|
|
2
|
-
import { getWorkerManager, terminateWorker, areWorkersAvailable } from '
|
|
2
|
+
import { getWorkerManager, terminateWorker, areWorkersAvailable } from '../workerManager.js';
|
|
3
3
|
|
|
4
4
|
describe('WorkerManager (Browser)', () => {
|
|
5
5
|
afterEach(() => {
|
package/web/zkProve.worker.ts
CHANGED
|
@@ -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)
|
|
@@ -68,8 +69,8 @@ self.onmessage = async (event: MessageEvent) => {
|
|
|
68
69
|
const fheKeyBytes = fromHexString(fheKeyHex);
|
|
69
70
|
const crsBytes = fromHexString(crsHex);
|
|
70
71
|
|
|
71
|
-
const fheKey = tfheModule.TfheCompactPublicKey.
|
|
72
|
-
const crs = tfheModule.CompactPkeCrs.
|
|
72
|
+
const fheKey = tfheModule.TfheCompactPublicKey.safe_deserialize(fheKeyBytes, TFHE_RS_SAFE_SERIALIZATION_SIZE_LIMIT);
|
|
73
|
+
const crs = tfheModule.CompactPkeCrs.safe_deserialize(crsBytes, TFHE_RS_SAFE_SERIALIZATION_SIZE_LIMIT);
|
|
73
74
|
|
|
74
75
|
// Create builder
|
|
75
76
|
const builder = tfheModule.ProvenCompactCiphertextList.builder(fheKey);
|
|
@@ -108,7 +109,7 @@ self.onmessage = async (event: MessageEvent) => {
|
|
|
108
109
|
const compactList = builder.build_with_proof_packed(crs, metadataBytes, 1);
|
|
109
110
|
|
|
110
111
|
// Serialize result
|
|
111
|
-
const result = compactList.
|
|
112
|
+
const result = compactList.safe_serialize(TFHE_RS_SAFE_SERIALIZATION_SIZE_LIMIT);
|
|
112
113
|
|
|
113
114
|
// Send success response
|
|
114
115
|
self.postMessage({
|
package/node/client.test.ts
DELETED
|
@@ -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
|
-
});
|
package/node/config.test.ts
DELETED
|
@@ -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
|
-
});
|