@cofhe/sdk 0.3.2 → 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 +38 -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 +15 -5
- package/core/clientTypes.ts +7 -5
- package/core/consts.ts +9 -0
- package/core/decrypt/cofheMocksDecryptForTx.ts +14 -3
- package/core/decrypt/decryptForTxBuilder.ts +24 -10
- package/core/decrypt/decryptForViewBuilder.ts +14 -7
- package/core/decrypt/polling.ts +14 -0
- package/core/decrypt/tnDecryptUtils.ts +65 -0
- package/core/decrypt/{tnDecrypt.ts → tnDecryptV1.ts} +7 -70
- package/core/decrypt/tnDecryptV2.ts +483 -0
- 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 +8 -3
- 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 +21 -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-LWMRB6SD.js → chunk-S7OKGLFD.js} +615 -198
- package/dist/{clientTypes-Y43CKbOz.d.cts → clientTypes-BSbwairE.d.cts} +38 -13
- package/dist/{clientTypes-PQha8zes.d.ts → clientTypes-DDmcgZ0a.d.ts} +38 -13
- package/dist/core.cjs +691 -235
- package/dist/core.d.cts +24 -6
- package/dist/core.d.ts +24 -6
- package/dist/core.js +3 -2
- package/dist/node.cjs +696 -237
- 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.ts → permit-DnVMDT5h.d.cts} +34 -4
- package/dist/{permit-MZ502UBl.d.cts → 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 +718 -242
- 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,390 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { type PublicClient, type WalletClient, createPublicClient, createWalletClient, http } from 'viem';
|
|
3
|
+
import { privateKeyToAccount } from 'viem/accounts';
|
|
4
|
+
import { arbitrumSepolia } from 'viem/chains';
|
|
5
|
+
import { DecryptForTxBuilder } from '../decrypt/decryptForTxBuilder.js';
|
|
6
|
+
import { DecryptForViewBuilder } from '../decrypt/decryptForViewBuilder.js';
|
|
7
|
+
import { createCofheConfigBase, type CofheConfig } from '../config.js';
|
|
8
|
+
import { CofheErrorCode } from '../error.js';
|
|
9
|
+
import { FheTypes } from '../types.js';
|
|
10
|
+
|
|
11
|
+
const TEST_PRIVATE_KEY = '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80';
|
|
12
|
+
const account = privateKeyToAccount(TEST_PRIVATE_KEY);
|
|
13
|
+
const TEST_CHAIN_ID = 421614;
|
|
14
|
+
const TEST_CT_HASH = '0xabcdef1234567890';
|
|
15
|
+
|
|
16
|
+
const MockCoFheUrl = 'http://localhost:3001';
|
|
17
|
+
|
|
18
|
+
const publicClient: PublicClient = createPublicClient({
|
|
19
|
+
chain: arbitrumSepolia,
|
|
20
|
+
transport: http(),
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
const walletClient: WalletClient = createWalletClient({
|
|
24
|
+
chain: arbitrumSepolia,
|
|
25
|
+
transport: http(),
|
|
26
|
+
account,
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
const mockConfig: CofheConfig = createCofheConfigBase({
|
|
30
|
+
supportedChains: [
|
|
31
|
+
{
|
|
32
|
+
id: TEST_CHAIN_ID,
|
|
33
|
+
name: 'Mock Chain',
|
|
34
|
+
network: 'Mock Network',
|
|
35
|
+
coFheUrl: MockCoFheUrl,
|
|
36
|
+
thresholdNetworkUrl: MockCoFheUrl,
|
|
37
|
+
environment: 'TESTNET',
|
|
38
|
+
verifierUrl: MockCoFheUrl,
|
|
39
|
+
},
|
|
40
|
+
],
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
function createTxBuilder(overrides?: Partial<{ chainId: number; account: string; ctHash: string | bigint }>) {
|
|
44
|
+
return new DecryptForTxBuilder({
|
|
45
|
+
config: mockConfig,
|
|
46
|
+
publicClient,
|
|
47
|
+
walletClient,
|
|
48
|
+
chainId: TEST_CHAIN_ID,
|
|
49
|
+
account: account.address,
|
|
50
|
+
ctHash: TEST_CT_HASH,
|
|
51
|
+
requireConnected: undefined,
|
|
52
|
+
...overrides,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function createViewBuilder<U extends FheTypes>(
|
|
57
|
+
utype: U,
|
|
58
|
+
overrides?: Partial<{ chainId: number; account: string; ctHash: string | bigint }>
|
|
59
|
+
) {
|
|
60
|
+
return new DecryptForViewBuilder<U>({
|
|
61
|
+
config: mockConfig,
|
|
62
|
+
publicClient,
|
|
63
|
+
walletClient,
|
|
64
|
+
chainId: TEST_CHAIN_ID,
|
|
65
|
+
account: account.address,
|
|
66
|
+
ctHash: TEST_CT_HASH,
|
|
67
|
+
utype,
|
|
68
|
+
requireConnected: undefined,
|
|
69
|
+
...overrides,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// ---------------------------------------------------------------------------
|
|
74
|
+
// DecryptForTxBuilder
|
|
75
|
+
// ---------------------------------------------------------------------------
|
|
76
|
+
|
|
77
|
+
describe('DecryptForTxBuilder', () => {
|
|
78
|
+
// --- setChainId / getChainId ---
|
|
79
|
+
|
|
80
|
+
describe('setChainId / getChainId', () => {
|
|
81
|
+
it('should store and return the chainId', () => {
|
|
82
|
+
const builder = createTxBuilder({ chainId: undefined });
|
|
83
|
+
expect(builder.getChainId()).toBeUndefined();
|
|
84
|
+
|
|
85
|
+
builder.setChainId(11155111);
|
|
86
|
+
expect(builder.getChainId()).toBe(11155111);
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
it('should allow overriding', () => {
|
|
90
|
+
const builder = createTxBuilder({ chainId: 1 });
|
|
91
|
+
builder.setChainId(42);
|
|
92
|
+
expect(builder.getChainId()).toBe(42);
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
// --- setAccount / getAccount ---
|
|
97
|
+
|
|
98
|
+
describe('setAccount / getAccount', () => {
|
|
99
|
+
it('should store and return the account', () => {
|
|
100
|
+
const builder = createTxBuilder({ account: undefined });
|
|
101
|
+
expect(builder.getAccount()).toBeUndefined();
|
|
102
|
+
|
|
103
|
+
builder.setAccount('0xdeadbeef');
|
|
104
|
+
expect(builder.getAccount()).toBe('0xdeadbeef');
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
it('should allow overriding', () => {
|
|
108
|
+
const builder = createTxBuilder();
|
|
109
|
+
builder.setAccount('0xnewaccount');
|
|
110
|
+
expect(builder.getAccount()).toBe('0xnewaccount');
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
// --- withPermit / withoutPermit selection ---
|
|
115
|
+
|
|
116
|
+
describe('withPermit / withoutPermit selection', () => {
|
|
117
|
+
it('withPermit() should set permit selection', () => {
|
|
118
|
+
const builder = createTxBuilder();
|
|
119
|
+
const selected = builder.withPermit();
|
|
120
|
+
expect(selected).toBeDefined();
|
|
121
|
+
expect(selected.getPermit()).toBeUndefined();
|
|
122
|
+
expect(selected.getPermitHash()).toBeUndefined();
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
it('withPermit(hash) should store the permit hash', () => {
|
|
126
|
+
const builder = createTxBuilder();
|
|
127
|
+
const selected = builder.withPermit('0xmypermithash');
|
|
128
|
+
expect(selected.getPermitHash()).toBe('0xmypermithash');
|
|
129
|
+
expect(selected.getPermit()).toBeUndefined();
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
it('withoutPermit() should set permit selection', () => {
|
|
133
|
+
const builder = createTxBuilder();
|
|
134
|
+
const selected = builder.withoutPermit();
|
|
135
|
+
expect(selected).toBeDefined();
|
|
136
|
+
expect(selected.getPermit()).toBeUndefined();
|
|
137
|
+
expect(selected.getPermitHash()).toBeUndefined();
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
it('should throw when withPermit() is called twice', () => {
|
|
141
|
+
const builder = createTxBuilder();
|
|
142
|
+
builder.withPermit();
|
|
143
|
+
|
|
144
|
+
expect(() => (builder as any).withPermit()).toThrow('withPermit() can only be selected once');
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
it('should throw when withoutPermit() is called twice', () => {
|
|
148
|
+
const builder = createTxBuilder();
|
|
149
|
+
builder.withoutPermit();
|
|
150
|
+
|
|
151
|
+
expect(() => (builder as any).withoutPermit()).toThrow('withoutPermit() can only be selected once');
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
it('should throw when withPermit() is called after withoutPermit()', () => {
|
|
155
|
+
const builder = createTxBuilder();
|
|
156
|
+
builder.withoutPermit();
|
|
157
|
+
|
|
158
|
+
expect(() => (builder as any).withPermit()).toThrow('cannot call withPermit() after withoutPermit()');
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
it('should throw when withoutPermit() is called after withPermit()', () => {
|
|
162
|
+
const builder = createTxBuilder();
|
|
163
|
+
builder.withPermit();
|
|
164
|
+
|
|
165
|
+
expect(() => (builder as any).withoutPermit()).toThrow('cannot call withoutPermit() after withPermit()');
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
// --- chaining ---
|
|
170
|
+
|
|
171
|
+
describe('chaining', () => {
|
|
172
|
+
it('should return the builder from each setter for fluent chaining', () => {
|
|
173
|
+
const builder = createTxBuilder({ chainId: undefined, account: undefined });
|
|
174
|
+
const result = builder.setChainId(TEST_CHAIN_ID).setAccount(account.address).withPermit();
|
|
175
|
+
|
|
176
|
+
expect(result).toBeDefined();
|
|
177
|
+
expect(result.getChainId()).toBe(TEST_CHAIN_ID);
|
|
178
|
+
expect(result.getAccount()).toBe(account.address);
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
it('should allow setChainId and setAccount after withPermit', () => {
|
|
182
|
+
const builder = createTxBuilder({ chainId: undefined, account: undefined });
|
|
183
|
+
const selected = builder.withPermit();
|
|
184
|
+
selected.setChainId(99);
|
|
185
|
+
selected.setAccount('0xabc');
|
|
186
|
+
|
|
187
|
+
expect(selected.getChainId()).toBe(99);
|
|
188
|
+
expect(selected.getAccount()).toBe('0xabc');
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
it('should allow setChainId and setAccount after withoutPermit', () => {
|
|
192
|
+
const builder = createTxBuilder({ chainId: undefined, account: undefined });
|
|
193
|
+
const selected = builder.withoutPermit();
|
|
194
|
+
selected.setChainId(99);
|
|
195
|
+
selected.setAccount('0xabc');
|
|
196
|
+
|
|
197
|
+
expect(selected.getChainId()).toBe(99);
|
|
198
|
+
expect(selected.getAccount()).toBe('0xabc');
|
|
199
|
+
});
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
// --- execute error paths ---
|
|
203
|
+
|
|
204
|
+
describe('execute – error paths', () => {
|
|
205
|
+
it('should throw when execute() is called without permit selection', async () => {
|
|
206
|
+
const builder = createTxBuilder();
|
|
207
|
+
|
|
208
|
+
try {
|
|
209
|
+
await builder.execute();
|
|
210
|
+
expect.fail('Expected error');
|
|
211
|
+
} catch (error) {
|
|
212
|
+
expect((error as any).code).toBe(CofheErrorCode.InternalError);
|
|
213
|
+
expect((error as Error).message).toContain('missing permit selection');
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
it('should throw when withPermit() has no active permit', async () => {
|
|
218
|
+
const builder = createTxBuilder();
|
|
219
|
+
|
|
220
|
+
try {
|
|
221
|
+
await builder.withPermit().execute();
|
|
222
|
+
expect.fail('Expected PermitNotFound error');
|
|
223
|
+
} catch (error) {
|
|
224
|
+
expect((error as any).code).toBe(CofheErrorCode.PermitNotFound);
|
|
225
|
+
expect((error as Error).message).toContain('Active permit not found');
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
it('should throw when withPermit(hash) cannot find permit', async () => {
|
|
230
|
+
const builder = createTxBuilder();
|
|
231
|
+
|
|
232
|
+
try {
|
|
233
|
+
await builder.withPermit('0xnonexistent').execute();
|
|
234
|
+
expect.fail('Expected PermitNotFound error');
|
|
235
|
+
} catch (error) {
|
|
236
|
+
expect((error as any).code).toBe(CofheErrorCode.PermitNotFound);
|
|
237
|
+
expect((error as Error).message).toContain('Permit with hash');
|
|
238
|
+
}
|
|
239
|
+
});
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
// --- constructor error paths ---
|
|
243
|
+
|
|
244
|
+
describe('constructor – error paths', () => {
|
|
245
|
+
it('should throw when config is undefined', () => {
|
|
246
|
+
expect(
|
|
247
|
+
() =>
|
|
248
|
+
new DecryptForTxBuilder({
|
|
249
|
+
config: undefined,
|
|
250
|
+
publicClient,
|
|
251
|
+
walletClient,
|
|
252
|
+
chainId: TEST_CHAIN_ID,
|
|
253
|
+
account: account.address,
|
|
254
|
+
ctHash: TEST_CT_HASH,
|
|
255
|
+
requireConnected: undefined,
|
|
256
|
+
})
|
|
257
|
+
).toThrow();
|
|
258
|
+
});
|
|
259
|
+
});
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
// ---------------------------------------------------------------------------
|
|
263
|
+
// DecryptForViewBuilder
|
|
264
|
+
// ---------------------------------------------------------------------------
|
|
265
|
+
|
|
266
|
+
describe('DecryptForViewBuilder', () => {
|
|
267
|
+
// --- setChainId / getChainId ---
|
|
268
|
+
|
|
269
|
+
describe('setChainId / getChainId', () => {
|
|
270
|
+
it('should store and return the chainId', () => {
|
|
271
|
+
const builder = createViewBuilder(FheTypes.Uint32, { chainId: undefined });
|
|
272
|
+
expect(builder.getChainId()).toBeUndefined();
|
|
273
|
+
|
|
274
|
+
builder.setChainId(11155111);
|
|
275
|
+
expect(builder.getChainId()).toBe(11155111);
|
|
276
|
+
});
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
// --- setAccount / getAccount ---
|
|
280
|
+
|
|
281
|
+
describe('setAccount / getAccount', () => {
|
|
282
|
+
it('should store and return the account', () => {
|
|
283
|
+
const builder = createViewBuilder(FheTypes.Uint32, { account: undefined });
|
|
284
|
+
expect(builder.getAccount()).toBeUndefined();
|
|
285
|
+
|
|
286
|
+
builder.setAccount('0xdeadbeef');
|
|
287
|
+
expect(builder.getAccount()).toBe('0xdeadbeef');
|
|
288
|
+
});
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
// --- withPermit ---
|
|
292
|
+
|
|
293
|
+
describe('withPermit', () => {
|
|
294
|
+
it('withPermit() should clear permit and hash', () => {
|
|
295
|
+
const builder = createViewBuilder(FheTypes.Uint32);
|
|
296
|
+
builder.withPermit();
|
|
297
|
+
expect(builder.getPermit()).toBeUndefined();
|
|
298
|
+
expect(builder.getPermitHash()).toBeUndefined();
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
it('withPermit(hash) should store the permit hash', () => {
|
|
302
|
+
const builder = createViewBuilder(FheTypes.Uint32);
|
|
303
|
+
builder.withPermit('0xmypermithash');
|
|
304
|
+
expect(builder.getPermitHash()).toBe('0xmypermithash');
|
|
305
|
+
expect(builder.getPermit()).toBeUndefined();
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
it('should allow overriding permit selection', () => {
|
|
309
|
+
const builder = createViewBuilder(FheTypes.Uint32);
|
|
310
|
+
builder.withPermit('0xfirst');
|
|
311
|
+
expect(builder.getPermitHash()).toBe('0xfirst');
|
|
312
|
+
|
|
313
|
+
builder.withPermit('0xsecond');
|
|
314
|
+
expect(builder.getPermitHash()).toBe('0xsecond');
|
|
315
|
+
});
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
// --- chaining ---
|
|
319
|
+
|
|
320
|
+
describe('chaining', () => {
|
|
321
|
+
it('should return the builder from each setter for fluent chaining', () => {
|
|
322
|
+
const builder = createViewBuilder(FheTypes.Uint32, { chainId: undefined, account: undefined });
|
|
323
|
+
const result = builder.setChainId(TEST_CHAIN_ID).setAccount(account.address).withPermit();
|
|
324
|
+
|
|
325
|
+
expect(result).toBeDefined();
|
|
326
|
+
expect(result.getChainId()).toBe(TEST_CHAIN_ID);
|
|
327
|
+
expect(result.getAccount()).toBe(account.address);
|
|
328
|
+
});
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
// --- execute error paths ---
|
|
332
|
+
|
|
333
|
+
describe('execute – error paths', () => {
|
|
334
|
+
it('should throw when active permit is not found', async () => {
|
|
335
|
+
const builder = createViewBuilder(FheTypes.Uint32);
|
|
336
|
+
|
|
337
|
+
try {
|
|
338
|
+
await builder.execute();
|
|
339
|
+
expect.fail('Expected PermitNotFound error');
|
|
340
|
+
} catch (error) {
|
|
341
|
+
expect((error as any).code).toBe(CofheErrorCode.PermitNotFound);
|
|
342
|
+
expect((error as Error).message).toContain('Active permit not found');
|
|
343
|
+
}
|
|
344
|
+
});
|
|
345
|
+
|
|
346
|
+
it('should throw when withPermit(hash) cannot find permit', async () => {
|
|
347
|
+
const builder = createViewBuilder(FheTypes.Uint32);
|
|
348
|
+
builder.withPermit('0xnonexistent');
|
|
349
|
+
|
|
350
|
+
try {
|
|
351
|
+
await builder.execute();
|
|
352
|
+
expect.fail('Expected PermitNotFound error');
|
|
353
|
+
} catch (error) {
|
|
354
|
+
expect((error as any).code).toBe(CofheErrorCode.PermitNotFound);
|
|
355
|
+
expect((error as Error).message).toContain('Permit with hash');
|
|
356
|
+
}
|
|
357
|
+
});
|
|
358
|
+
|
|
359
|
+
it('should throw for invalid utype', async () => {
|
|
360
|
+
const builder = createViewBuilder(999 as FheTypes);
|
|
361
|
+
|
|
362
|
+
try {
|
|
363
|
+
await builder.execute();
|
|
364
|
+
expect.fail('Expected InvalidUtype error');
|
|
365
|
+
} catch (error) {
|
|
366
|
+
expect((error as any).code).toBe(CofheErrorCode.InvalidUtype);
|
|
367
|
+
}
|
|
368
|
+
});
|
|
369
|
+
});
|
|
370
|
+
|
|
371
|
+
// --- constructor error paths ---
|
|
372
|
+
|
|
373
|
+
describe('constructor – error paths', () => {
|
|
374
|
+
it('should throw when config is undefined', () => {
|
|
375
|
+
expect(
|
|
376
|
+
() =>
|
|
377
|
+
new DecryptForViewBuilder({
|
|
378
|
+
config: undefined,
|
|
379
|
+
publicClient,
|
|
380
|
+
walletClient,
|
|
381
|
+
chainId: TEST_CHAIN_ID,
|
|
382
|
+
account: account.address,
|
|
383
|
+
ctHash: TEST_CT_HASH,
|
|
384
|
+
utype: FheTypes.Uint32,
|
|
385
|
+
requireConnected: undefined,
|
|
386
|
+
})
|
|
387
|
+
).toThrow();
|
|
388
|
+
});
|
|
389
|
+
});
|
|
390
|
+
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
2
|
-
import { EncryptInputsBuilder } from '
|
|
2
|
+
import { EncryptInputsBuilder } from '../encrypt/encryptInputsBuilder.js';
|
|
3
3
|
import {
|
|
4
4
|
type EncryptableItem,
|
|
5
5
|
FheTypes,
|
|
@@ -12,9 +12,9 @@ import { CofheError, CofheErrorCode } from '../error.js';
|
|
|
12
12
|
import { fromHexString, toHexString } from '../utils.js';
|
|
13
13
|
import { type PublicClient, createPublicClient, http, type WalletClient, createWalletClient } from 'viem';
|
|
14
14
|
import { privateKeyToAccount } from 'viem/accounts';
|
|
15
|
-
import { arbitrumSepolia
|
|
15
|
+
import { arbitrumSepolia } from 'viem/chains';
|
|
16
16
|
import { type CofheConfig, createCofheConfigBase } from '../config.js';
|
|
17
|
-
import { type ZkBuilderAndCrsGenerator } from '
|
|
17
|
+
import { type ZkBuilderAndCrsGenerator } from '../encrypt/zkPackProveVerify.js';
|
|
18
18
|
import { type KeysStorage, createKeysStore } from '../keyStore.js';
|
|
19
19
|
import { type FheKeyDeserializer } from '../fetchKeys.js';
|
|
20
20
|
|
|
@@ -122,8 +122,7 @@ class MockZkListBuilder {
|
|
|
122
122
|
|
|
123
123
|
const MockCrs = {
|
|
124
124
|
free: () => {},
|
|
125
|
-
|
|
126
|
-
safe_serialize: () => new Uint8Array(),
|
|
125
|
+
safe_serialize: (_serializedSizeLimit: bigint) => new Uint8Array(),
|
|
127
126
|
};
|
|
128
127
|
|
|
129
128
|
// Setup fetch mock for http://localhost:3001/verify
|
|
@@ -223,7 +222,7 @@ class MockZkProvenList {
|
|
|
223
222
|
this.metadata = metadata;
|
|
224
223
|
}
|
|
225
224
|
|
|
226
|
-
|
|
225
|
+
safe_serialize(_serializedSizeLimit: bigint): Uint8Array {
|
|
227
226
|
// Serialize this.items into JSON, then encode as Uint8Array (utf-8)
|
|
228
227
|
const json = stringifyWithBigInt({ items: this.items, metadata: this.metadata });
|
|
229
228
|
return new TextEncoder().encode(json);
|
|
@@ -744,4 +743,60 @@ describe('EncryptInputsBuilder', () => {
|
|
|
744
743
|
expect(encryptedMetadata2.chainId).toBe(defaultChainId);
|
|
745
744
|
});
|
|
746
745
|
});
|
|
746
|
+
|
|
747
|
+
describe('setUseWorker and getUseWorker', () => {
|
|
748
|
+
it('should have setUseWorker method', () => {
|
|
749
|
+
expect(builder).toHaveProperty('setUseWorker');
|
|
750
|
+
expect(typeof builder.setUseWorker).toBe('function');
|
|
751
|
+
});
|
|
752
|
+
|
|
753
|
+
it('should have getUseWorker method', () => {
|
|
754
|
+
expect(builder).toHaveProperty('getUseWorker');
|
|
755
|
+
expect(typeof builder.getUseWorker).toBe('function');
|
|
756
|
+
});
|
|
757
|
+
|
|
758
|
+
it('should return builder for method chaining', () => {
|
|
759
|
+
const returnedBuilder = builder.setUseWorker(false);
|
|
760
|
+
expect(returnedBuilder).toBe(builder);
|
|
761
|
+
});
|
|
762
|
+
|
|
763
|
+
it('should allow chaining with other builder methods', () => {
|
|
764
|
+
const chainedBuilder = builder.setUseWorker(false).onStep(() => {});
|
|
765
|
+
expect(chainedBuilder).toBeDefined();
|
|
766
|
+
expect(chainedBuilder).toHaveProperty('execute');
|
|
767
|
+
});
|
|
768
|
+
|
|
769
|
+
it('should accept true and false parameters without throwing', () => {
|
|
770
|
+
expect(() => builder.setUseWorker(true)).not.toThrow();
|
|
771
|
+
expect(() => builder.setUseWorker(false)).not.toThrow();
|
|
772
|
+
});
|
|
773
|
+
|
|
774
|
+
it('should return current useWorker value via getUseWorker', () => {
|
|
775
|
+
builder.setUseWorker(true);
|
|
776
|
+
expect(builder.getUseWorker()).toBe(true);
|
|
777
|
+
|
|
778
|
+
builder.setUseWorker(false);
|
|
779
|
+
expect(builder.getUseWorker()).toBe(false);
|
|
780
|
+
});
|
|
781
|
+
|
|
782
|
+
it('should reflect changes across multiple setUseWorker calls', () => {
|
|
783
|
+
builder.setUseWorker(true);
|
|
784
|
+
expect(builder.getUseWorker()).toBe(true);
|
|
785
|
+
|
|
786
|
+
builder.setUseWorker(false);
|
|
787
|
+
expect(builder.getUseWorker()).toBe(false);
|
|
788
|
+
|
|
789
|
+
builder.setUseWorker(true);
|
|
790
|
+
expect(builder.getUseWorker()).toBe(true);
|
|
791
|
+
});
|
|
792
|
+
|
|
793
|
+
it('should default useWorker based on config.useWorkers', () => {
|
|
794
|
+
const configWithWorkers = createMockCofheConfig(defaultChainId, MockZkVerifierUrl);
|
|
795
|
+
const builderWithWorkers = new EncryptInputsBuilder({
|
|
796
|
+
...createDefaultParams(),
|
|
797
|
+
config: configWithWorkers,
|
|
798
|
+
});
|
|
799
|
+
expect(builderWithWorkers.getUseWorker()).toBe(configWithWorkers.useWorkers);
|
|
800
|
+
});
|
|
801
|
+
});
|
|
747
802
|
});
|
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
import { sepolia, arbSepolia } from '@/chains';
|
|
5
5
|
|
|
6
6
|
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
|
|
7
|
-
import { fetchKeys } from '
|
|
8
|
-
import { type CofheConfig, createCofheConfigBase } from '
|
|
9
|
-
import { createKeysStore, type KeysStorage } from '
|
|
7
|
+
import { fetchKeys } from '../fetchKeys.js';
|
|
8
|
+
import { type CofheConfig, createCofheConfigBase } from '../config.js';
|
|
9
|
+
import { createKeysStore, type KeysStorage } from '../keyStore.js';
|
|
10
10
|
|
|
11
11
|
describe('fetchKeys', () => {
|
|
12
12
|
let config: CofheConfig;
|
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
/* eslint-disable no-undef */
|
|
3
3
|
|
|
4
4
|
import { describe, it, expect, beforeEach, vi, afterEach } from 'vitest';
|
|
5
|
-
|
|
5
|
+
|
|
6
|
+
import { createKeysStore, type KeysStore, type KeysStorage } from '../keyStore';
|
|
7
|
+
import { TFHE_RS_KEY_VERSION } from 'core/consts';
|
|
6
8
|
|
|
7
9
|
// Mock the storage module
|
|
8
10
|
const mockStorage = {
|
|
@@ -11,7 +13,7 @@ const mockStorage = {
|
|
|
11
13
|
removeItem: vi.fn(),
|
|
12
14
|
};
|
|
13
15
|
|
|
14
|
-
vi.mock('
|
|
16
|
+
vi.mock('../../src/storage', () => ({
|
|
15
17
|
getStorage: () => mockStorage,
|
|
16
18
|
}));
|
|
17
19
|
|
|
@@ -124,7 +126,7 @@ describe('KeyStore', () => {
|
|
|
124
126
|
it('should clear keys storage', async () => {
|
|
125
127
|
await keysStorage.clearKeysStorage();
|
|
126
128
|
|
|
127
|
-
expect(mockStorage.removeItem).toHaveBeenCalledWith(
|
|
129
|
+
expect(mockStorage.removeItem).toHaveBeenCalledWith(`cofhesdk-keys-v${TFHE_RS_KEY_VERSION}`);
|
|
128
130
|
});
|
|
129
131
|
|
|
130
132
|
it('should rehydrate keys store', async () => {
|
|
@@ -7,7 +7,7 @@ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
|
7
7
|
import { createPublicClient, createWalletClient, http, type PublicClient, type WalletClient } from 'viem';
|
|
8
8
|
import { arbitrumSepolia } from 'viem/chains';
|
|
9
9
|
import { privateKeyToAccount } from 'viem/accounts';
|
|
10
|
-
import { permits } from '
|
|
10
|
+
import { permits } from '../permits.js';
|
|
11
11
|
|
|
12
12
|
// Type declarations for happy-dom environment
|
|
13
13
|
declare const localStorage: {
|
|
@@ -435,6 +435,47 @@ describe('Core Permits Tests', () => {
|
|
|
435
435
|
});
|
|
436
436
|
});
|
|
437
437
|
|
|
438
|
+
describe('Export', () => {
|
|
439
|
+
it('should export self permit data without sensitive fields', async () => {
|
|
440
|
+
const permit = await permits.createSelf(
|
|
441
|
+
{ name: 'Test Self Permit', issuer: bobAddress },
|
|
442
|
+
publicClient,
|
|
443
|
+
bobWalletClient
|
|
444
|
+
);
|
|
445
|
+
|
|
446
|
+
const exported = permits.export(permit);
|
|
447
|
+
const parsed = JSON.parse(exported);
|
|
448
|
+
|
|
449
|
+
expect(parsed.name).toBe('Test Self Permit');
|
|
450
|
+
expect(parsed.issuer).toBe(bobAddress);
|
|
451
|
+
expect(parsed).not.toHaveProperty('sealingPair');
|
|
452
|
+
expect(parsed).not.toHaveProperty('issuerSignature');
|
|
453
|
+
});
|
|
454
|
+
|
|
455
|
+
it('should export sharing permit data with recipient and issuerSignature', async () => {
|
|
456
|
+
const permit = await permits.createSharing(
|
|
457
|
+
{
|
|
458
|
+
name: 'Test Sharing Permit',
|
|
459
|
+
issuer: bobAddress,
|
|
460
|
+
recipient: aliceAddress,
|
|
461
|
+
},
|
|
462
|
+
publicClient,
|
|
463
|
+
bobWalletClient
|
|
464
|
+
);
|
|
465
|
+
|
|
466
|
+
const exported = permits.export(permit);
|
|
467
|
+
const parsed = JSON.parse(exported);
|
|
468
|
+
|
|
469
|
+
expect(parsed.name).toBe('Test Sharing Permit');
|
|
470
|
+
expect(parsed.type).toBe('sharing');
|
|
471
|
+
expect(parsed.issuer).toBe(bobAddress);
|
|
472
|
+
expect(parsed.recipient).toBe(aliceAddress);
|
|
473
|
+
expect(parsed.issuerSignature).toBeDefined();
|
|
474
|
+
expect(parsed.issuerSignature).not.toBe('0x');
|
|
475
|
+
expect(parsed).not.toHaveProperty('sealingPair');
|
|
476
|
+
});
|
|
477
|
+
});
|
|
478
|
+
|
|
438
479
|
describe('getOrCreate - Multiple Types Scenarios', () => {
|
|
439
480
|
it('should handle switching between self and sharing permits', async () => {
|
|
440
481
|
// Create self permit
|