@cofhe/sdk 0.2.0 → 0.3.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 +36 -0
- package/chains/defineChain.ts +2 -2
- package/chains/types.ts +3 -3
- package/core/baseBuilder.ts +18 -18
- package/core/client.test.ts +155 -41
- package/core/client.ts +72 -32
- package/core/clientTypes.ts +28 -18
- package/core/config.test.ts +40 -33
- package/core/config.ts +56 -51
- package/core/consts.ts +22 -0
- package/core/decrypt/{MockQueryDecrypterAbi.ts → MockThresholdNetworkAbi.ts} +71 -21
- package/core/decrypt/cofheMocksDecryptForTx.ts +142 -0
- package/core/decrypt/{cofheMocksSealOutput.ts → cofheMocksDecryptForView.ts} +12 -14
- package/core/decrypt/decryptForTxBuilder.ts +340 -0
- package/core/decrypt/{decryptHandleBuilder.ts → decryptForViewBuilder.ts} +75 -42
- package/core/decrypt/tnDecrypt.ts +232 -0
- package/core/decrypt/tnSealOutputV1.ts +5 -5
- package/core/decrypt/tnSealOutputV2.ts +27 -27
- package/core/encrypt/cofheMocksZkVerifySign.ts +19 -26
- package/core/encrypt/encryptInputsBuilder.test.ts +57 -61
- package/core/encrypt/encryptInputsBuilder.ts +65 -42
- package/core/encrypt/zkPackProveVerify.ts +11 -11
- package/core/error.ts +18 -18
- package/core/fetchKeys.test.ts +3 -3
- package/core/fetchKeys.ts +3 -3
- package/core/index.ts +22 -11
- package/core/permits.test.ts +5 -6
- package/core/permits.ts +5 -4
- package/core/utils.ts +10 -10
- package/dist/chains.cjs +4 -7
- package/dist/chains.d.cts +12 -12
- package/dist/chains.d.ts +12 -12
- package/dist/chains.js +1 -1
- package/dist/{chunk-WGCRJCBR.js → chunk-2TPSCOW3.js} +820 -224
- package/dist/{chunk-UGBVZNRT.js → chunk-NWDKXBIP.js} +309 -189
- package/dist/{chunk-WEAZ25JO.js → chunk-TBLR7NNE.js} +4 -7
- package/dist/{clientTypes-5_1nwtUe.d.cts → clientTypes-6aTZPQ_4.d.ts} +233 -173
- package/dist/{clientTypes-Es7fyi65.d.ts → clientTypes-Bhq7pCSA.d.cts} +233 -173
- package/dist/core.cjs +1138 -418
- package/dist/core.d.cts +37 -24
- package/dist/core.d.ts +37 -24
- package/dist/core.js +3 -3
- package/dist/node.cjs +1082 -370
- package/dist/node.d.cts +12 -12
- package/dist/node.d.ts +12 -12
- package/dist/node.js +8 -8
- package/dist/{permit-fUSe6KKq.d.cts → permit-MZ502UBl.d.cts} +30 -33
- package/dist/{permit-fUSe6KKq.d.ts → permit-MZ502UBl.d.ts} +30 -33
- package/dist/permits.cjs +305 -187
- package/dist/permits.d.cts +111 -812
- package/dist/permits.d.ts +111 -812
- package/dist/permits.js +1 -1
- package/dist/types-YiAC4gig.d.cts +33 -0
- package/dist/types-YiAC4gig.d.ts +33 -0
- package/dist/web.cjs +1085 -373
- package/dist/web.d.cts +13 -13
- package/dist/web.d.ts +13 -13
- package/dist/web.js +10 -10
- package/node/client.test.ts +34 -34
- package/node/config.test.ts +11 -11
- package/node/encryptInputs.test.ts +29 -29
- package/node/index.ts +15 -15
- package/package.json +3 -3
- package/permits/localstorage.test.ts +9 -13
- package/permits/onchain-utils.ts +221 -0
- package/permits/permit.test.ts +51 -5
- package/permits/permit.ts +28 -74
- package/permits/store.test.ts +10 -50
- package/permits/store.ts +4 -14
- package/permits/test-utils.ts +10 -2
- package/permits/types.ts +22 -9
- package/permits/utils.ts +0 -4
- package/permits/validation.test.ts +29 -32
- package/permits/validation.ts +112 -194
- package/web/client.web.test.ts +34 -34
- package/web/config.web.test.ts +11 -11
- package/web/encryptInputs.web.test.ts +29 -29
- package/web/index.ts +19 -19
- package/web/worker.builder.web.test.ts +28 -28
- package/web/worker.config.web.test.ts +47 -47
- package/web/worker.output.web.test.ts +10 -10
- package/dist/types-KImPrEIe.d.cts +0 -48
- package/dist/types-KImPrEIe.d.ts +0 -48
|
@@ -8,12 +8,12 @@ import {
|
|
|
8
8
|
EncryptStep,
|
|
9
9
|
type TfheInitializer,
|
|
10
10
|
} from '../types.js';
|
|
11
|
-
import {
|
|
11
|
+
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 } from 'viem/chains';
|
|
16
|
-
import { type
|
|
15
|
+
import { arbitrumSepolia, hardhat } from 'viem/chains';
|
|
16
|
+
import { type CofheConfig, createCofheConfigBase } from '../config.js';
|
|
17
17
|
import { type ZkBuilderAndCrsGenerator } from './zkPackProveVerify.js';
|
|
18
18
|
import { type KeysStorage, createKeysStore } from '../keyStore.js';
|
|
19
19
|
import { type FheKeyDeserializer } from '../fetchKeys.js';
|
|
@@ -56,8 +56,8 @@ export const deconstructZkPoKMetadata = (
|
|
|
56
56
|
): { accountAddr: string; securityZone: number; chainId: number } => {
|
|
57
57
|
if (metadata.length < 53) {
|
|
58
58
|
// 1 + 20 + 32 = 53 bytes minimum
|
|
59
|
-
throw new
|
|
60
|
-
code:
|
|
59
|
+
throw new CofheError({
|
|
60
|
+
code: CofheErrorCode.InternalError,
|
|
61
61
|
message: 'Invalid metadata: insufficient length',
|
|
62
62
|
});
|
|
63
63
|
}
|
|
@@ -198,8 +198,8 @@ const mockZkBuilderAndCrsGenerator: ZkBuilderAndCrsGenerator = (fhe: string, crs
|
|
|
198
198
|
};
|
|
199
199
|
};
|
|
200
200
|
|
|
201
|
-
const
|
|
202
|
-
return
|
|
201
|
+
const createMockCofheConfig = (chainId: number, zkVerifierUrl: string) => {
|
|
202
|
+
return createCofheConfigBase({
|
|
203
203
|
supportedChains: [
|
|
204
204
|
{
|
|
205
205
|
id: chainId,
|
|
@@ -239,7 +239,7 @@ describe('EncryptInputsBuilder', () => {
|
|
|
239
239
|
account: defaultSender,
|
|
240
240
|
chainId: defaultChainId,
|
|
241
241
|
|
|
242
|
-
config:
|
|
242
|
+
config: createMockCofheConfig(defaultChainId, MockZkVerifierUrl),
|
|
243
243
|
publicClient: publicClient,
|
|
244
244
|
walletClient: bobWalletClient,
|
|
245
245
|
|
|
@@ -278,41 +278,41 @@ describe('EncryptInputsBuilder', () => {
|
|
|
278
278
|
});
|
|
279
279
|
|
|
280
280
|
it('should throw an error if config is not set', async () => {
|
|
281
|
-
// Should throw before .
|
|
281
|
+
// Should throw before .execute() is called
|
|
282
282
|
try {
|
|
283
283
|
new EncryptInputsBuilder({
|
|
284
284
|
...createDefaultParams(),
|
|
285
|
-
config: undefined as unknown as
|
|
285
|
+
config: undefined as unknown as CofheConfig,
|
|
286
286
|
});
|
|
287
287
|
} catch (error) {
|
|
288
|
-
expect(error).toBeInstanceOf(
|
|
289
|
-
expect((error as
|
|
288
|
+
expect(error).toBeInstanceOf(CofheError);
|
|
289
|
+
expect((error as CofheError).code).toBe(CofheErrorCode.MissingConfig);
|
|
290
290
|
}
|
|
291
291
|
});
|
|
292
292
|
|
|
293
293
|
it('should throw an error if tfhePublicKeyDeserializer is not set', async () => {
|
|
294
|
-
// Should throw before .
|
|
294
|
+
// Should throw before .execute() is called
|
|
295
295
|
try {
|
|
296
296
|
new EncryptInputsBuilder({
|
|
297
297
|
...createDefaultParams(),
|
|
298
298
|
tfhePublicKeyDeserializer: undefined as unknown as FheKeyDeserializer,
|
|
299
299
|
});
|
|
300
300
|
} catch (error) {
|
|
301
|
-
expect(error).toBeInstanceOf(
|
|
302
|
-
expect((error as
|
|
301
|
+
expect(error).toBeInstanceOf(CofheError);
|
|
302
|
+
expect((error as CofheError).code).toBe(CofheErrorCode.MissingTfhePublicKeyDeserializer);
|
|
303
303
|
}
|
|
304
304
|
});
|
|
305
305
|
|
|
306
306
|
it('should throw an error if compactPkeCrsDeserializer is not set', async () => {
|
|
307
|
-
// Should throw before .
|
|
307
|
+
// Should throw before .execute() is called
|
|
308
308
|
try {
|
|
309
309
|
new EncryptInputsBuilder({
|
|
310
310
|
...createDefaultParams(),
|
|
311
311
|
compactPkeCrsDeserializer: undefined as unknown as FheKeyDeserializer,
|
|
312
312
|
});
|
|
313
313
|
} catch (error) {
|
|
314
|
-
expect(error).toBeInstanceOf(
|
|
315
|
-
expect((error as
|
|
314
|
+
expect(error).toBeInstanceOf(CofheError);
|
|
315
|
+
expect((error as CofheError).code).toBe(CofheErrorCode.MissingCompactPkeCrsDeserializer);
|
|
316
316
|
}
|
|
317
317
|
});
|
|
318
318
|
|
|
@@ -321,10 +321,10 @@ describe('EncryptInputsBuilder', () => {
|
|
|
321
321
|
await new EncryptInputsBuilder({
|
|
322
322
|
...createDefaultParams(),
|
|
323
323
|
initTfhe: vi.fn().mockRejectedValue(new Error('Failed to initialize TFHE')),
|
|
324
|
-
}).
|
|
324
|
+
}).execute();
|
|
325
325
|
} catch (error) {
|
|
326
|
-
expect(error).toBeInstanceOf(
|
|
327
|
-
expect((error as
|
|
326
|
+
expect(error).toBeInstanceOf(CofheError);
|
|
327
|
+
expect((error as CofheError).code).toBe(CofheErrorCode.InitTfheFailed);
|
|
328
328
|
}
|
|
329
329
|
});
|
|
330
330
|
|
|
@@ -332,7 +332,7 @@ describe('EncryptInputsBuilder', () => {
|
|
|
332
332
|
const result = await new EncryptInputsBuilder({
|
|
333
333
|
...createDefaultParams(),
|
|
334
334
|
initTfhe: mockInitTfhe,
|
|
335
|
-
}).
|
|
335
|
+
}).execute();
|
|
336
336
|
expect(result).toBeDefined();
|
|
337
337
|
});
|
|
338
338
|
});
|
|
@@ -354,7 +354,7 @@ describe('EncryptInputsBuilder', () => {
|
|
|
354
354
|
const result = builder
|
|
355
355
|
.setAccount(sender)
|
|
356
356
|
.setSecurityZone(securityZone)
|
|
357
|
-
.
|
|
357
|
+
.onStep(() => {});
|
|
358
358
|
|
|
359
359
|
expect(result).toBe(builder);
|
|
360
360
|
expect(result.getAccount()).toBe(sender);
|
|
@@ -366,10 +366,10 @@ describe('EncryptInputsBuilder', () => {
|
|
|
366
366
|
await new EncryptInputsBuilder({
|
|
367
367
|
...createDefaultParams(),
|
|
368
368
|
account: undefined,
|
|
369
|
-
}).
|
|
369
|
+
}).execute();
|
|
370
370
|
} catch (error) {
|
|
371
|
-
expect(error).toBeInstanceOf(
|
|
372
|
-
expect((error as
|
|
371
|
+
expect(error).toBeInstanceOf(CofheError);
|
|
372
|
+
expect((error as CofheError).code).toBe(CofheErrorCode.AccountUninitialized);
|
|
373
373
|
}
|
|
374
374
|
});
|
|
375
375
|
});
|
|
@@ -389,7 +389,7 @@ describe('EncryptInputsBuilder', () => {
|
|
|
389
389
|
const result = builder
|
|
390
390
|
.setSecurityZone(securityZone)
|
|
391
391
|
.setAccount(sender)
|
|
392
|
-
.
|
|
392
|
+
.onStep(() => {});
|
|
393
393
|
|
|
394
394
|
expect(result).toBe(builder);
|
|
395
395
|
expect(result.getAccount()).toBe(sender);
|
|
@@ -410,10 +410,10 @@ describe('EncryptInputsBuilder', () => {
|
|
|
410
410
|
await new EncryptInputsBuilder({
|
|
411
411
|
...createDefaultParams(),
|
|
412
412
|
chainId: undefined,
|
|
413
|
-
}).
|
|
413
|
+
}).execute();
|
|
414
414
|
} catch (error) {
|
|
415
|
-
expect(error).toBeInstanceOf(
|
|
416
|
-
expect((error as
|
|
415
|
+
expect(error).toBeInstanceOf(CofheError);
|
|
416
|
+
expect((error as CofheError).code).toBe(CofheErrorCode.ChainIdUninitialized);
|
|
417
417
|
}
|
|
418
418
|
});
|
|
419
419
|
});
|
|
@@ -426,25 +426,25 @@ describe('EncryptInputsBuilder', () => {
|
|
|
426
426
|
inputs: [Encryptable.uint128(100n)] as [EncryptableUint128],
|
|
427
427
|
account: '0x1234567890123456789012345678901234567890',
|
|
428
428
|
chainId: 1,
|
|
429
|
-
config:
|
|
430
|
-
}).
|
|
429
|
+
config: createMockCofheConfig(defaultChainId, undefined as unknown as string),
|
|
430
|
+
}).execute();
|
|
431
431
|
} catch (error) {
|
|
432
|
-
expect(error).toBeInstanceOf(
|
|
433
|
-
expect((error as
|
|
432
|
+
expect(error).toBeInstanceOf(CofheError);
|
|
433
|
+
expect((error as CofheError).code).toBe(CofheErrorCode.ZkVerifierUrlUninitialized);
|
|
434
434
|
}
|
|
435
435
|
});
|
|
436
436
|
});
|
|
437
437
|
|
|
438
|
-
describe('
|
|
438
|
+
describe('onStep', () => {
|
|
439
439
|
it('should set step callback and return builder for chaining', () => {
|
|
440
440
|
const callback = vi.fn();
|
|
441
|
-
const result = builder.
|
|
441
|
+
const result = builder.onStep(callback);
|
|
442
442
|
expect(result).toBe(builder);
|
|
443
443
|
});
|
|
444
444
|
|
|
445
445
|
it('should allow chaining with other methods', () => {
|
|
446
446
|
const callback = vi.fn();
|
|
447
|
-
const result = builder.
|
|
447
|
+
const result = builder.onStep(callback).setSecurityZone(15);
|
|
448
448
|
|
|
449
449
|
expect(result).toBe(builder);
|
|
450
450
|
});
|
|
@@ -453,9 +453,9 @@ describe('EncryptInputsBuilder', () => {
|
|
|
453
453
|
describe('encrypt', () => {
|
|
454
454
|
it('should execute the full encryption flow with step callbacks', async () => {
|
|
455
455
|
const stepCallback = vi.fn();
|
|
456
|
-
builder.
|
|
456
|
+
builder.onStep(stepCallback);
|
|
457
457
|
|
|
458
|
-
const result = await builder.
|
|
458
|
+
const result = await builder.execute();
|
|
459
459
|
|
|
460
460
|
// Verify step callbacks were called in order
|
|
461
461
|
expect(stepCallback).toHaveBeenCalledTimes(10);
|
|
@@ -568,7 +568,7 @@ describe('EncryptInputsBuilder', () => {
|
|
|
568
568
|
const overriddenSender = '0x5555555555555555555555555555555555555555';
|
|
569
569
|
builder.setAccount(overriddenSender);
|
|
570
570
|
|
|
571
|
-
const result = await builder.
|
|
571
|
+
const result = await builder.execute();
|
|
572
572
|
|
|
573
573
|
// Verify result embedded metadata
|
|
574
574
|
const [encrypted] = result;
|
|
@@ -585,7 +585,7 @@ describe('EncryptInputsBuilder', () => {
|
|
|
585
585
|
|
|
586
586
|
insertMockKeys(defaultChainId, overriddenZone);
|
|
587
587
|
|
|
588
|
-
const result = await builder.
|
|
588
|
+
const result = await builder.execute();
|
|
589
589
|
|
|
590
590
|
// Verify result embedded metadata
|
|
591
591
|
const [encrypted] = result;
|
|
@@ -598,7 +598,7 @@ describe('EncryptInputsBuilder', () => {
|
|
|
598
598
|
|
|
599
599
|
it('should work without step callback', async () => {
|
|
600
600
|
// No step callback set
|
|
601
|
-
const result = await builder.
|
|
601
|
+
const result = await builder.execute();
|
|
602
602
|
|
|
603
603
|
expect(result).toBeDefined();
|
|
604
604
|
expect(Array.isArray(result)).toBe(true);
|
|
@@ -614,7 +614,7 @@ describe('EncryptInputsBuilder', () => {
|
|
|
614
614
|
],
|
|
615
615
|
});
|
|
616
616
|
|
|
617
|
-
const result = await multiInputBuilder.
|
|
617
|
+
const result = await multiInputBuilder.execute();
|
|
618
618
|
|
|
619
619
|
expect(result).toBeDefined();
|
|
620
620
|
expect(Array.isArray(result)).toBe(true);
|
|
@@ -646,10 +646,10 @@ describe('EncryptInputsBuilder', () => {
|
|
|
646
646
|
Encryptable.uint128(100n),
|
|
647
647
|
Encryptable.uint128(100n),
|
|
648
648
|
],
|
|
649
|
-
}).
|
|
649
|
+
}).execute();
|
|
650
650
|
} catch (error) {
|
|
651
|
-
expect(error).toBeInstanceOf(
|
|
652
|
-
expect((error as
|
|
651
|
+
expect(error).toBeInstanceOf(CofheError);
|
|
652
|
+
expect((error as CofheError).code).toBe(CofheErrorCode.ZkPackFailed);
|
|
653
653
|
}
|
|
654
654
|
});
|
|
655
655
|
|
|
@@ -665,8 +665,8 @@ describe('EncryptInputsBuilder', () => {
|
|
|
665
665
|
] as unknown as [EncryptableItem],
|
|
666
666
|
});
|
|
667
667
|
} catch (error) {
|
|
668
|
-
expect(error).toBeInstanceOf(
|
|
669
|
-
expect((error as
|
|
668
|
+
expect(error).toBeInstanceOf(CofheError);
|
|
669
|
+
expect((error as CofheError).code).toBe(CofheErrorCode.ZkPackFailed);
|
|
670
670
|
}
|
|
671
671
|
});
|
|
672
672
|
});
|
|
@@ -674,18 +674,18 @@ describe('EncryptInputsBuilder', () => {
|
|
|
674
674
|
// TODO: Implement error handling tests
|
|
675
675
|
// describe('error handling', () => {
|
|
676
676
|
// it('should handle ZK pack errors gracefully', async () => {
|
|
677
|
-
// const result = await builder.
|
|
678
|
-
// expectResultError(result,
|
|
677
|
+
// const result = await builder.execute();
|
|
678
|
+
// expectResultError(result, CofheErrorCode.InternalError, 'ZK pack failed');
|
|
679
679
|
// });
|
|
680
680
|
|
|
681
681
|
// it('should handle ZK prove errors gracefully', async () => {
|
|
682
|
-
// const result = await builder.
|
|
683
|
-
// expectResultError(result,
|
|
682
|
+
// const result = await builder.execute();
|
|
683
|
+
// expectResultError(result, CofheErrorCode.InternalError, 'ZK prove failed');
|
|
684
684
|
// });
|
|
685
685
|
|
|
686
686
|
// it('should handle ZK verify errors gracefully', async () => {
|
|
687
|
-
// const result = await builder.
|
|
688
|
-
// expectResultError(result,
|
|
687
|
+
// const result = await builder.execute();
|
|
688
|
+
// expectResultError(result, CofheErrorCode.InternalError, 'ZK verify failed');
|
|
689
689
|
// });
|
|
690
690
|
// });
|
|
691
691
|
|
|
@@ -697,11 +697,7 @@ describe('EncryptInputsBuilder', () => {
|
|
|
697
697
|
insertMockKeys(defaultChainId, securityZone);
|
|
698
698
|
|
|
699
699
|
const stepCallback = vi.fn();
|
|
700
|
-
const result = await builder
|
|
701
|
-
.setAccount(sender)
|
|
702
|
-
.setSecurityZone(securityZone)
|
|
703
|
-
.setStepCallback(stepCallback)
|
|
704
|
-
.encrypt();
|
|
700
|
+
const result = await builder.setAccount(sender).setSecurityZone(securityZone).onStep(stepCallback).execute();
|
|
705
701
|
|
|
706
702
|
expect(result).toBeDefined();
|
|
707
703
|
expect(stepCallback).toHaveBeenCalledTimes(10);
|
|
@@ -725,8 +721,8 @@ describe('EncryptInputsBuilder', () => {
|
|
|
725
721
|
builder.setSecurityZone(securityZone);
|
|
726
722
|
|
|
727
723
|
// Call encrypt multiple times to ensure state is maintained
|
|
728
|
-
const result1 = await builder.
|
|
729
|
-
const result2 = await builder.
|
|
724
|
+
const result1 = await builder.execute();
|
|
725
|
+
const result2 = await builder.execute();
|
|
730
726
|
|
|
731
727
|
expect(result1).toBeDefined();
|
|
732
728
|
expect(result2).toBeDefined();
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
zkVerify,
|
|
8
8
|
constructZkPoKMetadata,
|
|
9
9
|
} from './zkPackProveVerify.js';
|
|
10
|
-
import {
|
|
10
|
+
import { CofheError, CofheErrorCode } from '../error.js';
|
|
11
11
|
import {
|
|
12
12
|
type EncryptStepCallbackFunction,
|
|
13
13
|
EncryptStep,
|
|
@@ -90,8 +90,8 @@ export class EncryptInputsBuilder<T extends EncryptableItem[]> extends BaseBuild
|
|
|
90
90
|
|
|
91
91
|
// Check that tfhePublicKeyDeserializer is provided
|
|
92
92
|
if (!params.tfhePublicKeyDeserializer) {
|
|
93
|
-
throw new
|
|
94
|
-
code:
|
|
93
|
+
throw new CofheError({
|
|
94
|
+
code: CofheErrorCode.MissingTfhePublicKeyDeserializer,
|
|
95
95
|
message: 'EncryptInputsBuilder tfhePublicKeyDeserializer is undefined',
|
|
96
96
|
hint: 'Ensure client has been created with a tfhePublicKeyDeserializer.',
|
|
97
97
|
context: {
|
|
@@ -103,8 +103,8 @@ export class EncryptInputsBuilder<T extends EncryptableItem[]> extends BaseBuild
|
|
|
103
103
|
|
|
104
104
|
// Check that compactPkeCrsDeserializer is provided
|
|
105
105
|
if (!params.compactPkeCrsDeserializer) {
|
|
106
|
-
throw new
|
|
107
|
-
code:
|
|
106
|
+
throw new CofheError({
|
|
107
|
+
code: CofheErrorCode.MissingCompactPkeCrsDeserializer,
|
|
108
108
|
message: 'EncryptInputsBuilder compactPkeCrsDeserializer is undefined',
|
|
109
109
|
hint: 'Ensure client has been created with a compactPkeCrsDeserializer.',
|
|
110
110
|
context: {
|
|
@@ -116,8 +116,8 @@ export class EncryptInputsBuilder<T extends EncryptableItem[]> extends BaseBuild
|
|
|
116
116
|
|
|
117
117
|
// Check that zkBuilderAndCrsGenerator is provided
|
|
118
118
|
if (!params.zkBuilderAndCrsGenerator) {
|
|
119
|
-
throw new
|
|
120
|
-
code:
|
|
119
|
+
throw new CofheError({
|
|
120
|
+
code: CofheErrorCode.MissingZkBuilderAndCrsGenerator,
|
|
121
121
|
message: 'EncryptInputsBuilder zkBuilderAndCrsGenerator is undefined',
|
|
122
122
|
hint: 'Ensure client has been created with a zkBuilderAndCrsGenerator.',
|
|
123
123
|
context: {
|
|
@@ -149,7 +149,7 @@ export class EncryptInputsBuilder<T extends EncryptableItem[]> extends BaseBuild
|
|
|
149
149
|
* ```typescript
|
|
150
150
|
* const encrypted = await encryptInputs([Encryptable.uint128(10n)])
|
|
151
151
|
* .setAccount("0x123")
|
|
152
|
-
* .
|
|
152
|
+
* .execute();
|
|
153
153
|
* ```
|
|
154
154
|
*
|
|
155
155
|
* @returns The chainable EncryptInputsBuilder instance.
|
|
@@ -172,7 +172,7 @@ export class EncryptInputsBuilder<T extends EncryptableItem[]> extends BaseBuild
|
|
|
172
172
|
* ```typescript
|
|
173
173
|
* const encrypted = await encryptInputs([Encryptable.uint128(10n)])
|
|
174
174
|
* .setChainId(11155111)
|
|
175
|
-
* .
|
|
175
|
+
* .execute();
|
|
176
176
|
* ```
|
|
177
177
|
*
|
|
178
178
|
* @returns The chainable EncryptInputsBuilder instance.
|
|
@@ -195,7 +195,7 @@ export class EncryptInputsBuilder<T extends EncryptableItem[]> extends BaseBuild
|
|
|
195
195
|
* ```typescript
|
|
196
196
|
* const encrypted = await encryptInputs([Encryptable.uint128(10n)])
|
|
197
197
|
* .setSecurityZone(1)
|
|
198
|
-
* .
|
|
198
|
+
* .execute();
|
|
199
199
|
* ```
|
|
200
200
|
*
|
|
201
201
|
* @returns The chainable EncryptInputsBuilder instance.
|
|
@@ -218,7 +218,7 @@ export class EncryptInputsBuilder<T extends EncryptableItem[]> extends BaseBuild
|
|
|
218
218
|
* ```typescript
|
|
219
219
|
* const encrypted = await encryptInputs([Encryptable.uint128(10n)])
|
|
220
220
|
* .setUseWorker(false)
|
|
221
|
-
* .
|
|
221
|
+
* .execute();
|
|
222
222
|
* ```
|
|
223
223
|
*
|
|
224
224
|
* @returns The chainable EncryptInputsBuilder instance.
|
|
@@ -254,13 +254,13 @@ export class EncryptInputsBuilder<T extends EncryptableItem[]> extends BaseBuild
|
|
|
254
254
|
* Example:
|
|
255
255
|
* ```typescript
|
|
256
256
|
* const encrypted = await encryptInputs([Encryptable.uint128(10n)])
|
|
257
|
-
* .
|
|
258
|
-
* .
|
|
257
|
+
* .onStep((step: EncryptStep) => console.log(step))
|
|
258
|
+
* .execute();
|
|
259
259
|
* ```
|
|
260
260
|
*
|
|
261
261
|
* @returns The EncryptInputsBuilder instance.
|
|
262
262
|
*/
|
|
263
|
-
|
|
263
|
+
onStep(callback: EncryptStepCallbackFunction): EncryptInputsBuilder<T> {
|
|
264
264
|
this.stepCallback = callback;
|
|
265
265
|
return this;
|
|
266
266
|
}
|
|
@@ -290,7 +290,7 @@ export class EncryptInputsBuilder<T extends EncryptableItem[]> extends BaseBuild
|
|
|
290
290
|
}
|
|
291
291
|
|
|
292
292
|
/**
|
|
293
|
-
* zkVerifierUrl is included in the chains exported from
|
|
293
|
+
* zkVerifierUrl is included in the chains exported from @cofhe/sdk/chains for use in CofheConfig.supportedChains
|
|
294
294
|
* Users should generally not set this manually.
|
|
295
295
|
*/
|
|
296
296
|
private async getZkVerifierUrl(): Promise<string> {
|
|
@@ -299,7 +299,7 @@ export class EncryptInputsBuilder<T extends EncryptableItem[]> extends BaseBuild
|
|
|
299
299
|
}
|
|
300
300
|
|
|
301
301
|
/**
|
|
302
|
-
* initTfhe is a platform-specific dependency injected into core/
|
|
302
|
+
* initTfhe is a platform-specific dependency injected into core/createCofheClientBase by web/createCofheClient and node/createCofheClient
|
|
303
303
|
* web/ uses zama "tfhe"
|
|
304
304
|
* node/ uses zama "node-tfhe"
|
|
305
305
|
* Users should not set this manually.
|
|
@@ -310,8 +310,8 @@ export class EncryptInputsBuilder<T extends EncryptableItem[]> extends BaseBuild
|
|
|
310
310
|
try {
|
|
311
311
|
return await this.initTfhe();
|
|
312
312
|
} catch (error) {
|
|
313
|
-
throw
|
|
314
|
-
code:
|
|
313
|
+
throw CofheError.fromError(error, {
|
|
314
|
+
code: CofheErrorCode.InitTfheFailed,
|
|
315
315
|
message: `Failed to initialize TFHE`,
|
|
316
316
|
context: {
|
|
317
317
|
initTfhe: this.initTfhe,
|
|
@@ -336,8 +336,8 @@ export class EncryptInputsBuilder<T extends EncryptableItem[]> extends BaseBuild
|
|
|
336
336
|
try {
|
|
337
337
|
await this.keysStorage?.rehydrateKeysStore();
|
|
338
338
|
} catch (error) {
|
|
339
|
-
throw
|
|
340
|
-
code:
|
|
339
|
+
throw CofheError.fromError(error, {
|
|
340
|
+
code: CofheErrorCode.RehydrateKeysStoreFailed,
|
|
341
341
|
message: `Failed to rehydrate keys store`,
|
|
342
342
|
context: {
|
|
343
343
|
keysStorage: this.keysStorage,
|
|
@@ -360,8 +360,8 @@ export class EncryptInputsBuilder<T extends EncryptableItem[]> extends BaseBuild
|
|
|
360
360
|
this.keysStorage
|
|
361
361
|
);
|
|
362
362
|
} catch (error) {
|
|
363
|
-
throw
|
|
364
|
-
code:
|
|
363
|
+
throw CofheError.fromError(error, {
|
|
364
|
+
code: CofheErrorCode.FetchKeysFailed,
|
|
365
365
|
message: `Failed to fetch FHE key and CRS`,
|
|
366
366
|
context: {
|
|
367
367
|
config: this.config,
|
|
@@ -374,8 +374,8 @@ export class EncryptInputsBuilder<T extends EncryptableItem[]> extends BaseBuild
|
|
|
374
374
|
}
|
|
375
375
|
|
|
376
376
|
if (!fheKey) {
|
|
377
|
-
throw new
|
|
378
|
-
code:
|
|
377
|
+
throw new CofheError({
|
|
378
|
+
code: CofheErrorCode.MissingFheKey,
|
|
379
379
|
message: `FHE key not found`,
|
|
380
380
|
context: {
|
|
381
381
|
chainId: this.chainId,
|
|
@@ -385,8 +385,8 @@ export class EncryptInputsBuilder<T extends EncryptableItem[]> extends BaseBuild
|
|
|
385
385
|
}
|
|
386
386
|
|
|
387
387
|
if (!crs) {
|
|
388
|
-
throw new
|
|
389
|
-
code:
|
|
388
|
+
throw new CofheError({
|
|
389
|
+
code: CofheErrorCode.MissingCrs,
|
|
390
390
|
message: `CRS not found for chainId <${this.chainId}>`,
|
|
391
391
|
context: {
|
|
392
392
|
chainId: this.chainId,
|
|
@@ -397,6 +397,18 @@ export class EncryptInputsBuilder<T extends EncryptableItem[]> extends BaseBuild
|
|
|
397
397
|
return { fheKey, fheKeyFetchedFromCoFHE, crs, crsFetchedFromCoFHE };
|
|
398
398
|
}
|
|
399
399
|
|
|
400
|
+
/**
|
|
401
|
+
* Resolves the encryptDelay config into an array of 5 per-step delays.
|
|
402
|
+
* A single number is broadcast to all steps; a tuple is used as-is.
|
|
403
|
+
*/
|
|
404
|
+
private resolveEncryptDelays(): [number, number, number, number, number] {
|
|
405
|
+
const encryptDelay = this.config?.mocks?.encryptDelay ?? [100, 100, 100, 500, 500];
|
|
406
|
+
if (typeof encryptDelay === 'number') {
|
|
407
|
+
return [encryptDelay, encryptDelay, encryptDelay, encryptDelay, encryptDelay];
|
|
408
|
+
}
|
|
409
|
+
return encryptDelay;
|
|
410
|
+
}
|
|
411
|
+
|
|
400
412
|
/**
|
|
401
413
|
* @dev Encrypt against the cofheMocks instead of CoFHE
|
|
402
414
|
*
|
|
@@ -404,30 +416,41 @@ export class EncryptInputsBuilder<T extends EncryptableItem[]> extends BaseBuild
|
|
|
404
416
|
* cofheMocksInsertPackedHashes - stores the ctHashes and their plaintext values for on-chain mocking of FHE operations.
|
|
405
417
|
* cofheMocksZkCreateProofSignatures - creates signatures to be included in the encrypted inputs. The signers address is known and verified in the mock contracts.
|
|
406
418
|
*/
|
|
407
|
-
private async
|
|
419
|
+
private async mocksExecute(): Promise<[...EncryptedItemInputs<T>]> {
|
|
408
420
|
this.assertAccount();
|
|
409
421
|
this.assertPublicClient();
|
|
410
422
|
this.assertWalletClient();
|
|
411
423
|
|
|
424
|
+
const [initTfheDelay, fetchKeysDelay, packDelay, proveDelay, verifyDelay] = this.resolveEncryptDelays();
|
|
425
|
+
|
|
412
426
|
this.fireStepStart(EncryptStep.InitTfhe);
|
|
413
|
-
await sleep(
|
|
414
|
-
this.fireStepEnd(EncryptStep.InitTfhe, {
|
|
427
|
+
await sleep(initTfheDelay);
|
|
428
|
+
this.fireStepEnd(EncryptStep.InitTfhe, {
|
|
429
|
+
tfheInitializationExecuted: false,
|
|
430
|
+
isMocks: true,
|
|
431
|
+
mockSleep: initTfheDelay,
|
|
432
|
+
});
|
|
415
433
|
|
|
416
434
|
this.fireStepStart(EncryptStep.FetchKeys);
|
|
417
|
-
await sleep(
|
|
418
|
-
this.fireStepEnd(EncryptStep.FetchKeys, {
|
|
435
|
+
await sleep(fetchKeysDelay);
|
|
436
|
+
this.fireStepEnd(EncryptStep.FetchKeys, {
|
|
437
|
+
fheKeyFetchedFromCoFHE: false,
|
|
438
|
+
crsFetchedFromCoFHE: false,
|
|
439
|
+
isMocks: true,
|
|
440
|
+
mockSleep: fetchKeysDelay,
|
|
441
|
+
});
|
|
419
442
|
|
|
420
443
|
this.fireStepStart(EncryptStep.Pack);
|
|
421
444
|
await cofheMocksCheckEncryptableBits(this.inputItems);
|
|
422
|
-
await sleep(
|
|
423
|
-
this.fireStepEnd(EncryptStep.Pack);
|
|
445
|
+
await sleep(packDelay);
|
|
446
|
+
this.fireStepEnd(EncryptStep.Pack, { isMocks: true, mockSleep: packDelay });
|
|
424
447
|
|
|
425
448
|
this.fireStepStart(EncryptStep.Prove);
|
|
426
|
-
await sleep(
|
|
427
|
-
this.fireStepEnd(EncryptStep.Prove);
|
|
449
|
+
await sleep(proveDelay);
|
|
450
|
+
this.fireStepEnd(EncryptStep.Prove, { isMocks: true, mockSleep: proveDelay });
|
|
428
451
|
|
|
429
452
|
this.fireStepStart(EncryptStep.Verify);
|
|
430
|
-
await sleep(
|
|
453
|
+
await sleep(verifyDelay);
|
|
431
454
|
const signedResults = await cofheMocksZkVerifySign(
|
|
432
455
|
this.inputItems,
|
|
433
456
|
this.account,
|
|
@@ -442,7 +465,7 @@ export class EncryptInputsBuilder<T extends EncryptableItem[]> extends BaseBuild
|
|
|
442
465
|
utype: this.inputItems[index].utype,
|
|
443
466
|
signature,
|
|
444
467
|
}));
|
|
445
|
-
this.fireStepEnd(EncryptStep.Verify);
|
|
468
|
+
this.fireStepEnd(EncryptStep.Verify, { isMocks: true, mockSleep: verifyDelay });
|
|
446
469
|
|
|
447
470
|
return encryptedInputs as [...EncryptedItemInputs<T>];
|
|
448
471
|
}
|
|
@@ -450,7 +473,7 @@ export class EncryptInputsBuilder<T extends EncryptableItem[]> extends BaseBuild
|
|
|
450
473
|
/**
|
|
451
474
|
* In the production context, perform a true encryption with the CoFHE coprocessor.
|
|
452
475
|
*/
|
|
453
|
-
private async
|
|
476
|
+
private async productionExecute(): Promise<[...EncryptedItemInputs<T>]> {
|
|
454
477
|
this.assertAccount();
|
|
455
478
|
this.assertChainId();
|
|
456
479
|
|
|
@@ -545,16 +568,16 @@ export class EncryptInputsBuilder<T extends EncryptableItem[]> extends BaseBuild
|
|
|
545
568
|
* const encrypted = await encryptInputs([Encryptable.uint128(10n)])
|
|
546
569
|
* .setAccount('0x123...890') // optional
|
|
547
570
|
* .setChainId(11155111) // optional
|
|
548
|
-
* .
|
|
571
|
+
* .execute(); // execute
|
|
549
572
|
* ```
|
|
550
573
|
*
|
|
551
574
|
* @returns The encrypted inputs.
|
|
552
575
|
*/
|
|
553
|
-
async
|
|
576
|
+
async execute(): Promise<[...EncryptedItemInputs<T>]> {
|
|
554
577
|
// On hardhat chain, interact with MockZkVerifier contract instead of CoFHE
|
|
555
|
-
if (this.chainId === hardhat.id) return this.
|
|
578
|
+
if (this.chainId === hardhat.id) return this.mocksExecute();
|
|
556
579
|
|
|
557
580
|
// On other chains, interact with CoFHE coprocessor
|
|
558
|
-
return this.
|
|
581
|
+
return this.productionExecute();
|
|
559
582
|
}
|
|
560
583
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { CofheError, CofheErrorCode } from '../error.js';
|
|
2
2
|
import { type EncryptableItem, FheTypes } from '../types.js';
|
|
3
3
|
import { toBigIntOrThrow, validateBigIntInRange, toHexString, hexToBytes } from '../utils.js';
|
|
4
4
|
|
|
@@ -162,8 +162,8 @@ export const zkPack = (items: EncryptableItem[], builder: ZkCiphertextListBuilde
|
|
|
162
162
|
break;
|
|
163
163
|
}
|
|
164
164
|
default: {
|
|
165
|
-
throw new
|
|
166
|
-
code:
|
|
165
|
+
throw new CofheError({
|
|
166
|
+
code: CofheErrorCode.ZkPackFailed,
|
|
167
167
|
message: `Invalid utype: ${(item as any).utype}`,
|
|
168
168
|
hint: `Ensure that the utype is valid, using the Encryptable type, for example: Encryptable.uint128(100n)`,
|
|
169
169
|
context: {
|
|
@@ -175,8 +175,8 @@ export const zkPack = (items: EncryptableItem[], builder: ZkCiphertextListBuilde
|
|
|
175
175
|
}
|
|
176
176
|
|
|
177
177
|
if (totalBits > MAX_ENCRYPTABLE_BITS) {
|
|
178
|
-
throw new
|
|
179
|
-
code:
|
|
178
|
+
throw new CofheError({
|
|
179
|
+
code: CofheErrorCode.ZkPackFailed,
|
|
180
180
|
message: `Total bits ${totalBits} exceeds ${MAX_ENCRYPTABLE_BITS}`,
|
|
181
181
|
hint: `Ensure that the total bits of the items to encrypt does not exceed ${MAX_ENCRYPTABLE_BITS}`,
|
|
182
182
|
context: {
|
|
@@ -300,8 +300,8 @@ export const zkVerify = async (
|
|
|
300
300
|
if (!response.ok) {
|
|
301
301
|
// Get the response body as text for better error details
|
|
302
302
|
const errorBody = await response.text();
|
|
303
|
-
throw new
|
|
304
|
-
code:
|
|
303
|
+
throw new CofheError({
|
|
304
|
+
code: CofheErrorCode.ZkVerifyFailed,
|
|
305
305
|
message: `HTTP error! ZK proof verification failed - ${errorBody}`,
|
|
306
306
|
});
|
|
307
307
|
}
|
|
@@ -309,8 +309,8 @@ export const zkVerify = async (
|
|
|
309
309
|
const json = (await response.json()) as { status: string; data: VerifyResultRaw[]; error: string };
|
|
310
310
|
|
|
311
311
|
if (json.status !== 'success') {
|
|
312
|
-
throw new
|
|
313
|
-
code:
|
|
312
|
+
throw new CofheError({
|
|
313
|
+
code: CofheErrorCode.ZkVerifyFailed,
|
|
314
314
|
message: `ZK proof verification response malformed - ${json.error}`,
|
|
315
315
|
});
|
|
316
316
|
}
|
|
@@ -322,8 +322,8 @@ export const zkVerify = async (
|
|
|
322
322
|
};
|
|
323
323
|
});
|
|
324
324
|
} catch (e) {
|
|
325
|
-
throw new
|
|
326
|
-
code:
|
|
325
|
+
throw new CofheError({
|
|
326
|
+
code: CofheErrorCode.ZkVerifyFailed,
|
|
327
327
|
message: `ZK proof verification failed`,
|
|
328
328
|
cause: e instanceof Error ? e : undefined,
|
|
329
329
|
});
|