@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
|
@@ -1,61 +1,61 @@
|
|
|
1
|
-
import { hardhat as hardhat$1 } from './chunk-
|
|
2
|
-
import { permitStore, PermitUtils } from './chunk-
|
|
1
|
+
import { hardhat as hardhat$1 } from './chunk-TBLR7NNE.js';
|
|
2
|
+
import { permitStore, PermitUtils, MOCKS_THRESHOLD_NETWORK_ADDRESS, MOCKS_DECRYPT_RESULT_SIGNER_PRIVATE_KEY, MOCKS_ZK_VERIFIER_SIGNER_PRIVATE_KEY, MOCKS_ZK_VERIFIER_ADDRESS } from './chunk-NWDKXBIP.js';
|
|
3
3
|
import { createStore } from 'zustand/vanilla';
|
|
4
|
-
import {
|
|
4
|
+
import { pad, toHex, encodePacked, keccak256, createWalletClient, http, toBytes, hashMessage, getAddress } from 'viem';
|
|
5
5
|
import { hardhat } from 'viem/chains';
|
|
6
|
-
import { privateKeyToAccount } from 'viem/accounts';
|
|
6
|
+
import { sign, privateKeyToAccount } from 'viem/accounts';
|
|
7
7
|
import { z } from 'zod';
|
|
8
8
|
import { persist, createJSONStorage } from 'zustand/middleware';
|
|
9
9
|
import { produce } from 'immer';
|
|
10
10
|
|
|
11
11
|
// core/error.ts
|
|
12
|
-
var
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
return
|
|
57
|
-
})(
|
|
58
|
-
var
|
|
12
|
+
var CofheErrorCode = /* @__PURE__ */ ((CofheErrorCode2) => {
|
|
13
|
+
CofheErrorCode2["InternalError"] = "INTERNAL_ERROR";
|
|
14
|
+
CofheErrorCode2["UnknownEnvironment"] = "UNKNOWN_ENVIRONMENT";
|
|
15
|
+
CofheErrorCode2["InitTfheFailed"] = "INIT_TFHE_FAILED";
|
|
16
|
+
CofheErrorCode2["InitViemFailed"] = "INIT_VIEM_FAILED";
|
|
17
|
+
CofheErrorCode2["InitEthersFailed"] = "INIT_ETHERS_FAILED";
|
|
18
|
+
CofheErrorCode2["NotConnected"] = "NOT_CONNECTED";
|
|
19
|
+
CofheErrorCode2["MissingPublicClient"] = "MISSING_PUBLIC_CLIENT";
|
|
20
|
+
CofheErrorCode2["MissingWalletClient"] = "MISSING_WALLET_CLIENT";
|
|
21
|
+
CofheErrorCode2["MissingProviderParam"] = "MISSING_PROVIDER_PARAM";
|
|
22
|
+
CofheErrorCode2["EmptySecurityZonesParam"] = "EMPTY_SECURITY_ZONES_PARAM";
|
|
23
|
+
CofheErrorCode2["InvalidPermitData"] = "INVALID_PERMIT_DATA";
|
|
24
|
+
CofheErrorCode2["InvalidPermitDomain"] = "INVALID_PERMIT_DOMAIN";
|
|
25
|
+
CofheErrorCode2["PermitNotFound"] = "PERMIT_NOT_FOUND";
|
|
26
|
+
CofheErrorCode2["CannotRemoveLastPermit"] = "CANNOT_REMOVE_LAST_PERMIT";
|
|
27
|
+
CofheErrorCode2["AccountUninitialized"] = "ACCOUNT_UNINITIALIZED";
|
|
28
|
+
CofheErrorCode2["ChainIdUninitialized"] = "CHAIN_ID_UNINITIALIZED";
|
|
29
|
+
CofheErrorCode2["SealOutputFailed"] = "SEAL_OUTPUT_FAILED";
|
|
30
|
+
CofheErrorCode2["SealOutputReturnedNull"] = "SEAL_OUTPUT_RETURNED_NULL";
|
|
31
|
+
CofheErrorCode2["InvalidUtype"] = "INVALID_UTYPE";
|
|
32
|
+
CofheErrorCode2["DecryptFailed"] = "DECRYPT_FAILED";
|
|
33
|
+
CofheErrorCode2["DecryptReturnedNull"] = "DECRYPT_RETURNED_NULL";
|
|
34
|
+
CofheErrorCode2["ZkMocksInsertCtHashesFailed"] = "ZK_MOCKS_INSERT_CT_HASHES_FAILED";
|
|
35
|
+
CofheErrorCode2["ZkMocksCalcCtHashesFailed"] = "ZK_MOCKS_CALC_CT_HASHES_FAILED";
|
|
36
|
+
CofheErrorCode2["ZkMocksVerifySignFailed"] = "ZK_MOCKS_VERIFY_SIGN_FAILED";
|
|
37
|
+
CofheErrorCode2["ZkMocksCreateProofSignatureFailed"] = "ZK_MOCKS_CREATE_PROOF_SIGNATURE_FAILED";
|
|
38
|
+
CofheErrorCode2["ZkVerifyFailed"] = "ZK_VERIFY_FAILED";
|
|
39
|
+
CofheErrorCode2["ZkPackFailed"] = "ZK_PACK_FAILED";
|
|
40
|
+
CofheErrorCode2["ZkProveFailed"] = "ZK_PROVE_FAILED";
|
|
41
|
+
CofheErrorCode2["EncryptRemainingInItems"] = "ENCRYPT_REMAINING_IN_ITEMS";
|
|
42
|
+
CofheErrorCode2["ZkUninitialized"] = "ZK_UNINITIALIZED";
|
|
43
|
+
CofheErrorCode2["ZkVerifierUrlUninitialized"] = "ZK_VERIFIER_URL_UNINITIALIZED";
|
|
44
|
+
CofheErrorCode2["ThresholdNetworkUrlUninitialized"] = "THRESHOLD_NETWORK_URL_UNINITIALIZED";
|
|
45
|
+
CofheErrorCode2["MissingConfig"] = "MISSING_CONFIG";
|
|
46
|
+
CofheErrorCode2["UnsupportedChain"] = "UNSUPPORTED_CHAIN";
|
|
47
|
+
CofheErrorCode2["MissingZkBuilderAndCrsGenerator"] = "MISSING_ZK_BUILDER_AND_CRS_GENERATOR";
|
|
48
|
+
CofheErrorCode2["MissingTfhePublicKeyDeserializer"] = "MISSING_TFHE_PUBLIC_KEY_DESERIALIZER";
|
|
49
|
+
CofheErrorCode2["MissingCompactPkeCrsDeserializer"] = "MISSING_COMPACT_PKE_CRS_DESERIALIZER";
|
|
50
|
+
CofheErrorCode2["MissingFheKey"] = "MISSING_FHE_KEY";
|
|
51
|
+
CofheErrorCode2["MissingCrs"] = "MISSING_CRS";
|
|
52
|
+
CofheErrorCode2["FetchKeysFailed"] = "FETCH_KEYS_FAILED";
|
|
53
|
+
CofheErrorCode2["PublicWalletGetChainIdFailed"] = "PUBLIC_WALLET_GET_CHAIN_ID_FAILED";
|
|
54
|
+
CofheErrorCode2["PublicWalletGetAddressesFailed"] = "PUBLIC_WALLET_GET_ADDRESSES_FAILED";
|
|
55
|
+
CofheErrorCode2["RehydrateKeysStoreFailed"] = "REHYDRATE_KEYS_STORE_FAILED";
|
|
56
|
+
return CofheErrorCode2;
|
|
57
|
+
})(CofheErrorCode || {});
|
|
58
|
+
var CofheError = class _CofheError extends Error {
|
|
59
59
|
code;
|
|
60
60
|
cause;
|
|
61
61
|
hint;
|
|
@@ -63,25 +63,25 @@ var CofhesdkError = class _CofhesdkError extends Error {
|
|
|
63
63
|
constructor({ code, message, cause, hint, context }) {
|
|
64
64
|
const fullMessage = cause ? `${message} | Caused by: ${cause.message}` : message;
|
|
65
65
|
super(fullMessage);
|
|
66
|
-
this.name = "
|
|
66
|
+
this.name = "CofheError";
|
|
67
67
|
this.code = code;
|
|
68
68
|
this.cause = cause;
|
|
69
69
|
this.hint = hint;
|
|
70
70
|
this.context = context;
|
|
71
71
|
if (Error.captureStackTrace) {
|
|
72
|
-
Error.captureStackTrace(this,
|
|
72
|
+
Error.captureStackTrace(this, _CofheError);
|
|
73
73
|
}
|
|
74
74
|
}
|
|
75
75
|
/**
|
|
76
|
-
* Creates a
|
|
77
|
-
* If the error is a
|
|
78
|
-
* If a wrapperError is provided, it is used to create the new
|
|
76
|
+
* Creates a CofheError from an unknown error
|
|
77
|
+
* If the error is a CofheError, it is returned unchanged, else a new CofheError is created
|
|
78
|
+
* If a wrapperError is provided, it is used to create the new CofheError, else a default is used
|
|
79
79
|
*/
|
|
80
80
|
static fromError(error, wrapperError) {
|
|
81
|
-
if (
|
|
81
|
+
if (isCofheError(error))
|
|
82
82
|
return error;
|
|
83
83
|
const cause = error instanceof Error ? error : new Error(`${error}`);
|
|
84
|
-
return new
|
|
84
|
+
return new _CofheError({
|
|
85
85
|
code: wrapperError?.code ?? "INTERNAL_ERROR" /* InternalError */,
|
|
86
86
|
message: wrapperError?.message ?? "An internal error occurred",
|
|
87
87
|
hint: wrapperError?.hint,
|
|
@@ -141,7 +141,7 @@ var bigintSafeJsonStringify = (value) => {
|
|
|
141
141
|
return value2;
|
|
142
142
|
});
|
|
143
143
|
};
|
|
144
|
-
var
|
|
144
|
+
var isCofheError = (error) => error instanceof CofheError;
|
|
145
145
|
|
|
146
146
|
// core/types.ts
|
|
147
147
|
var FheTypes = /* @__PURE__ */ ((FheTypes2) => {
|
|
@@ -292,14 +292,14 @@ async function getPublicClientChainID(publicClient) {
|
|
|
292
292
|
try {
|
|
293
293
|
chainId = publicClient.chain?.id ?? await publicClient.getChainId();
|
|
294
294
|
} catch (e) {
|
|
295
|
-
throw new
|
|
295
|
+
throw new CofheError({
|
|
296
296
|
code: "PUBLIC_WALLET_GET_CHAIN_ID_FAILED" /* PublicWalletGetChainIdFailed */,
|
|
297
297
|
message: "getting chain ID from public client failed",
|
|
298
298
|
cause: e instanceof Error ? e : void 0
|
|
299
299
|
});
|
|
300
300
|
}
|
|
301
301
|
if (chainId === null) {
|
|
302
|
-
throw new
|
|
302
|
+
throw new CofheError({
|
|
303
303
|
code: "PUBLIC_WALLET_GET_CHAIN_ID_FAILED" /* PublicWalletGetChainIdFailed */,
|
|
304
304
|
message: "chain ID from public client is null"
|
|
305
305
|
});
|
|
@@ -314,14 +314,14 @@ async function getWalletClientAccount(walletClient) {
|
|
|
314
314
|
address = (await walletClient.getAddresses())?.[0];
|
|
315
315
|
}
|
|
316
316
|
} catch (e) {
|
|
317
|
-
throw new
|
|
317
|
+
throw new CofheError({
|
|
318
318
|
code: "PUBLIC_WALLET_GET_ADDRESSES_FAILED" /* PublicWalletGetAddressesFailed */,
|
|
319
319
|
message: "getting address from wallet client failed",
|
|
320
320
|
cause: e instanceof Error ? e : void 0
|
|
321
321
|
});
|
|
322
322
|
}
|
|
323
323
|
if (!address) {
|
|
324
|
-
throw new
|
|
324
|
+
throw new CofheError({
|
|
325
325
|
code: "PUBLIC_WALLET_GET_ADDRESSES_FAILED" /* PublicWalletGetAddressesFailed */,
|
|
326
326
|
message: "address from wallet client is null"
|
|
327
327
|
});
|
|
@@ -425,7 +425,7 @@ var zkPack = (items, builder) => {
|
|
|
425
425
|
break;
|
|
426
426
|
}
|
|
427
427
|
default: {
|
|
428
|
-
throw new
|
|
428
|
+
throw new CofheError({
|
|
429
429
|
code: "ZK_PACK_FAILED" /* ZkPackFailed */,
|
|
430
430
|
message: `Invalid utype: ${item.utype}`,
|
|
431
431
|
hint: `Ensure that the utype is valid, using the Encryptable type, for example: Encryptable.uint128(100n)`,
|
|
@@ -437,7 +437,7 @@ var zkPack = (items, builder) => {
|
|
|
437
437
|
}
|
|
438
438
|
}
|
|
439
439
|
if (totalBits > MAX_ENCRYPTABLE_BITS) {
|
|
440
|
-
throw new
|
|
440
|
+
throw new CofheError({
|
|
441
441
|
code: "ZK_PACK_FAILED" /* ZkPackFailed */,
|
|
442
442
|
message: `Total bits ${totalBits} exceeds ${MAX_ENCRYPTABLE_BITS}`,
|
|
443
443
|
hint: `Ensure that the total bits of the items to encrypt does not exceed ${MAX_ENCRYPTABLE_BITS}`,
|
|
@@ -501,14 +501,14 @@ var zkVerify = async (verifierUrl, serializedBytes, address, securityZone, chain
|
|
|
501
501
|
});
|
|
502
502
|
if (!response.ok) {
|
|
503
503
|
const errorBody = await response.text();
|
|
504
|
-
throw new
|
|
504
|
+
throw new CofheError({
|
|
505
505
|
code: "ZK_VERIFY_FAILED" /* ZkVerifyFailed */,
|
|
506
506
|
message: `HTTP error! ZK proof verification failed - ${errorBody}`
|
|
507
507
|
});
|
|
508
508
|
}
|
|
509
509
|
const json = await response.json();
|
|
510
510
|
if (json.status !== "success") {
|
|
511
|
-
throw new
|
|
511
|
+
throw new CofheError({
|
|
512
512
|
code: "ZK_VERIFY_FAILED" /* ZkVerifyFailed */,
|
|
513
513
|
message: `ZK proof verification response malformed - ${json.error}`
|
|
514
514
|
});
|
|
@@ -520,7 +520,7 @@ var zkVerify = async (verifierUrl, serializedBytes, address, securityZone, chain
|
|
|
520
520
|
};
|
|
521
521
|
});
|
|
522
522
|
} catch (e) {
|
|
523
|
-
throw new
|
|
523
|
+
throw new CofheError({
|
|
524
524
|
code: "ZK_VERIFY_FAILED" /* ZkVerifyFailed */,
|
|
525
525
|
message: `ZK proof verification failed`,
|
|
526
526
|
cause: e instanceof Error ? e : void 0
|
|
@@ -638,9 +638,6 @@ var MockZkVerifierAbi = [
|
|
|
638
638
|
},
|
|
639
639
|
{ type: "error", name: "InvalidInputs", inputs: [] }
|
|
640
640
|
];
|
|
641
|
-
var MocksZkVerifierAddress = "0x0000000000000000000000000000000000000100";
|
|
642
|
-
var MOCKS_ZK_VERIFIER_SIGNER_PRIVATE_KEY = "0x6C8D7F768A6BB4AAFE85E8A2F5A9680355239C7E14646ED62B044E39DE154512";
|
|
643
|
-
var MOCKS_ZK_VERIFIER_SIGNER_ADDRESS = "0x6E12D8C87503D4287c294f2Fdef96ACd9DFf6bd2";
|
|
644
641
|
function createMockZkVerifierSigner() {
|
|
645
642
|
return createWalletClient({
|
|
646
643
|
chain: hardhat,
|
|
@@ -683,7 +680,7 @@ async function cofheMocksCheckEncryptableBits(items) {
|
|
|
683
680
|
}
|
|
684
681
|
}
|
|
685
682
|
if (totalBits > MAX_ENCRYPTABLE_BITS) {
|
|
686
|
-
throw new
|
|
683
|
+
throw new CofheError({
|
|
687
684
|
code: "ZK_PACK_FAILED" /* ZkPackFailed */,
|
|
688
685
|
message: `Total bits ${totalBits} exceeds ${MAX_ENCRYPTABLE_BITS}`,
|
|
689
686
|
hint: `Ensure that the total bits of the items to encrypt does not exceed ${MAX_ENCRYPTABLE_BITS}`,
|
|
@@ -706,18 +703,18 @@ async function calcCtHashes(items, account, securityZone, publicClient) {
|
|
|
706
703
|
let ctHashes;
|
|
707
704
|
try {
|
|
708
705
|
ctHashes = await publicClient.readContract({
|
|
709
|
-
address:
|
|
706
|
+
address: MOCKS_ZK_VERIFIER_ADDRESS,
|
|
710
707
|
abi: MockZkVerifierAbi,
|
|
711
708
|
functionName: "zkVerifyCalcCtHashesPacked",
|
|
712
709
|
args: calcCtHashesArgs
|
|
713
710
|
});
|
|
714
711
|
} catch (err) {
|
|
715
|
-
throw new
|
|
712
|
+
throw new CofheError({
|
|
716
713
|
code: "ZK_MOCKS_CALC_CT_HASHES_FAILED" /* ZkMocksCalcCtHashesFailed */,
|
|
717
714
|
message: `mockZkVerifySign calcCtHashes failed while calling zkVerifyCalcCtHashesPacked`,
|
|
718
715
|
cause: err instanceof Error ? err : void 0,
|
|
719
716
|
context: {
|
|
720
|
-
address:
|
|
717
|
+
address: MOCKS_ZK_VERIFIER_ADDRESS,
|
|
721
718
|
items,
|
|
722
719
|
account,
|
|
723
720
|
securityZone,
|
|
@@ -727,7 +724,7 @@ async function calcCtHashes(items, account, securityZone, publicClient) {
|
|
|
727
724
|
});
|
|
728
725
|
}
|
|
729
726
|
if (ctHashes.length !== items.length) {
|
|
730
|
-
throw new
|
|
727
|
+
throw new CofheError({
|
|
731
728
|
code: "ZK_MOCKS_CALC_CT_HASHES_FAILED" /* ZkMocksCalcCtHashesFailed */,
|
|
732
729
|
message: `mockZkVerifySign calcCtHashes returned incorrect number of ctHashes`,
|
|
733
730
|
context: {
|
|
@@ -750,7 +747,7 @@ async function insertCtHashes(items, walletClient) {
|
|
|
750
747
|
try {
|
|
751
748
|
const account = walletClient.account;
|
|
752
749
|
await walletClient.writeContract({
|
|
753
|
-
address:
|
|
750
|
+
address: MOCKS_ZK_VERIFIER_ADDRESS,
|
|
754
751
|
abi: MockZkVerifierAbi,
|
|
755
752
|
functionName: "insertPackedCtHashes",
|
|
756
753
|
args: insertPackedCtHashesArgs,
|
|
@@ -758,7 +755,7 @@ async function insertCtHashes(items, walletClient) {
|
|
|
758
755
|
account
|
|
759
756
|
});
|
|
760
757
|
} catch (err) {
|
|
761
|
-
throw new
|
|
758
|
+
throw new CofheError({
|
|
762
759
|
code: "ZK_MOCKS_INSERT_CT_HASHES_FAILED" /* ZkMocksInsertCtHashesFailed */,
|
|
763
760
|
message: `mockZkVerifySign insertPackedCtHashes failed while calling insertPackedCtHashes`,
|
|
764
761
|
cause: err instanceof Error ? err : void 0,
|
|
@@ -776,7 +773,7 @@ async function createProofSignatures(items, securityZone) {
|
|
|
776
773
|
try {
|
|
777
774
|
encInputSignerClient = createMockZkVerifierSigner();
|
|
778
775
|
} catch (err) {
|
|
779
|
-
throw new
|
|
776
|
+
throw new CofheError({
|
|
780
777
|
code: "ZK_MOCKS_CREATE_PROOF_SIGNATURE_FAILED" /* ZkMocksCreateProofSignatureFailed */,
|
|
781
778
|
message: `mockZkVerifySign createProofSignatures failed while creating wallet client`,
|
|
782
779
|
cause: err instanceof Error ? err : void 0,
|
|
@@ -797,7 +794,7 @@ async function createProofSignatures(items, securityZone) {
|
|
|
797
794
|
signatures.push(signature);
|
|
798
795
|
}
|
|
799
796
|
} catch (err) {
|
|
800
|
-
throw new
|
|
797
|
+
throw new CofheError({
|
|
801
798
|
code: "ZK_MOCKS_CREATE_PROOF_SIGNATURE_FAILED" /* ZkMocksCreateProofSignatureFailed */,
|
|
802
799
|
message: `mockZkVerifySign createProofSignatures failed while calling signMessage`,
|
|
803
800
|
cause: err instanceof Error ? err : void 0,
|
|
@@ -808,7 +805,7 @@ async function createProofSignatures(items, securityZone) {
|
|
|
808
805
|
});
|
|
809
806
|
}
|
|
810
807
|
if (signatures.length !== items.length) {
|
|
811
|
-
throw new
|
|
808
|
+
throw new CofheError({
|
|
812
809
|
code: "ZK_MOCKS_CREATE_PROOF_SIGNATURE_FAILED" /* ZkMocksCreateProofSignatureFailed */,
|
|
813
810
|
message: `mockZkVerifySign createProofSignatures returned incorrect number of signatures`,
|
|
814
811
|
context: {
|
|
@@ -829,46 +826,51 @@ async function cofheMocksZkVerifySign(items, account, securityZone, publicClient
|
|
|
829
826
|
signature: signatures[index]
|
|
830
827
|
}));
|
|
831
828
|
}
|
|
832
|
-
var
|
|
829
|
+
var CofheConfigSchema = z.object({
|
|
833
830
|
/** Environment that the SDK is running in */
|
|
834
831
|
environment: z.enum(["node", "hardhat", "web", "react"]).optional().default("node"),
|
|
835
832
|
/** List of supported chain configurations */
|
|
836
833
|
supportedChains: z.array(z.custom()),
|
|
837
|
-
/** How permits are generated */
|
|
838
|
-
permitGeneration: z.enum(["ON_CONNECT", "ON_DECRYPT_HANDLES", "MANUAL"]).optional().default("ON_CONNECT"),
|
|
839
834
|
/** Default permit expiration in seconds, default is 30 days */
|
|
840
835
|
defaultPermitExpiration: z.number().optional().default(60 * 60 * 24 * 30),
|
|
841
836
|
/** Storage method for fhe keys (defaults to indexedDB on web, filesystem on node) */
|
|
842
837
|
fheKeyStorage: z.object({
|
|
843
|
-
getItem: z.
|
|
844
|
-
|
|
845
|
-
|
|
838
|
+
getItem: z.custom((val) => typeof val === "function", {
|
|
839
|
+
message: "getItem must be a function"
|
|
840
|
+
}),
|
|
841
|
+
setItem: z.custom((val) => typeof val === "function", {
|
|
842
|
+
message: "setItem must be a function"
|
|
843
|
+
}),
|
|
844
|
+
removeItem: z.custom((val) => typeof val === "function", {
|
|
845
|
+
message: "removeItem must be a function"
|
|
846
|
+
})
|
|
846
847
|
}).or(z.null()).default(null),
|
|
847
848
|
/** Whether to use Web Workers for ZK proof generation (web platform only) */
|
|
848
849
|
useWorkers: z.boolean().optional().default(true),
|
|
849
850
|
/** Mocks configs */
|
|
850
851
|
mocks: z.object({
|
|
851
|
-
|
|
852
|
-
|
|
852
|
+
decryptDelay: z.number().optional().default(0),
|
|
853
|
+
encryptDelay: z.union([z.number(), z.tuple([z.number(), z.number(), z.number(), z.number(), z.number()])]).optional().default([100, 100, 100, 500, 500])
|
|
854
|
+
}).optional().default({ decryptDelay: 0, encryptDelay: [100, 100, 100, 500, 500] }),
|
|
853
855
|
/** Internal configuration */
|
|
854
856
|
_internal: z.object({
|
|
855
857
|
zkvWalletClient: z.any().optional()
|
|
856
858
|
}).optional()
|
|
857
859
|
});
|
|
858
|
-
function
|
|
859
|
-
const result =
|
|
860
|
+
function createCofheConfigBase(config) {
|
|
861
|
+
const result = CofheConfigSchema.safeParse(config);
|
|
860
862
|
if (!result.success) {
|
|
861
|
-
throw new Error(`Invalid
|
|
863
|
+
throw new Error(`Invalid cofhe configuration: ${z.prettifyError(result.error)}`, { cause: result.error });
|
|
862
864
|
}
|
|
863
865
|
return result.data;
|
|
864
866
|
}
|
|
865
|
-
var
|
|
867
|
+
var getCofheConfigItem = (config, key) => {
|
|
866
868
|
return config[key];
|
|
867
869
|
};
|
|
868
870
|
function getSupportedChainOrThrow(config, chainId) {
|
|
869
871
|
const supportedChain = config.supportedChains.find((chain) => chain.id === chainId);
|
|
870
872
|
if (!supportedChain) {
|
|
871
|
-
throw new
|
|
873
|
+
throw new CofheError({
|
|
872
874
|
code: "UNSUPPORTED_CHAIN" /* UnsupportedChain */,
|
|
873
875
|
message: `Config does not support chain <${chainId}>`,
|
|
874
876
|
hint: "Ensure config passed to client has been created with this chain in the config.supportedChains array.",
|
|
@@ -884,7 +886,7 @@ function getCoFheUrlOrThrow(config, chainId) {
|
|
|
884
886
|
const supportedChain = getSupportedChainOrThrow(config, chainId);
|
|
885
887
|
const url = supportedChain.coFheUrl;
|
|
886
888
|
if (!url) {
|
|
887
|
-
throw new
|
|
889
|
+
throw new CofheError({
|
|
888
890
|
code: "MISSING_CONFIG" /* MissingConfig */,
|
|
889
891
|
message: `CoFHE URL is not configured for chain <${chainId}>`,
|
|
890
892
|
hint: "Ensure this chain config includes a coFheUrl property.",
|
|
@@ -897,7 +899,7 @@ function getZkVerifierUrlOrThrow(config, chainId) {
|
|
|
897
899
|
const supportedChain = getSupportedChainOrThrow(config, chainId);
|
|
898
900
|
const url = supportedChain.verifierUrl;
|
|
899
901
|
if (!url) {
|
|
900
|
-
throw new
|
|
902
|
+
throw new CofheError({
|
|
901
903
|
code: "ZK_VERIFIER_URL_UNINITIALIZED" /* ZkVerifierUrlUninitialized */,
|
|
902
904
|
message: `ZK verifier URL is not configured for chain <${chainId}>`,
|
|
903
905
|
hint: "Ensure this chain config includes a verifierUrl property.",
|
|
@@ -910,7 +912,7 @@ function getThresholdNetworkUrlOrThrow(config, chainId) {
|
|
|
910
912
|
const supportedChain = getSupportedChainOrThrow(config, chainId);
|
|
911
913
|
const url = supportedChain.thresholdNetworkUrl;
|
|
912
914
|
if (!url) {
|
|
913
|
-
throw new
|
|
915
|
+
throw new CofheError({
|
|
914
916
|
code: "THRESHOLD_NETWORK_URL_UNINITIALIZED" /* ThresholdNetworkUrlUninitialized */,
|
|
915
917
|
message: `Threshold network URL is not configured for chain <${chainId}>`,
|
|
916
918
|
hint: "Ensure this chain config includes a thresholdNetworkUrl property.",
|
|
@@ -1122,7 +1124,7 @@ var BaseBuilder = class {
|
|
|
1122
1124
|
account;
|
|
1123
1125
|
constructor(params) {
|
|
1124
1126
|
if (!params.config) {
|
|
1125
|
-
throw new
|
|
1127
|
+
throw new CofheError({
|
|
1126
1128
|
code: "MISSING_CONFIG" /* MissingConfig */,
|
|
1127
1129
|
message: "Builder config is undefined",
|
|
1128
1130
|
hint: "Ensure client has been created with a config.",
|
|
@@ -1140,12 +1142,12 @@ var BaseBuilder = class {
|
|
|
1140
1142
|
}
|
|
1141
1143
|
/**
|
|
1142
1144
|
* Asserts that this.chainId is populated
|
|
1143
|
-
* @throws {
|
|
1145
|
+
* @throws {CofheError} If chainId is not set
|
|
1144
1146
|
*/
|
|
1145
1147
|
assertChainId() {
|
|
1146
1148
|
if (this.chainId)
|
|
1147
1149
|
return;
|
|
1148
|
-
throw new
|
|
1150
|
+
throw new CofheError({
|
|
1149
1151
|
code: "CHAIN_ID_UNINITIALIZED" /* ChainIdUninitialized */,
|
|
1150
1152
|
message: "Chain ID is not set",
|
|
1151
1153
|
hint: "Ensure client.connect() has been called and awaited, or use setChainId(...) to set the chainId explicitly.",
|
|
@@ -1156,12 +1158,12 @@ var BaseBuilder = class {
|
|
|
1156
1158
|
}
|
|
1157
1159
|
/**
|
|
1158
1160
|
* Asserts that this.account is populated
|
|
1159
|
-
* @throws {
|
|
1161
|
+
* @throws {CofheError} If account is not set
|
|
1160
1162
|
*/
|
|
1161
1163
|
assertAccount() {
|
|
1162
1164
|
if (this.account)
|
|
1163
1165
|
return;
|
|
1164
|
-
throw new
|
|
1166
|
+
throw new CofheError({
|
|
1165
1167
|
code: "ACCOUNT_UNINITIALIZED" /* AccountUninitialized */,
|
|
1166
1168
|
message: "Account is not set",
|
|
1167
1169
|
hint: "Ensure client.connect() has been called and awaited, or use setAccount(...) to set the account explicitly.",
|
|
@@ -1172,12 +1174,12 @@ var BaseBuilder = class {
|
|
|
1172
1174
|
}
|
|
1173
1175
|
/**
|
|
1174
1176
|
* Asserts that this.publicClient is populated
|
|
1175
|
-
* @throws {
|
|
1177
|
+
* @throws {CofheError} If publicClient is not set
|
|
1176
1178
|
*/
|
|
1177
1179
|
assertPublicClient() {
|
|
1178
1180
|
if (this.publicClient)
|
|
1179
1181
|
return;
|
|
1180
|
-
throw new
|
|
1182
|
+
throw new CofheError({
|
|
1181
1183
|
code: "MISSING_PUBLIC_CLIENT" /* MissingPublicClient */,
|
|
1182
1184
|
message: "Public client not found",
|
|
1183
1185
|
hint: "Ensure client.connect() has been called with a publicClient.",
|
|
@@ -1188,12 +1190,12 @@ var BaseBuilder = class {
|
|
|
1188
1190
|
}
|
|
1189
1191
|
/**
|
|
1190
1192
|
* Asserts that this.walletClient is populated
|
|
1191
|
-
* @throws {
|
|
1193
|
+
* @throws {CofheError} If walletClient is not set
|
|
1192
1194
|
*/
|
|
1193
1195
|
assertWalletClient() {
|
|
1194
1196
|
if (this.walletClient)
|
|
1195
1197
|
return;
|
|
1196
|
-
throw new
|
|
1198
|
+
throw new CofheError({
|
|
1197
1199
|
code: "MISSING_WALLET_CLIENT" /* MissingWalletClient */,
|
|
1198
1200
|
message: "Wallet client not found",
|
|
1199
1201
|
hint: "Ensure client.connect() has been called with a walletClient.",
|
|
@@ -1238,7 +1240,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
|
|
|
1238
1240
|
this.securityZone = params.securityZone ?? 0;
|
|
1239
1241
|
this.zkvWalletClient = params.zkvWalletClient;
|
|
1240
1242
|
if (!params.tfhePublicKeyDeserializer) {
|
|
1241
|
-
throw new
|
|
1243
|
+
throw new CofheError({
|
|
1242
1244
|
code: "MISSING_TFHE_PUBLIC_KEY_DESERIALIZER" /* MissingTfhePublicKeyDeserializer */,
|
|
1243
1245
|
message: "EncryptInputsBuilder tfhePublicKeyDeserializer is undefined",
|
|
1244
1246
|
hint: "Ensure client has been created with a tfhePublicKeyDeserializer.",
|
|
@@ -1249,7 +1251,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
|
|
|
1249
1251
|
}
|
|
1250
1252
|
this.tfhePublicKeyDeserializer = params.tfhePublicKeyDeserializer;
|
|
1251
1253
|
if (!params.compactPkeCrsDeserializer) {
|
|
1252
|
-
throw new
|
|
1254
|
+
throw new CofheError({
|
|
1253
1255
|
code: "MISSING_COMPACT_PKE_CRS_DESERIALIZER" /* MissingCompactPkeCrsDeserializer */,
|
|
1254
1256
|
message: "EncryptInputsBuilder compactPkeCrsDeserializer is undefined",
|
|
1255
1257
|
hint: "Ensure client has been created with a compactPkeCrsDeserializer.",
|
|
@@ -1260,7 +1262,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
|
|
|
1260
1262
|
}
|
|
1261
1263
|
this.compactPkeCrsDeserializer = params.compactPkeCrsDeserializer;
|
|
1262
1264
|
if (!params.zkBuilderAndCrsGenerator) {
|
|
1263
|
-
throw new
|
|
1265
|
+
throw new CofheError({
|
|
1264
1266
|
code: "MISSING_ZK_BUILDER_AND_CRS_GENERATOR" /* MissingZkBuilderAndCrsGenerator */,
|
|
1265
1267
|
message: "EncryptInputsBuilder zkBuilderAndCrsGenerator is undefined",
|
|
1266
1268
|
hint: "Ensure client has been created with a zkBuilderAndCrsGenerator.",
|
|
@@ -1284,7 +1286,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
|
|
|
1284
1286
|
* ```typescript
|
|
1285
1287
|
* const encrypted = await encryptInputs([Encryptable.uint128(10n)])
|
|
1286
1288
|
* .setAccount("0x123")
|
|
1287
|
-
* .
|
|
1289
|
+
* .execute();
|
|
1288
1290
|
* ```
|
|
1289
1291
|
*
|
|
1290
1292
|
* @returns The chainable EncryptInputsBuilder instance.
|
|
@@ -1305,7 +1307,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
|
|
|
1305
1307
|
* ```typescript
|
|
1306
1308
|
* const encrypted = await encryptInputs([Encryptable.uint128(10n)])
|
|
1307
1309
|
* .setChainId(11155111)
|
|
1308
|
-
* .
|
|
1310
|
+
* .execute();
|
|
1309
1311
|
* ```
|
|
1310
1312
|
*
|
|
1311
1313
|
* @returns The chainable EncryptInputsBuilder instance.
|
|
@@ -1326,7 +1328,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
|
|
|
1326
1328
|
* ```typescript
|
|
1327
1329
|
* const encrypted = await encryptInputs([Encryptable.uint128(10n)])
|
|
1328
1330
|
* .setSecurityZone(1)
|
|
1329
|
-
* .
|
|
1331
|
+
* .execute();
|
|
1330
1332
|
* ```
|
|
1331
1333
|
*
|
|
1332
1334
|
* @returns The chainable EncryptInputsBuilder instance.
|
|
@@ -1347,7 +1349,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
|
|
|
1347
1349
|
* ```typescript
|
|
1348
1350
|
* const encrypted = await encryptInputs([Encryptable.uint128(10n)])
|
|
1349
1351
|
* .setUseWorker(false)
|
|
1350
|
-
* .
|
|
1352
|
+
* .execute();
|
|
1351
1353
|
* ```
|
|
1352
1354
|
*
|
|
1353
1355
|
* @returns The chainable EncryptInputsBuilder instance.
|
|
@@ -1381,13 +1383,13 @@ var EncryptInputsBuilder = class extends BaseBuilder {
|
|
|
1381
1383
|
* Example:
|
|
1382
1384
|
* ```typescript
|
|
1383
1385
|
* const encrypted = await encryptInputs([Encryptable.uint128(10n)])
|
|
1384
|
-
* .
|
|
1385
|
-
* .
|
|
1386
|
+
* .onStep((step: EncryptStep) => console.log(step))
|
|
1387
|
+
* .execute();
|
|
1386
1388
|
* ```
|
|
1387
1389
|
*
|
|
1388
1390
|
* @returns The EncryptInputsBuilder instance.
|
|
1389
1391
|
*/
|
|
1390
|
-
|
|
1392
|
+
onStep(callback) {
|
|
1391
1393
|
this.stepCallback = callback;
|
|
1392
1394
|
return this;
|
|
1393
1395
|
}
|
|
@@ -1410,7 +1412,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
|
|
|
1410
1412
|
this.stepCallback(step, { ...context, isStart: false, isEnd: true, duration });
|
|
1411
1413
|
}
|
|
1412
1414
|
/**
|
|
1413
|
-
* zkVerifierUrl is included in the chains exported from
|
|
1415
|
+
* zkVerifierUrl is included in the chains exported from @cofhe/sdk/chains for use in CofheConfig.supportedChains
|
|
1414
1416
|
* Users should generally not set this manually.
|
|
1415
1417
|
*/
|
|
1416
1418
|
async getZkVerifierUrl() {
|
|
@@ -1418,7 +1420,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
|
|
|
1418
1420
|
return getZkVerifierUrlOrThrow(this.config, this.chainId);
|
|
1419
1421
|
}
|
|
1420
1422
|
/**
|
|
1421
|
-
* initTfhe is a platform-specific dependency injected into core/
|
|
1423
|
+
* initTfhe is a platform-specific dependency injected into core/createCofheClientBase by web/createCofheClient and node/createCofheClient
|
|
1422
1424
|
* web/ uses zama "tfhe"
|
|
1423
1425
|
* node/ uses zama "node-tfhe"
|
|
1424
1426
|
* Users should not set this manually.
|
|
@@ -1429,7 +1431,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
|
|
|
1429
1431
|
try {
|
|
1430
1432
|
return await this.initTfhe();
|
|
1431
1433
|
} catch (error) {
|
|
1432
|
-
throw
|
|
1434
|
+
throw CofheError.fromError(error, {
|
|
1433
1435
|
code: "INIT_TFHE_FAILED" /* InitTfheFailed */,
|
|
1434
1436
|
message: `Failed to initialize TFHE`,
|
|
1435
1437
|
context: {
|
|
@@ -1448,7 +1450,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
|
|
|
1448
1450
|
try {
|
|
1449
1451
|
await this.keysStorage?.rehydrateKeysStore();
|
|
1450
1452
|
} catch (error) {
|
|
1451
|
-
throw
|
|
1453
|
+
throw CofheError.fromError(error, {
|
|
1452
1454
|
code: "REHYDRATE_KEYS_STORE_FAILED" /* RehydrateKeysStoreFailed */,
|
|
1453
1455
|
message: `Failed to rehydrate keys store`,
|
|
1454
1456
|
context: {
|
|
@@ -1470,7 +1472,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
|
|
|
1470
1472
|
this.keysStorage
|
|
1471
1473
|
);
|
|
1472
1474
|
} catch (error) {
|
|
1473
|
-
throw
|
|
1475
|
+
throw CofheError.fromError(error, {
|
|
1474
1476
|
code: "FETCH_KEYS_FAILED" /* FetchKeysFailed */,
|
|
1475
1477
|
message: `Failed to fetch FHE key and CRS`,
|
|
1476
1478
|
context: {
|
|
@@ -1483,7 +1485,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
|
|
|
1483
1485
|
});
|
|
1484
1486
|
}
|
|
1485
1487
|
if (!fheKey) {
|
|
1486
|
-
throw new
|
|
1488
|
+
throw new CofheError({
|
|
1487
1489
|
code: "MISSING_FHE_KEY" /* MissingFheKey */,
|
|
1488
1490
|
message: `FHE key not found`,
|
|
1489
1491
|
context: {
|
|
@@ -1493,7 +1495,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
|
|
|
1493
1495
|
});
|
|
1494
1496
|
}
|
|
1495
1497
|
if (!crs) {
|
|
1496
|
-
throw new
|
|
1498
|
+
throw new CofheError({
|
|
1497
1499
|
code: "MISSING_CRS" /* MissingCrs */,
|
|
1498
1500
|
message: `CRS not found for chainId <${this.chainId}>`,
|
|
1499
1501
|
context: {
|
|
@@ -1503,6 +1505,17 @@ var EncryptInputsBuilder = class extends BaseBuilder {
|
|
|
1503
1505
|
}
|
|
1504
1506
|
return { fheKey, fheKeyFetchedFromCoFHE, crs, crsFetchedFromCoFHE };
|
|
1505
1507
|
}
|
|
1508
|
+
/**
|
|
1509
|
+
* Resolves the encryptDelay config into an array of 5 per-step delays.
|
|
1510
|
+
* A single number is broadcast to all steps; a tuple is used as-is.
|
|
1511
|
+
*/
|
|
1512
|
+
resolveEncryptDelays() {
|
|
1513
|
+
const encryptDelay = this.config?.mocks?.encryptDelay ?? [100, 100, 100, 500, 500];
|
|
1514
|
+
if (typeof encryptDelay === "number") {
|
|
1515
|
+
return [encryptDelay, encryptDelay, encryptDelay, encryptDelay, encryptDelay];
|
|
1516
|
+
}
|
|
1517
|
+
return encryptDelay;
|
|
1518
|
+
}
|
|
1506
1519
|
/**
|
|
1507
1520
|
* @dev Encrypt against the cofheMocks instead of CoFHE
|
|
1508
1521
|
*
|
|
@@ -1510,25 +1523,35 @@ var EncryptInputsBuilder = class extends BaseBuilder {
|
|
|
1510
1523
|
* cofheMocksInsertPackedHashes - stores the ctHashes and their plaintext values for on-chain mocking of FHE operations.
|
|
1511
1524
|
* cofheMocksZkCreateProofSignatures - creates signatures to be included in the encrypted inputs. The signers address is known and verified in the mock contracts.
|
|
1512
1525
|
*/
|
|
1513
|
-
async
|
|
1526
|
+
async mocksExecute() {
|
|
1514
1527
|
this.assertAccount();
|
|
1515
1528
|
this.assertPublicClient();
|
|
1516
1529
|
this.assertWalletClient();
|
|
1530
|
+
const [initTfheDelay, fetchKeysDelay, packDelay, proveDelay, verifyDelay] = this.resolveEncryptDelays();
|
|
1517
1531
|
this.fireStepStart("initTfhe" /* InitTfhe */);
|
|
1518
|
-
await sleep(
|
|
1519
|
-
this.fireStepEnd("initTfhe" /* InitTfhe */, {
|
|
1532
|
+
await sleep(initTfheDelay);
|
|
1533
|
+
this.fireStepEnd("initTfhe" /* InitTfhe */, {
|
|
1534
|
+
tfheInitializationExecuted: false,
|
|
1535
|
+
isMocks: true,
|
|
1536
|
+
mockSleep: initTfheDelay
|
|
1537
|
+
});
|
|
1520
1538
|
this.fireStepStart("fetchKeys" /* FetchKeys */);
|
|
1521
|
-
await sleep(
|
|
1522
|
-
this.fireStepEnd("fetchKeys" /* FetchKeys */, {
|
|
1539
|
+
await sleep(fetchKeysDelay);
|
|
1540
|
+
this.fireStepEnd("fetchKeys" /* FetchKeys */, {
|
|
1541
|
+
fheKeyFetchedFromCoFHE: false,
|
|
1542
|
+
crsFetchedFromCoFHE: false,
|
|
1543
|
+
isMocks: true,
|
|
1544
|
+
mockSleep: fetchKeysDelay
|
|
1545
|
+
});
|
|
1523
1546
|
this.fireStepStart("pack" /* Pack */);
|
|
1524
1547
|
await cofheMocksCheckEncryptableBits(this.inputItems);
|
|
1525
|
-
await sleep(
|
|
1526
|
-
this.fireStepEnd("pack" /* Pack
|
|
1548
|
+
await sleep(packDelay);
|
|
1549
|
+
this.fireStepEnd("pack" /* Pack */, { isMocks: true, mockSleep: packDelay });
|
|
1527
1550
|
this.fireStepStart("prove" /* Prove */);
|
|
1528
|
-
await sleep(
|
|
1529
|
-
this.fireStepEnd("prove" /* Prove
|
|
1551
|
+
await sleep(proveDelay);
|
|
1552
|
+
this.fireStepEnd("prove" /* Prove */, { isMocks: true, mockSleep: proveDelay });
|
|
1530
1553
|
this.fireStepStart("verify" /* Verify */);
|
|
1531
|
-
await sleep(
|
|
1554
|
+
await sleep(verifyDelay);
|
|
1532
1555
|
const signedResults = await cofheMocksZkVerifySign(
|
|
1533
1556
|
this.inputItems,
|
|
1534
1557
|
this.account,
|
|
@@ -1543,13 +1566,13 @@ var EncryptInputsBuilder = class extends BaseBuilder {
|
|
|
1543
1566
|
utype: this.inputItems[index].utype,
|
|
1544
1567
|
signature
|
|
1545
1568
|
}));
|
|
1546
|
-
this.fireStepEnd("verify" /* Verify
|
|
1569
|
+
this.fireStepEnd("verify" /* Verify */, { isMocks: true, mockSleep: verifyDelay });
|
|
1547
1570
|
return encryptedInputs;
|
|
1548
1571
|
}
|
|
1549
1572
|
/**
|
|
1550
1573
|
* In the production context, perform a true encryption with the CoFHE coprocessor.
|
|
1551
1574
|
*/
|
|
1552
|
-
async
|
|
1575
|
+
async productionExecute() {
|
|
1553
1576
|
this.assertAccount();
|
|
1554
1577
|
this.assertChainId();
|
|
1555
1578
|
this.fireStepStart("initTfhe" /* InitTfhe */);
|
|
@@ -1612,22 +1635,22 @@ var EncryptInputsBuilder = class extends BaseBuilder {
|
|
|
1612
1635
|
* const encrypted = await encryptInputs([Encryptable.uint128(10n)])
|
|
1613
1636
|
* .setAccount('0x123...890') // optional
|
|
1614
1637
|
* .setChainId(11155111) // optional
|
|
1615
|
-
* .
|
|
1638
|
+
* .execute(); // execute
|
|
1616
1639
|
* ```
|
|
1617
1640
|
*
|
|
1618
1641
|
* @returns The encrypted inputs.
|
|
1619
1642
|
*/
|
|
1620
|
-
async
|
|
1643
|
+
async execute() {
|
|
1621
1644
|
if (this.chainId === hardhat.id)
|
|
1622
|
-
return this.
|
|
1623
|
-
return this.
|
|
1645
|
+
return this.mocksExecute();
|
|
1646
|
+
return this.productionExecute();
|
|
1624
1647
|
}
|
|
1625
1648
|
};
|
|
1626
1649
|
var storeActivePermit = async (permit, publicClient, walletClient) => {
|
|
1627
1650
|
const chainId = await publicClient.getChainId();
|
|
1628
1651
|
const account = walletClient.account.address;
|
|
1629
1652
|
permitStore.setPermit(chainId, account, permit);
|
|
1630
|
-
permitStore.setActivePermitHash(chainId, account,
|
|
1653
|
+
permitStore.setActivePermitHash(chainId, account, permit.hash);
|
|
1631
1654
|
};
|
|
1632
1655
|
var createPermitWithSign = async (options, publicClient, walletClient, permitMethod) => {
|
|
1633
1656
|
const permit = await permitMethod(options, publicClient, walletClient);
|
|
@@ -1685,7 +1708,7 @@ var getOrCreateSharingPermit = async (publicClient, walletClient, options, chain
|
|
|
1685
1708
|
}
|
|
1686
1709
|
return createSharing(options, publicClient, walletClient);
|
|
1687
1710
|
};
|
|
1688
|
-
var removePermit = async (chainId, account, hash
|
|
1711
|
+
var removePermit = async (chainId, account, hash) => permitStore.removePermit(chainId, account, hash);
|
|
1689
1712
|
var removeActivePermit = async (chainId, account) => permitStore.removeActivePermitHash(chainId, account);
|
|
1690
1713
|
var permits = {
|
|
1691
1714
|
getSnapshot: permitStore.store.getState,
|
|
@@ -1725,8 +1748,8 @@ var convertViaUtype = (utype, value) => {
|
|
|
1725
1748
|
}
|
|
1726
1749
|
};
|
|
1727
1750
|
|
|
1728
|
-
// core/decrypt/
|
|
1729
|
-
var
|
|
1751
|
+
// core/decrypt/MockThresholdNetworkAbi.ts
|
|
1752
|
+
var MockThresholdNetworkAbi = [
|
|
1730
1753
|
{
|
|
1731
1754
|
type: "function",
|
|
1732
1755
|
name: "acl",
|
|
@@ -1773,11 +1796,7 @@ var MockQueryDecrypterAbi = [
|
|
|
1773
1796
|
{ name: "expiration", type: "uint64", internalType: "uint64" },
|
|
1774
1797
|
{ name: "recipient", type: "address", internalType: "address" },
|
|
1775
1798
|
{ name: "validatorId", type: "uint256", internalType: "uint256" },
|
|
1776
|
-
{
|
|
1777
|
-
name: "validatorContract",
|
|
1778
|
-
type: "address",
|
|
1779
|
-
internalType: "address"
|
|
1780
|
-
},
|
|
1799
|
+
{ name: "validatorContract", type: "address", internalType: "address" },
|
|
1781
1800
|
{ name: "sealingKey", type: "bytes32", internalType: "bytes32" },
|
|
1782
1801
|
{ name: "issuerSignature", type: "bytes", internalType: "bytes" },
|
|
1783
1802
|
{ name: "recipientSignature", type: "bytes", internalType: "bytes" }
|
|
@@ -1806,11 +1825,7 @@ var MockQueryDecrypterAbi = [
|
|
|
1806
1825
|
{ name: "expiration", type: "uint64", internalType: "uint64" },
|
|
1807
1826
|
{ name: "recipient", type: "address", internalType: "address" },
|
|
1808
1827
|
{ name: "validatorId", type: "uint256", internalType: "uint256" },
|
|
1809
|
-
{
|
|
1810
|
-
name: "validatorContract",
|
|
1811
|
-
type: "address",
|
|
1812
|
-
internalType: "address"
|
|
1813
|
-
},
|
|
1828
|
+
{ name: "validatorContract", type: "address", internalType: "address" },
|
|
1814
1829
|
{ name: "sealingKey", type: "bytes32", internalType: "bytes32" },
|
|
1815
1830
|
{ name: "issuerSignature", type: "bytes", internalType: "bytes" },
|
|
1816
1831
|
{ name: "recipientSignature", type: "bytes", internalType: "bytes" }
|
|
@@ -1834,13 +1849,6 @@ var MockQueryDecrypterAbi = [
|
|
|
1834
1849
|
outputs: [{ name: "", type: "bytes32", internalType: "bytes32" }],
|
|
1835
1850
|
stateMutability: "pure"
|
|
1836
1851
|
},
|
|
1837
|
-
{
|
|
1838
|
-
type: "function",
|
|
1839
|
-
name: "taskManager",
|
|
1840
|
-
inputs: [],
|
|
1841
|
-
outputs: [{ name: "", type: "address", internalType: "contract TaskManager" }],
|
|
1842
|
-
stateMutability: "view"
|
|
1843
|
-
},
|
|
1844
1852
|
{
|
|
1845
1853
|
type: "function",
|
|
1846
1854
|
name: "unseal",
|
|
@@ -1851,16 +1859,80 @@ var MockQueryDecrypterAbi = [
|
|
|
1851
1859
|
outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
|
|
1852
1860
|
stateMutability: "pure"
|
|
1853
1861
|
},
|
|
1854
|
-
{
|
|
1855
|
-
|
|
1856
|
-
|
|
1862
|
+
{
|
|
1863
|
+
type: "function",
|
|
1864
|
+
name: "mockAcl",
|
|
1865
|
+
inputs: [],
|
|
1866
|
+
outputs: [{ name: "", type: "address", internalType: "contract MockACL" }],
|
|
1867
|
+
stateMutability: "view"
|
|
1868
|
+
},
|
|
1869
|
+
{
|
|
1870
|
+
type: "function",
|
|
1871
|
+
name: "mockTaskManager",
|
|
1872
|
+
inputs: [],
|
|
1873
|
+
outputs: [{ name: "", type: "address", internalType: "contract MockTaskManager" }],
|
|
1874
|
+
stateMutability: "view"
|
|
1875
|
+
},
|
|
1876
|
+
{
|
|
1877
|
+
type: "function",
|
|
1878
|
+
name: "mockQueryDecrypt",
|
|
1879
|
+
inputs: [
|
|
1880
|
+
{ name: "ctHash", type: "uint256", internalType: "uint256" },
|
|
1881
|
+
{ name: "", type: "uint256", internalType: "uint256" },
|
|
1882
|
+
{ name: "issuer", type: "address", internalType: "address" }
|
|
1883
|
+
],
|
|
1884
|
+
outputs: [
|
|
1885
|
+
{ name: "allowed", type: "bool", internalType: "bool" },
|
|
1886
|
+
{ name: "error", type: "string", internalType: "string" },
|
|
1887
|
+
{ name: "", type: "uint256", internalType: "uint256" }
|
|
1888
|
+
],
|
|
1889
|
+
stateMutability: "view"
|
|
1890
|
+
},
|
|
1891
|
+
{
|
|
1892
|
+
type: "function",
|
|
1893
|
+
name: "decryptForTxWithPermit",
|
|
1894
|
+
inputs: [
|
|
1895
|
+
{ name: "ctHash", type: "uint256", internalType: "uint256" },
|
|
1896
|
+
{
|
|
1897
|
+
name: "permission",
|
|
1898
|
+
type: "tuple",
|
|
1899
|
+
internalType: "struct Permission",
|
|
1900
|
+
components: [
|
|
1901
|
+
{ name: "issuer", type: "address", internalType: "address" },
|
|
1902
|
+
{ name: "expiration", type: "uint64", internalType: "uint64" },
|
|
1903
|
+
{ name: "recipient", type: "address", internalType: "address" },
|
|
1904
|
+
{ name: "validatorId", type: "uint256", internalType: "uint256" },
|
|
1905
|
+
{ name: "validatorContract", type: "address", internalType: "address" },
|
|
1906
|
+
{ name: "sealingKey", type: "bytes32", internalType: "bytes32" },
|
|
1907
|
+
{ name: "issuerSignature", type: "bytes", internalType: "bytes" },
|
|
1908
|
+
{ name: "recipientSignature", type: "bytes", internalType: "bytes" }
|
|
1909
|
+
]
|
|
1910
|
+
}
|
|
1911
|
+
],
|
|
1912
|
+
outputs: [
|
|
1913
|
+
{ name: "allowed", type: "bool", internalType: "bool" },
|
|
1914
|
+
{ name: "error", type: "string", internalType: "string" },
|
|
1915
|
+
{ name: "decryptedValue", type: "uint256", internalType: "uint256" }
|
|
1916
|
+
],
|
|
1917
|
+
stateMutability: "view"
|
|
1918
|
+
},
|
|
1919
|
+
{
|
|
1920
|
+
type: "function",
|
|
1921
|
+
name: "decryptForTxWithoutPermit",
|
|
1922
|
+
inputs: [{ name: "ctHash", type: "uint256", internalType: "uint256" }],
|
|
1923
|
+
outputs: [
|
|
1924
|
+
{ name: "allowed", type: "bool", internalType: "bool" },
|
|
1925
|
+
{ name: "error", type: "string", internalType: "string" },
|
|
1926
|
+
{ name: "decryptedValue", type: "uint256", internalType: "uint256" }
|
|
1927
|
+
],
|
|
1928
|
+
stateMutability: "view"
|
|
1929
|
+
}
|
|
1857
1930
|
];
|
|
1858
1931
|
|
|
1859
|
-
// core/decrypt/
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
await sleep(mocksSealOutputDelay);
|
|
1932
|
+
// core/decrypt/cofheMocksDecryptForView.ts
|
|
1933
|
+
async function cofheMocksDecryptForView(ctHash, utype, permit, publicClient, mocksDecryptDelay) {
|
|
1934
|
+
if (mocksDecryptDelay > 0)
|
|
1935
|
+
await sleep(mocksDecryptDelay);
|
|
1864
1936
|
const permission = PermitUtils.getPermission(permit, true);
|
|
1865
1937
|
const permissionWithBigInts = {
|
|
1866
1938
|
...permission,
|
|
@@ -1868,19 +1940,19 @@ async function cofheMocksSealOutput(ctHash, utype, permit, publicClient, mocksSe
|
|
|
1868
1940
|
validatorId: BigInt(permission.validatorId)
|
|
1869
1941
|
};
|
|
1870
1942
|
const [allowed, error, result] = await publicClient.readContract({
|
|
1871
|
-
address:
|
|
1872
|
-
abi:
|
|
1943
|
+
address: MOCKS_THRESHOLD_NETWORK_ADDRESS,
|
|
1944
|
+
abi: MockThresholdNetworkAbi,
|
|
1873
1945
|
functionName: "querySealOutput",
|
|
1874
1946
|
args: [ctHash, BigInt(utype), permissionWithBigInts]
|
|
1875
1947
|
});
|
|
1876
1948
|
if (error != "") {
|
|
1877
|
-
throw new
|
|
1949
|
+
throw new CofheError({
|
|
1878
1950
|
code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
|
|
1879
1951
|
message: `mocks querySealOutput call failed: ${error}`
|
|
1880
1952
|
});
|
|
1881
1953
|
}
|
|
1882
1954
|
if (allowed == false) {
|
|
1883
|
-
throw new
|
|
1955
|
+
throw new CofheError({
|
|
1884
1956
|
code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
|
|
1885
1957
|
message: `mocks querySealOutput call failed: ACL Access Denied (NotAllowed)`
|
|
1886
1958
|
});
|
|
@@ -1899,7 +1971,7 @@ function numberArrayToUint8Array(arr) {
|
|
|
1899
1971
|
}
|
|
1900
1972
|
function convertSealedData(sealed) {
|
|
1901
1973
|
if (!sealed) {
|
|
1902
|
-
throw new
|
|
1974
|
+
throw new CofheError({
|
|
1903
1975
|
code: "SEAL_OUTPUT_RETURNED_NULL" /* SealOutputReturnedNull */,
|
|
1904
1976
|
message: "Sealed data is missing from completed response"
|
|
1905
1977
|
});
|
|
@@ -1926,7 +1998,7 @@ async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, per
|
|
|
1926
1998
|
body: JSON.stringify(body)
|
|
1927
1999
|
});
|
|
1928
2000
|
} catch (e) {
|
|
1929
|
-
throw new
|
|
2001
|
+
throw new CofheError({
|
|
1930
2002
|
code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
|
|
1931
2003
|
message: `sealOutput request failed`,
|
|
1932
2004
|
hint: "Ensure the threshold network URL is valid and reachable.",
|
|
@@ -1945,7 +2017,7 @@ async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, per
|
|
|
1945
2017
|
} catch {
|
|
1946
2018
|
errorMessage = response.statusText || errorMessage;
|
|
1947
2019
|
}
|
|
1948
|
-
throw new
|
|
2020
|
+
throw new CofheError({
|
|
1949
2021
|
code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
|
|
1950
2022
|
message: `sealOutput request failed: ${errorMessage}`,
|
|
1951
2023
|
hint: "Check the threshold network URL and request parameters.",
|
|
@@ -1961,7 +2033,7 @@ async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, per
|
|
|
1961
2033
|
try {
|
|
1962
2034
|
submitResponse = await response.json();
|
|
1963
2035
|
} catch (e) {
|
|
1964
|
-
throw new
|
|
2036
|
+
throw new CofheError({
|
|
1965
2037
|
code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
|
|
1966
2038
|
message: `Failed to parse sealOutput submit response`,
|
|
1967
2039
|
cause: e instanceof Error ? e : void 0,
|
|
@@ -1972,7 +2044,7 @@ async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, per
|
|
|
1972
2044
|
});
|
|
1973
2045
|
}
|
|
1974
2046
|
if (!submitResponse.request_id) {
|
|
1975
|
-
throw new
|
|
2047
|
+
throw new CofheError({
|
|
1976
2048
|
code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
|
|
1977
2049
|
message: `sealOutput submit response missing request_id`,
|
|
1978
2050
|
context: {
|
|
@@ -1989,7 +2061,7 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId) {
|
|
|
1989
2061
|
let completed = false;
|
|
1990
2062
|
while (!completed) {
|
|
1991
2063
|
if (Date.now() - startTime > POLL_TIMEOUT_MS) {
|
|
1992
|
-
throw new
|
|
2064
|
+
throw new CofheError({
|
|
1993
2065
|
code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
|
|
1994
2066
|
message: `sealOutput polling timed out after ${POLL_TIMEOUT_MS}ms`,
|
|
1995
2067
|
hint: "The request may still be processing. Try again later.",
|
|
@@ -2009,7 +2081,7 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId) {
|
|
|
2009
2081
|
}
|
|
2010
2082
|
});
|
|
2011
2083
|
} catch (e) {
|
|
2012
|
-
throw new
|
|
2084
|
+
throw new CofheError({
|
|
2013
2085
|
code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
|
|
2014
2086
|
message: `sealOutput status poll failed`,
|
|
2015
2087
|
hint: "Ensure the threshold network URL is valid and reachable.",
|
|
@@ -2021,7 +2093,7 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId) {
|
|
|
2021
2093
|
});
|
|
2022
2094
|
}
|
|
2023
2095
|
if (response.status === 404) {
|
|
2024
|
-
throw new
|
|
2096
|
+
throw new CofheError({
|
|
2025
2097
|
code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
|
|
2026
2098
|
message: `sealOutput request not found: ${requestId}`,
|
|
2027
2099
|
hint: "The request may have expired or been invalid.",
|
|
@@ -2039,7 +2111,7 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId) {
|
|
|
2039
2111
|
} catch {
|
|
2040
2112
|
errorMessage = response.statusText || errorMessage;
|
|
2041
2113
|
}
|
|
2042
|
-
throw new
|
|
2114
|
+
throw new CofheError({
|
|
2043
2115
|
code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
|
|
2044
2116
|
message: `sealOutput status poll failed: ${errorMessage}`,
|
|
2045
2117
|
context: {
|
|
@@ -2054,7 +2126,7 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId) {
|
|
|
2054
2126
|
try {
|
|
2055
2127
|
statusResponse = await response.json();
|
|
2056
2128
|
} catch (e) {
|
|
2057
|
-
throw new
|
|
2129
|
+
throw new CofheError({
|
|
2058
2130
|
code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
|
|
2059
2131
|
message: `Failed to parse sealOutput status response`,
|
|
2060
2132
|
cause: e instanceof Error ? e : void 0,
|
|
@@ -2067,7 +2139,7 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId) {
|
|
|
2067
2139
|
if (statusResponse.status === "COMPLETED") {
|
|
2068
2140
|
if (statusResponse.is_succeed === false) {
|
|
2069
2141
|
const errorMessage = statusResponse.error_message || "Unknown error";
|
|
2070
|
-
throw new
|
|
2142
|
+
throw new CofheError({
|
|
2071
2143
|
code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
|
|
2072
2144
|
message: `sealOutput request failed: ${errorMessage}`,
|
|
2073
2145
|
context: {
|
|
@@ -2078,7 +2150,7 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId) {
|
|
|
2078
2150
|
});
|
|
2079
2151
|
}
|
|
2080
2152
|
if (!statusResponse.sealed) {
|
|
2081
|
-
throw new
|
|
2153
|
+
throw new CofheError({
|
|
2082
2154
|
code: "SEAL_OUTPUT_RETURNED_NULL" /* SealOutputReturnedNull */,
|
|
2083
2155
|
message: `sealOutput request completed but returned no sealed data`,
|
|
2084
2156
|
context: {
|
|
@@ -2092,7 +2164,7 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId) {
|
|
|
2092
2164
|
}
|
|
2093
2165
|
await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS));
|
|
2094
2166
|
}
|
|
2095
|
-
throw new
|
|
2167
|
+
throw new CofheError({
|
|
2096
2168
|
code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
|
|
2097
2169
|
message: "Polling loop exited unexpectedly",
|
|
2098
2170
|
context: {
|
|
@@ -2105,9 +2177,99 @@ async function tnSealOutputV2(ctHash, chainId, permission, thresholdNetworkUrl)
|
|
|
2105
2177
|
const requestId = await submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, permission);
|
|
2106
2178
|
return await pollSealOutputStatus(thresholdNetworkUrl, requestId);
|
|
2107
2179
|
}
|
|
2180
|
+
async function cofheMocksDecryptForTx(ctHash, utype, permit, publicClient, mocksDecryptForTxDelay) {
|
|
2181
|
+
if (mocksDecryptForTxDelay > 0)
|
|
2182
|
+
await sleep(mocksDecryptForTxDelay);
|
|
2183
|
+
if (permit !== null) {
|
|
2184
|
+
let permission = PermitUtils.getPermission(permit, true);
|
|
2185
|
+
const permissionWithBigInts = {
|
|
2186
|
+
...permission,
|
|
2187
|
+
expiration: BigInt(permission.expiration),
|
|
2188
|
+
validatorId: BigInt(permission.validatorId)
|
|
2189
|
+
};
|
|
2190
|
+
const [allowed2, error2, result2] = await publicClient.readContract({
|
|
2191
|
+
address: MOCKS_THRESHOLD_NETWORK_ADDRESS,
|
|
2192
|
+
abi: MockThresholdNetworkAbi,
|
|
2193
|
+
functionName: "decryptForTxWithPermit",
|
|
2194
|
+
args: [ctHash, permissionWithBigInts]
|
|
2195
|
+
});
|
|
2196
|
+
if (error2 != "") {
|
|
2197
|
+
throw new CofheError({
|
|
2198
|
+
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
2199
|
+
message: `mocks decryptForTx call failed: ${error2}`
|
|
2200
|
+
});
|
|
2201
|
+
}
|
|
2202
|
+
if (allowed2 == false) {
|
|
2203
|
+
throw new CofheError({
|
|
2204
|
+
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
2205
|
+
message: `mocks decryptForTx call failed: ACL Access Denied (NotAllowed)`
|
|
2206
|
+
});
|
|
2207
|
+
}
|
|
2208
|
+
const chainId2 = await publicClient.getChainId();
|
|
2209
|
+
const ctHashBigInt2 = BigInt(ctHash);
|
|
2210
|
+
const resultBigInt2 = BigInt(result2);
|
|
2211
|
+
const encryptionType2 = Number((ctHashBigInt2 & 0x7fn << 8n) >> 8n);
|
|
2212
|
+
const ctHashBytes322 = pad(toHex(ctHashBigInt2), { size: 32 });
|
|
2213
|
+
const packed2 = encodePacked(
|
|
2214
|
+
["uint256", "uint32", "uint64", "bytes32"],
|
|
2215
|
+
[resultBigInt2, encryptionType2, BigInt(chainId2), ctHashBytes322]
|
|
2216
|
+
);
|
|
2217
|
+
const messageHash2 = keccak256(packed2);
|
|
2218
|
+
const signatureHex2 = await sign({
|
|
2219
|
+
hash: messageHash2,
|
|
2220
|
+
privateKey: MOCKS_DECRYPT_RESULT_SIGNER_PRIVATE_KEY,
|
|
2221
|
+
to: "hex"
|
|
2222
|
+
});
|
|
2223
|
+
const signature2 = signatureHex2.slice(2);
|
|
2224
|
+
return {
|
|
2225
|
+
ctHash,
|
|
2226
|
+
decryptedValue: BigInt(result2),
|
|
2227
|
+
signature: signature2
|
|
2228
|
+
};
|
|
2229
|
+
}
|
|
2230
|
+
const [allowed, error, result] = await publicClient.readContract({
|
|
2231
|
+
address: MOCKS_THRESHOLD_NETWORK_ADDRESS,
|
|
2232
|
+
abi: MockThresholdNetworkAbi,
|
|
2233
|
+
functionName: "decryptForTxWithoutPermit",
|
|
2234
|
+
args: [ctHash]
|
|
2235
|
+
});
|
|
2236
|
+
if (error != "") {
|
|
2237
|
+
throw new CofheError({
|
|
2238
|
+
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
2239
|
+
message: `mocks decryptForTx call failed: ${error}`
|
|
2240
|
+
});
|
|
2241
|
+
}
|
|
2242
|
+
if (allowed == false) {
|
|
2243
|
+
throw new CofheError({
|
|
2244
|
+
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
2245
|
+
message: `mocks decryptForTx call failed: ACL Access Denied (NotAllowed)`
|
|
2246
|
+
});
|
|
2247
|
+
}
|
|
2248
|
+
const chainId = await publicClient.getChainId();
|
|
2249
|
+
const ctHashBigInt = BigInt(ctHash);
|
|
2250
|
+
const resultBigInt = BigInt(result);
|
|
2251
|
+
const encryptionType = Number((ctHashBigInt & 0x7fn << 8n) >> 8n);
|
|
2252
|
+
const ctHashBytes32 = pad(toHex(ctHashBigInt), { size: 32 });
|
|
2253
|
+
const packed = encodePacked(
|
|
2254
|
+
["uint256", "uint32", "uint64", "bytes32"],
|
|
2255
|
+
[resultBigInt, encryptionType, BigInt(chainId), ctHashBytes32]
|
|
2256
|
+
);
|
|
2257
|
+
const messageHash = keccak256(packed);
|
|
2258
|
+
const signatureHex = await sign({
|
|
2259
|
+
hash: messageHash,
|
|
2260
|
+
privateKey: MOCKS_DECRYPT_RESULT_SIGNER_PRIVATE_KEY,
|
|
2261
|
+
to: "hex"
|
|
2262
|
+
});
|
|
2263
|
+
const signature = signatureHex.slice(2);
|
|
2264
|
+
return {
|
|
2265
|
+
ctHash,
|
|
2266
|
+
decryptedValue: BigInt(result),
|
|
2267
|
+
signature
|
|
2268
|
+
};
|
|
2269
|
+
}
|
|
2108
2270
|
|
|
2109
|
-
// core/decrypt/
|
|
2110
|
-
var
|
|
2271
|
+
// core/decrypt/decryptForViewBuilder.ts
|
|
2272
|
+
var DecryptForViewBuilder = class extends BaseBuilder {
|
|
2111
2273
|
ctHash;
|
|
2112
2274
|
utype;
|
|
2113
2275
|
permitHash;
|
|
@@ -2133,12 +2295,12 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
|
|
|
2133
2295
|
*
|
|
2134
2296
|
* Example:
|
|
2135
2297
|
* ```typescript
|
|
2136
|
-
* const unsealed = await
|
|
2298
|
+
* const unsealed = await client.decryptForView(ctHash, utype)
|
|
2137
2299
|
* .setChainId(11155111)
|
|
2138
|
-
* .
|
|
2300
|
+
* .execute();
|
|
2139
2301
|
* ```
|
|
2140
2302
|
*
|
|
2141
|
-
* @returns The chainable
|
|
2303
|
+
* @returns The chainable DecryptForViewBuilder instance.
|
|
2142
2304
|
*/
|
|
2143
2305
|
setChainId(chainId) {
|
|
2144
2306
|
this.chainId = chainId;
|
|
@@ -2154,12 +2316,12 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
|
|
|
2154
2316
|
*
|
|
2155
2317
|
* Example:
|
|
2156
2318
|
* ```typescript
|
|
2157
|
-
* const unsealed = await
|
|
2319
|
+
* const unsealed = await client.decryptForView(ctHash, utype)
|
|
2158
2320
|
* .setAccount('0x1234567890123456789012345678901234567890')
|
|
2159
|
-
* .
|
|
2321
|
+
* .execute();
|
|
2160
2322
|
* ```
|
|
2161
2323
|
*
|
|
2162
|
-
* @returns The chainable
|
|
2324
|
+
* @returns The chainable DecryptForViewBuilder instance.
|
|
2163
2325
|
*/
|
|
2164
2326
|
setAccount(account) {
|
|
2165
2327
|
this.account = account;
|
|
@@ -2168,6 +2330,19 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
|
|
|
2168
2330
|
getAccount() {
|
|
2169
2331
|
return this.account;
|
|
2170
2332
|
}
|
|
2333
|
+
withPermit(permitOrPermitHash) {
|
|
2334
|
+
if (typeof permitOrPermitHash === "string") {
|
|
2335
|
+
this.permitHash = permitOrPermitHash;
|
|
2336
|
+
this.permit = void 0;
|
|
2337
|
+
} else if (permitOrPermitHash === void 0) {
|
|
2338
|
+
this.permitHash = void 0;
|
|
2339
|
+
this.permit = void 0;
|
|
2340
|
+
} else {
|
|
2341
|
+
this.permit = permitOrPermitHash;
|
|
2342
|
+
this.permitHash = void 0;
|
|
2343
|
+
}
|
|
2344
|
+
return this;
|
|
2345
|
+
}
|
|
2171
2346
|
/**
|
|
2172
2347
|
* @param permitHash - Permit hash to decrypt values from. Used to fetch the correct permit.
|
|
2173
2348
|
*
|
|
@@ -2176,16 +2351,16 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
|
|
|
2176
2351
|
*
|
|
2177
2352
|
* Example:
|
|
2178
2353
|
* ```typescript
|
|
2179
|
-
* const unsealed = await
|
|
2354
|
+
* const unsealed = await client.decryptForView(ctHash, utype)
|
|
2180
2355
|
* .setPermitHash('0x1234567890123456789012345678901234567890')
|
|
2181
|
-
* .
|
|
2356
|
+
* .execute();
|
|
2182
2357
|
* ```
|
|
2183
2358
|
*
|
|
2184
|
-
* @returns The chainable
|
|
2359
|
+
* @returns The chainable DecryptForViewBuilder instance.
|
|
2185
2360
|
*/
|
|
2361
|
+
/** @deprecated Use `withPermit(permitHash)` instead. */
|
|
2186
2362
|
setPermitHash(permitHash) {
|
|
2187
|
-
this.permitHash
|
|
2188
|
-
return this;
|
|
2363
|
+
return this.withPermit(permitHash);
|
|
2189
2364
|
}
|
|
2190
2365
|
getPermitHash() {
|
|
2191
2366
|
return this.permitHash;
|
|
@@ -2197,16 +2372,16 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
|
|
|
2197
2372
|
*
|
|
2198
2373
|
* Example:
|
|
2199
2374
|
* ```typescript
|
|
2200
|
-
* const unsealed = await
|
|
2375
|
+
* const unsealed = await client.decryptForView(ctHash, utype)
|
|
2201
2376
|
* .setPermit(permit)
|
|
2202
|
-
* .
|
|
2377
|
+
* .execute();
|
|
2203
2378
|
* ```
|
|
2204
2379
|
*
|
|
2205
|
-
* @returns The chainable
|
|
2380
|
+
* @returns The chainable DecryptForViewBuilder instance.
|
|
2206
2381
|
*/
|
|
2382
|
+
/** @deprecated Use `withPermit(permit)` instead. */
|
|
2207
2383
|
setPermit(permit) {
|
|
2208
|
-
this.permit
|
|
2209
|
-
return this;
|
|
2384
|
+
return this.withPermit(permit);
|
|
2210
2385
|
}
|
|
2211
2386
|
getPermit() {
|
|
2212
2387
|
return this.permit;
|
|
@@ -2217,7 +2392,7 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
|
|
|
2217
2392
|
}
|
|
2218
2393
|
validateUtypeOrThrow() {
|
|
2219
2394
|
if (!isValidUtype(this.utype))
|
|
2220
|
-
throw new
|
|
2395
|
+
throw new CofheError({
|
|
2221
2396
|
code: "INVALID_UTYPE" /* InvalidUtype */,
|
|
2222
2397
|
message: `Invalid utype to decrypt to`,
|
|
2223
2398
|
context: {
|
|
@@ -2233,7 +2408,7 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
|
|
|
2233
2408
|
if (this.permitHash) {
|
|
2234
2409
|
const permit2 = await permits.getPermit(this.chainId, this.account, this.permitHash);
|
|
2235
2410
|
if (!permit2) {
|
|
2236
|
-
throw new
|
|
2411
|
+
throw new CofheError({
|
|
2237
2412
|
code: "PERMIT_NOT_FOUND" /* PermitNotFound */,
|
|
2238
2413
|
message: `Permit with hash <${this.permitHash}> not found for account <${this.account}> and chainId <${this.chainId}>`,
|
|
2239
2414
|
hint: "Ensure the permit exists and is valid.",
|
|
@@ -2248,7 +2423,7 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
|
|
|
2248
2423
|
}
|
|
2249
2424
|
const permit = await permits.getActivePermit(this.chainId, this.account);
|
|
2250
2425
|
if (!permit) {
|
|
2251
|
-
throw new
|
|
2426
|
+
throw new CofheError({
|
|
2252
2427
|
code: "PERMIT_NOT_FOUND" /* PermitNotFound */,
|
|
2253
2428
|
message: `Active permit not found for chainId <${this.chainId}> and account <${this.account}>`,
|
|
2254
2429
|
hint: "Ensure a permit exists for this account on this chain.",
|
|
@@ -2265,8 +2440,8 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
|
|
|
2265
2440
|
*/
|
|
2266
2441
|
async mocksSealOutput(permit) {
|
|
2267
2442
|
this.assertPublicClient();
|
|
2268
|
-
const
|
|
2269
|
-
return
|
|
2443
|
+
const mocksDecryptDelay = this.config.mocks.decryptDelay;
|
|
2444
|
+
return cofheMocksDecryptForView(this.ctHash, this.utype, permit, this.publicClient, mocksDecryptDelay);
|
|
2270
2445
|
}
|
|
2271
2446
|
/**
|
|
2272
2447
|
* In the production context, perform a true decryption with the CoFHE coprocessor.
|
|
@@ -2291,15 +2466,16 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
|
|
|
2291
2466
|
*
|
|
2292
2467
|
* Example:
|
|
2293
2468
|
* ```typescript
|
|
2294
|
-
* const unsealed = await
|
|
2469
|
+
* const unsealed = await client.decryptForView(ctHash, utype)
|
|
2295
2470
|
* .setChainId(11155111) // optional
|
|
2296
2471
|
* .setAccount('0x123...890') // optional
|
|
2297
|
-
* .
|
|
2472
|
+
* .withPermit() // optional
|
|
2473
|
+
* .execute(); // execute
|
|
2298
2474
|
* ```
|
|
2299
2475
|
*
|
|
2300
2476
|
* @returns The unsealed item.
|
|
2301
2477
|
*/
|
|
2302
|
-
async
|
|
2478
|
+
async execute() {
|
|
2303
2479
|
this.validateUtypeOrThrow();
|
|
2304
2480
|
const permit = await this.getResolvedPermit();
|
|
2305
2481
|
PermitUtils.validate(permit);
|
|
@@ -2315,6 +2491,394 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
|
|
|
2315
2491
|
}
|
|
2316
2492
|
};
|
|
2317
2493
|
|
|
2494
|
+
// core/decrypt/tnDecrypt.ts
|
|
2495
|
+
function normalizeSignature(signature) {
|
|
2496
|
+
if (typeof signature !== "string") {
|
|
2497
|
+
throw new CofheError({
|
|
2498
|
+
code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
|
|
2499
|
+
message: "decrypt response missing signature",
|
|
2500
|
+
context: {
|
|
2501
|
+
signature
|
|
2502
|
+
}
|
|
2503
|
+
});
|
|
2504
|
+
}
|
|
2505
|
+
const trimmed = signature.trim();
|
|
2506
|
+
if (trimmed.length === 0) {
|
|
2507
|
+
throw new CofheError({
|
|
2508
|
+
code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
|
|
2509
|
+
message: "decrypt response returned empty signature"
|
|
2510
|
+
});
|
|
2511
|
+
}
|
|
2512
|
+
return trimmed.startsWith("0x") ? trimmed.slice(2) : trimmed;
|
|
2513
|
+
}
|
|
2514
|
+
function parseDecryptedBytesToBigInt(decrypted) {
|
|
2515
|
+
if (!Array.isArray(decrypted)) {
|
|
2516
|
+
throw new CofheError({
|
|
2517
|
+
code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
|
|
2518
|
+
message: "decrypt response field <decrypted> must be a byte array",
|
|
2519
|
+
context: {
|
|
2520
|
+
decrypted
|
|
2521
|
+
}
|
|
2522
|
+
});
|
|
2523
|
+
}
|
|
2524
|
+
if (decrypted.length === 0) {
|
|
2525
|
+
throw new CofheError({
|
|
2526
|
+
code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
|
|
2527
|
+
message: "decrypt response field <decrypted> was an empty byte array",
|
|
2528
|
+
context: {
|
|
2529
|
+
decrypted
|
|
2530
|
+
}
|
|
2531
|
+
});
|
|
2532
|
+
}
|
|
2533
|
+
let hex = "";
|
|
2534
|
+
for (const b of decrypted) {
|
|
2535
|
+
if (typeof b !== "number" || !Number.isInteger(b) || b < 0 || b > 255) {
|
|
2536
|
+
throw new CofheError({
|
|
2537
|
+
code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
|
|
2538
|
+
message: "decrypt response field <decrypted> contained a non-byte value",
|
|
2539
|
+
context: {
|
|
2540
|
+
badElement: b,
|
|
2541
|
+
decrypted
|
|
2542
|
+
}
|
|
2543
|
+
});
|
|
2544
|
+
}
|
|
2545
|
+
hex += b.toString(16).padStart(2, "0");
|
|
2546
|
+
}
|
|
2547
|
+
return BigInt(`0x${hex}`);
|
|
2548
|
+
}
|
|
2549
|
+
function assertTnDecryptResponse(value) {
|
|
2550
|
+
if (value == null || typeof value !== "object") {
|
|
2551
|
+
throw new CofheError({
|
|
2552
|
+
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
2553
|
+
message: "decrypt response must be a JSON object",
|
|
2554
|
+
context: {
|
|
2555
|
+
value
|
|
2556
|
+
}
|
|
2557
|
+
});
|
|
2558
|
+
}
|
|
2559
|
+
const v = value;
|
|
2560
|
+
const decrypted = v.decrypted;
|
|
2561
|
+
const signature = v.signature;
|
|
2562
|
+
const encryptionType = v.encryption_type;
|
|
2563
|
+
const errorMessage = v.error_message;
|
|
2564
|
+
if (!Array.isArray(decrypted)) {
|
|
2565
|
+
throw new CofheError({
|
|
2566
|
+
code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
|
|
2567
|
+
message: "decrypt response missing <decrypted> byte array",
|
|
2568
|
+
context: { decryptResponse: value }
|
|
2569
|
+
});
|
|
2570
|
+
}
|
|
2571
|
+
if (typeof signature !== "string") {
|
|
2572
|
+
throw new CofheError({
|
|
2573
|
+
code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
|
|
2574
|
+
message: "decrypt response missing <signature> string",
|
|
2575
|
+
context: { decryptResponse: value }
|
|
2576
|
+
});
|
|
2577
|
+
}
|
|
2578
|
+
if (typeof encryptionType !== "number") {
|
|
2579
|
+
throw new CofheError({
|
|
2580
|
+
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
2581
|
+
message: "decrypt response missing <encryption_type> number",
|
|
2582
|
+
context: { decryptResponse: value }
|
|
2583
|
+
});
|
|
2584
|
+
}
|
|
2585
|
+
if (!(typeof errorMessage === "string" || errorMessage === null)) {
|
|
2586
|
+
throw new CofheError({
|
|
2587
|
+
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
2588
|
+
message: "decrypt response field <error_message> must be string or null",
|
|
2589
|
+
context: { decryptResponse: value }
|
|
2590
|
+
});
|
|
2591
|
+
}
|
|
2592
|
+
return {
|
|
2593
|
+
decrypted,
|
|
2594
|
+
signature,
|
|
2595
|
+
encryption_type: encryptionType,
|
|
2596
|
+
error_message: errorMessage
|
|
2597
|
+
};
|
|
2598
|
+
}
|
|
2599
|
+
async function tnDecrypt(ctHash, chainId, permission, thresholdNetworkUrl) {
|
|
2600
|
+
const body = {
|
|
2601
|
+
ct_tempkey: ctHash.toString(16).padStart(64, "0"),
|
|
2602
|
+
host_chain_id: chainId
|
|
2603
|
+
};
|
|
2604
|
+
if (permission) {
|
|
2605
|
+
body.permit = permission;
|
|
2606
|
+
}
|
|
2607
|
+
let response;
|
|
2608
|
+
try {
|
|
2609
|
+
response = await fetch(`${thresholdNetworkUrl}/decrypt`, {
|
|
2610
|
+
method: "POST",
|
|
2611
|
+
headers: {
|
|
2612
|
+
"Content-Type": "application/json"
|
|
2613
|
+
},
|
|
2614
|
+
body: JSON.stringify(body)
|
|
2615
|
+
});
|
|
2616
|
+
} catch (e) {
|
|
2617
|
+
throw new CofheError({
|
|
2618
|
+
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
2619
|
+
message: `decrypt request failed`,
|
|
2620
|
+
hint: "Ensure the threshold network URL is valid and reachable.",
|
|
2621
|
+
cause: e instanceof Error ? e : void 0,
|
|
2622
|
+
context: {
|
|
2623
|
+
thresholdNetworkUrl,
|
|
2624
|
+
body
|
|
2625
|
+
}
|
|
2626
|
+
});
|
|
2627
|
+
}
|
|
2628
|
+
const responseText = await response.text();
|
|
2629
|
+
if (!response.ok) {
|
|
2630
|
+
let errorMessage = response.statusText || `HTTP ${response.status}`;
|
|
2631
|
+
try {
|
|
2632
|
+
const errorBody = JSON.parse(responseText);
|
|
2633
|
+
const maybeMessage = errorBody.error_message || errorBody.message;
|
|
2634
|
+
if (typeof maybeMessage === "string" && maybeMessage.length > 0)
|
|
2635
|
+
errorMessage = maybeMessage;
|
|
2636
|
+
} catch {
|
|
2637
|
+
const trimmed = responseText.trim();
|
|
2638
|
+
if (trimmed.length > 0)
|
|
2639
|
+
errorMessage = trimmed;
|
|
2640
|
+
}
|
|
2641
|
+
throw new CofheError({
|
|
2642
|
+
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
2643
|
+
message: `decrypt request failed: ${errorMessage}`,
|
|
2644
|
+
hint: "Check the threshold network URL and request parameters.",
|
|
2645
|
+
context: {
|
|
2646
|
+
thresholdNetworkUrl,
|
|
2647
|
+
status: response.status,
|
|
2648
|
+
statusText: response.statusText,
|
|
2649
|
+
body,
|
|
2650
|
+
responseText
|
|
2651
|
+
}
|
|
2652
|
+
});
|
|
2653
|
+
}
|
|
2654
|
+
let rawJson;
|
|
2655
|
+
try {
|
|
2656
|
+
rawJson = JSON.parse(responseText);
|
|
2657
|
+
} catch (e) {
|
|
2658
|
+
throw new CofheError({
|
|
2659
|
+
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
2660
|
+
message: `Failed to parse decrypt response`,
|
|
2661
|
+
cause: e instanceof Error ? e : void 0,
|
|
2662
|
+
context: {
|
|
2663
|
+
thresholdNetworkUrl,
|
|
2664
|
+
body,
|
|
2665
|
+
responseText
|
|
2666
|
+
}
|
|
2667
|
+
});
|
|
2668
|
+
}
|
|
2669
|
+
const decryptResponse = assertTnDecryptResponse(rawJson);
|
|
2670
|
+
if (decryptResponse.error_message) {
|
|
2671
|
+
throw new CofheError({
|
|
2672
|
+
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
2673
|
+
message: `decrypt request failed: ${decryptResponse.error_message}`,
|
|
2674
|
+
context: {
|
|
2675
|
+
thresholdNetworkUrl,
|
|
2676
|
+
body,
|
|
2677
|
+
decryptResponse
|
|
2678
|
+
}
|
|
2679
|
+
});
|
|
2680
|
+
}
|
|
2681
|
+
const decryptedValue = parseDecryptedBytesToBigInt(decryptResponse.decrypted);
|
|
2682
|
+
const signature = normalizeSignature(decryptResponse.signature);
|
|
2683
|
+
return { decryptedValue, signature };
|
|
2684
|
+
}
|
|
2685
|
+
|
|
2686
|
+
// core/decrypt/decryptForTxBuilder.ts
|
|
2687
|
+
var DecryptForTxBuilder = class extends BaseBuilder {
|
|
2688
|
+
ctHash;
|
|
2689
|
+
permitHash;
|
|
2690
|
+
permit;
|
|
2691
|
+
permitSelection = "unset";
|
|
2692
|
+
constructor(params) {
|
|
2693
|
+
super({
|
|
2694
|
+
config: params.config,
|
|
2695
|
+
publicClient: params.publicClient,
|
|
2696
|
+
walletClient: params.walletClient,
|
|
2697
|
+
chainId: params.chainId,
|
|
2698
|
+
account: params.account,
|
|
2699
|
+
requireConnected: params.requireConnected
|
|
2700
|
+
});
|
|
2701
|
+
this.ctHash = params.ctHash;
|
|
2702
|
+
}
|
|
2703
|
+
setChainId(chainId) {
|
|
2704
|
+
this.chainId = chainId;
|
|
2705
|
+
return this;
|
|
2706
|
+
}
|
|
2707
|
+
getChainId() {
|
|
2708
|
+
return this.chainId;
|
|
2709
|
+
}
|
|
2710
|
+
setAccount(account) {
|
|
2711
|
+
this.account = account;
|
|
2712
|
+
return this;
|
|
2713
|
+
}
|
|
2714
|
+
getAccount() {
|
|
2715
|
+
return this.account;
|
|
2716
|
+
}
|
|
2717
|
+
withPermit(permitOrPermitHash) {
|
|
2718
|
+
if (this.permitSelection === "with-permit") {
|
|
2719
|
+
throw new CofheError({
|
|
2720
|
+
code: "INTERNAL_ERROR" /* InternalError */,
|
|
2721
|
+
message: "decryptForTx: withPermit() can only be selected once.",
|
|
2722
|
+
hint: "Choose the permit mode once. If you need a different permit, start a new decryptForTx() builder chain."
|
|
2723
|
+
});
|
|
2724
|
+
}
|
|
2725
|
+
if (this.permitSelection === "without-permit") {
|
|
2726
|
+
throw new CofheError({
|
|
2727
|
+
code: "INTERNAL_ERROR" /* InternalError */,
|
|
2728
|
+
message: "decryptForTx: cannot call withPermit() after withoutPermit() has been selected.",
|
|
2729
|
+
hint: "Choose exactly one permit mode: either call .withPermit(...) or .withoutPermit(), but not both."
|
|
2730
|
+
});
|
|
2731
|
+
}
|
|
2732
|
+
this.permitSelection = "with-permit";
|
|
2733
|
+
if (typeof permitOrPermitHash === "string") {
|
|
2734
|
+
this.permitHash = permitOrPermitHash;
|
|
2735
|
+
this.permit = void 0;
|
|
2736
|
+
} else if (permitOrPermitHash === void 0) {
|
|
2737
|
+
this.permitHash = void 0;
|
|
2738
|
+
this.permit = void 0;
|
|
2739
|
+
} else {
|
|
2740
|
+
this.permit = permitOrPermitHash;
|
|
2741
|
+
this.permitHash = void 0;
|
|
2742
|
+
}
|
|
2743
|
+
return this;
|
|
2744
|
+
}
|
|
2745
|
+
/**
|
|
2746
|
+
* Select "no permit" mode.
|
|
2747
|
+
*
|
|
2748
|
+
* This uses global allowance (no permit required) and sends an empty permission payload to `/decrypt`.
|
|
2749
|
+
*/
|
|
2750
|
+
withoutPermit() {
|
|
2751
|
+
if (this.permitSelection === "without-permit") {
|
|
2752
|
+
throw new CofheError({
|
|
2753
|
+
code: "INTERNAL_ERROR" /* InternalError */,
|
|
2754
|
+
message: "decryptForTx: withoutPermit() can only be selected once.",
|
|
2755
|
+
hint: "Choose the permit mode once. If you need a different mode, start a new decryptForTx() builder chain."
|
|
2756
|
+
});
|
|
2757
|
+
}
|
|
2758
|
+
if (this.permitSelection === "with-permit") {
|
|
2759
|
+
throw new CofheError({
|
|
2760
|
+
code: "INTERNAL_ERROR" /* InternalError */,
|
|
2761
|
+
message: "decryptForTx: cannot call withoutPermit() after withPermit() has been selected.",
|
|
2762
|
+
hint: "Choose exactly one permit mode: either call .withPermit(...) or .withoutPermit(), but not both."
|
|
2763
|
+
});
|
|
2764
|
+
}
|
|
2765
|
+
this.permitSelection = "without-permit";
|
|
2766
|
+
this.permitHash = void 0;
|
|
2767
|
+
this.permit = void 0;
|
|
2768
|
+
return this;
|
|
2769
|
+
}
|
|
2770
|
+
getPermit() {
|
|
2771
|
+
return this.permit;
|
|
2772
|
+
}
|
|
2773
|
+
getPermitHash() {
|
|
2774
|
+
return this.permitHash;
|
|
2775
|
+
}
|
|
2776
|
+
async getThresholdNetworkUrl() {
|
|
2777
|
+
this.assertChainId();
|
|
2778
|
+
return getThresholdNetworkUrlOrThrow(this.config, this.chainId);
|
|
2779
|
+
}
|
|
2780
|
+
async getResolvedPermit() {
|
|
2781
|
+
if (this.permitSelection === "unset") {
|
|
2782
|
+
throw new CofheError({
|
|
2783
|
+
code: "INTERNAL_ERROR" /* InternalError */,
|
|
2784
|
+
message: "decryptForTx: missing permit selection; call withPermit(...) or withoutPermit() before execute().",
|
|
2785
|
+
hint: "Call .withPermit() to use the active permit, or .withoutPermit() for global allowance."
|
|
2786
|
+
});
|
|
2787
|
+
}
|
|
2788
|
+
if (this.permitSelection === "without-permit") {
|
|
2789
|
+
return null;
|
|
2790
|
+
}
|
|
2791
|
+
if (this.permit)
|
|
2792
|
+
return this.permit;
|
|
2793
|
+
this.assertChainId();
|
|
2794
|
+
this.assertAccount();
|
|
2795
|
+
if (this.permitHash) {
|
|
2796
|
+
const permit2 = await permits.getPermit(this.chainId, this.account, this.permitHash);
|
|
2797
|
+
if (!permit2) {
|
|
2798
|
+
throw new CofheError({
|
|
2799
|
+
code: "PERMIT_NOT_FOUND" /* PermitNotFound */,
|
|
2800
|
+
message: `Permit with hash <${this.permitHash}> not found for account <${this.account}> and chainId <${this.chainId}>`,
|
|
2801
|
+
hint: "Ensure the permit exists and is valid.",
|
|
2802
|
+
context: {
|
|
2803
|
+
chainId: this.chainId,
|
|
2804
|
+
account: this.account,
|
|
2805
|
+
permitHash: this.permitHash
|
|
2806
|
+
}
|
|
2807
|
+
});
|
|
2808
|
+
}
|
|
2809
|
+
return permit2;
|
|
2810
|
+
}
|
|
2811
|
+
const permit = await permits.getActivePermit(this.chainId, this.account);
|
|
2812
|
+
if (!permit) {
|
|
2813
|
+
throw new CofheError({
|
|
2814
|
+
code: "PERMIT_NOT_FOUND" /* PermitNotFound */,
|
|
2815
|
+
message: `Active permit not found for chainId <${this.chainId}> and account <${this.account}>`,
|
|
2816
|
+
hint: "Create a permit (e.g. client.permits.createSelf(...)) and/or set it active (client.permits.selectActivePermit(hash)).",
|
|
2817
|
+
context: {
|
|
2818
|
+
chainId: this.chainId,
|
|
2819
|
+
account: this.account
|
|
2820
|
+
}
|
|
2821
|
+
});
|
|
2822
|
+
}
|
|
2823
|
+
return permit;
|
|
2824
|
+
}
|
|
2825
|
+
/**
|
|
2826
|
+
* On hardhat, interact with MockThresholdNetwork contract
|
|
2827
|
+
*/
|
|
2828
|
+
async mocksDecryptForTx(permit) {
|
|
2829
|
+
this.assertPublicClient();
|
|
2830
|
+
const delay = this.config.mocks.decryptDelay;
|
|
2831
|
+
const result = await cofheMocksDecryptForTx(this.ctHash, 0, permit, this.publicClient, delay);
|
|
2832
|
+
return result;
|
|
2833
|
+
}
|
|
2834
|
+
/**
|
|
2835
|
+
* In the production context, perform a true decryption with the CoFHE coprocessor.
|
|
2836
|
+
*/
|
|
2837
|
+
async productionDecryptForTx(permit) {
|
|
2838
|
+
this.assertChainId();
|
|
2839
|
+
this.assertPublicClient();
|
|
2840
|
+
const thresholdNetworkUrl = await this.getThresholdNetworkUrl();
|
|
2841
|
+
const permission = permit ? PermitUtils.getPermission(permit, true) : null;
|
|
2842
|
+
const { decryptedValue, signature } = await tnDecrypt(this.ctHash, this.chainId, permission, thresholdNetworkUrl);
|
|
2843
|
+
return {
|
|
2844
|
+
ctHash: this.ctHash,
|
|
2845
|
+
decryptedValue,
|
|
2846
|
+
signature
|
|
2847
|
+
};
|
|
2848
|
+
}
|
|
2849
|
+
/**
|
|
2850
|
+
* Final step of the decryptForTx process. MUST BE CALLED LAST IN THE CHAIN.
|
|
2851
|
+
*
|
|
2852
|
+
* You must explicitly choose one permit mode before calling `execute()`:
|
|
2853
|
+
* - `withPermit(permit)` / `withPermit(permitHash)` / `withPermit()` (active permit)
|
|
2854
|
+
* - `withoutPermit()` (global allowance)
|
|
2855
|
+
*/
|
|
2856
|
+
async execute() {
|
|
2857
|
+
const permit = await this.getResolvedPermit();
|
|
2858
|
+
if (permit !== null) {
|
|
2859
|
+
PermitUtils.validate(permit);
|
|
2860
|
+
PermitUtils.isValid(permit);
|
|
2861
|
+
const chainId = permit._signedDomain.chainId;
|
|
2862
|
+
if (chainId === hardhat$1.id) {
|
|
2863
|
+
return await this.mocksDecryptForTx(permit);
|
|
2864
|
+
} else {
|
|
2865
|
+
return await this.productionDecryptForTx(permit);
|
|
2866
|
+
}
|
|
2867
|
+
} else {
|
|
2868
|
+
if (!this.chainId) {
|
|
2869
|
+
this.assertPublicClient();
|
|
2870
|
+
this.chainId = await getPublicClientChainID(this.publicClient);
|
|
2871
|
+
}
|
|
2872
|
+
this.assertChainId();
|
|
2873
|
+
if (this.chainId === hardhat$1.id) {
|
|
2874
|
+
return await this.mocksDecryptForTx(null);
|
|
2875
|
+
} else {
|
|
2876
|
+
return await this.productionDecryptForTx(null);
|
|
2877
|
+
}
|
|
2878
|
+
}
|
|
2879
|
+
}
|
|
2880
|
+
};
|
|
2881
|
+
|
|
2318
2882
|
// core/client.ts
|
|
2319
2883
|
var InitialConnectStore = {
|
|
2320
2884
|
connected: false,
|
|
@@ -2325,9 +2889,10 @@ var InitialConnectStore = {
|
|
|
2325
2889
|
publicClient: void 0,
|
|
2326
2890
|
walletClient: void 0
|
|
2327
2891
|
};
|
|
2328
|
-
function
|
|
2892
|
+
function createCofheClientBase(opts) {
|
|
2329
2893
|
const keysStorage = createKeysStore(opts.config.fheKeyStorage);
|
|
2330
2894
|
const connectStore = createStore(() => InitialConnectStore);
|
|
2895
|
+
let connectAttemptId = 0;
|
|
2331
2896
|
const updateConnectState = (partial) => {
|
|
2332
2897
|
connectStore.setState((state) => ({ ...state, ...partial }));
|
|
2333
2898
|
};
|
|
@@ -2335,7 +2900,7 @@ function createCofhesdkClientBase(opts) {
|
|
|
2335
2900
|
const state = connectStore.getState();
|
|
2336
2901
|
const notConnected = !state.connected || !state.account || !state.chainId || !state.publicClient || !state.walletClient;
|
|
2337
2902
|
if (notConnected) {
|
|
2338
|
-
throw new
|
|
2903
|
+
throw new CofheError({
|
|
2339
2904
|
code: "NOT_CONNECTED" /* NotConnected */,
|
|
2340
2905
|
message: "Client must be connected, account and chainId must be initialized",
|
|
2341
2906
|
hint: "Ensure client.connect() has been called and awaited.",
|
|
@@ -2353,6 +2918,8 @@ function createCofhesdkClientBase(opts) {
|
|
|
2353
2918
|
const state = connectStore.getState();
|
|
2354
2919
|
if (state.connected && state.publicClient === publicClient && state.walletClient === walletClient)
|
|
2355
2920
|
return;
|
|
2921
|
+
connectAttemptId += 1;
|
|
2922
|
+
const localAttemptId = connectAttemptId;
|
|
2356
2923
|
updateConnectState({
|
|
2357
2924
|
...InitialConnectStore,
|
|
2358
2925
|
connecting: true
|
|
@@ -2360,6 +2927,8 @@ function createCofhesdkClientBase(opts) {
|
|
|
2360
2927
|
try {
|
|
2361
2928
|
const chainId = await getPublicClientChainID(publicClient);
|
|
2362
2929
|
const account = await getWalletClientAccount(walletClient);
|
|
2930
|
+
if (localAttemptId !== connectAttemptId)
|
|
2931
|
+
return;
|
|
2363
2932
|
updateConnectState({
|
|
2364
2933
|
connected: true,
|
|
2365
2934
|
connecting: false,
|
|
@@ -2370,6 +2939,8 @@ function createCofhesdkClientBase(opts) {
|
|
|
2370
2939
|
walletClient
|
|
2371
2940
|
});
|
|
2372
2941
|
} catch (e) {
|
|
2942
|
+
if (localAttemptId !== connectAttemptId)
|
|
2943
|
+
return;
|
|
2373
2944
|
updateConnectState({
|
|
2374
2945
|
...InitialConnectStore,
|
|
2375
2946
|
connectError: e
|
|
@@ -2377,6 +2948,10 @@ function createCofhesdkClientBase(opts) {
|
|
|
2377
2948
|
throw e;
|
|
2378
2949
|
}
|
|
2379
2950
|
}
|
|
2951
|
+
function disconnect() {
|
|
2952
|
+
connectAttemptId += 1;
|
|
2953
|
+
updateConnectState({ ...InitialConnectStore });
|
|
2954
|
+
}
|
|
2380
2955
|
function encryptInputs(inputs) {
|
|
2381
2956
|
const state = connectStore.getState();
|
|
2382
2957
|
return new EncryptInputsBuilder({
|
|
@@ -2396,16 +2971,28 @@ function createCofhesdkClientBase(opts) {
|
|
|
2396
2971
|
requireConnected: _requireConnected
|
|
2397
2972
|
});
|
|
2398
2973
|
}
|
|
2399
|
-
function
|
|
2974
|
+
function decryptForView(ctHash, utype) {
|
|
2400
2975
|
const state = connectStore.getState();
|
|
2401
|
-
return new
|
|
2976
|
+
return new DecryptForViewBuilder({
|
|
2402
2977
|
ctHash,
|
|
2403
2978
|
utype,
|
|
2404
|
-
chainId: state.chainId
|
|
2405
|
-
account: state.account
|
|
2979
|
+
chainId: state.chainId,
|
|
2980
|
+
account: state.account,
|
|
2406
2981
|
config: opts.config,
|
|
2407
|
-
publicClient: state.publicClient
|
|
2408
|
-
walletClient: state.walletClient
|
|
2982
|
+
publicClient: state.publicClient,
|
|
2983
|
+
walletClient: state.walletClient,
|
|
2984
|
+
requireConnected: _requireConnected
|
|
2985
|
+
});
|
|
2986
|
+
}
|
|
2987
|
+
function decryptForTx(ctHash) {
|
|
2988
|
+
const state = connectStore.getState();
|
|
2989
|
+
return new DecryptForTxBuilder({
|
|
2990
|
+
ctHash,
|
|
2991
|
+
chainId: state.chainId,
|
|
2992
|
+
account: state.account,
|
|
2993
|
+
config: opts.config,
|
|
2994
|
+
publicClient: state.publicClient,
|
|
2995
|
+
walletClient: state.walletClient,
|
|
2409
2996
|
requireConnected: _requireConnected
|
|
2410
2997
|
});
|
|
2411
2998
|
}
|
|
@@ -2414,7 +3001,7 @@ function createCofhesdkClientBase(opts) {
|
|
|
2414
3001
|
const _chainId = chainId ?? state.chainId;
|
|
2415
3002
|
const _account = account ?? state.account;
|
|
2416
3003
|
if (_chainId == null || _account == null) {
|
|
2417
|
-
throw new
|
|
3004
|
+
throw new CofheError({
|
|
2418
3005
|
code: "NOT_CONNECTED" /* NotConnected */,
|
|
2419
3006
|
message: "ChainId or account not available.",
|
|
2420
3007
|
hint: "Ensure client.connect() has been called, or provide chainId and account explicitly.",
|
|
@@ -2481,9 +3068,9 @@ function createCofhesdkClientBase(opts) {
|
|
|
2481
3068
|
const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
|
|
2482
3069
|
return permits.selectActivePermit(_chainId, _account, hash);
|
|
2483
3070
|
},
|
|
2484
|
-
removePermit: async (hash, chainId, account
|
|
3071
|
+
removePermit: async (hash, chainId, account) => {
|
|
2485
3072
|
const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
|
|
2486
|
-
return permits.removePermit(_chainId, _account, hash
|
|
3073
|
+
return permits.removePermit(_chainId, _account, hash);
|
|
2487
3074
|
},
|
|
2488
3075
|
removeActivePermit: async (chainId, account) => {
|
|
2489
3076
|
const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
|
|
@@ -2499,6 +3086,9 @@ function createCofhesdkClientBase(opts) {
|
|
|
2499
3086
|
getSnapshot: connectStore.getState,
|
|
2500
3087
|
subscribe: connectStore.subscribe,
|
|
2501
3088
|
// flags (read-only: reflect snapshot)
|
|
3089
|
+
get connection() {
|
|
3090
|
+
return connectStore.getState();
|
|
3091
|
+
},
|
|
2502
3092
|
get connected() {
|
|
2503
3093
|
return connectStore.getState().connected;
|
|
2504
3094
|
},
|
|
@@ -2508,8 +3098,14 @@ function createCofhesdkClientBase(opts) {
|
|
|
2508
3098
|
// config & platform-specific (read-only)
|
|
2509
3099
|
config: opts.config,
|
|
2510
3100
|
connect,
|
|
3101
|
+
disconnect,
|
|
2511
3102
|
encryptInputs,
|
|
2512
|
-
|
|
3103
|
+
decryptForView,
|
|
3104
|
+
/**
|
|
3105
|
+
* @deprecated Use `decryptForView` instead. Kept for backward compatibility.
|
|
3106
|
+
*/
|
|
3107
|
+
decryptHandle: decryptForView,
|
|
3108
|
+
decryptForTx,
|
|
2513
3109
|
permits: clientPermits
|
|
2514
3110
|
// Add SDK-specific methods below that require connection
|
|
2515
3111
|
// Example:
|
|
@@ -2520,4 +3116,4 @@ function createCofhesdkClientBase(opts) {
|
|
|
2520
3116
|
};
|
|
2521
3117
|
}
|
|
2522
3118
|
|
|
2523
|
-
export {
|
|
3119
|
+
export { CofheError, CofheErrorCode, DecryptForTxBuilder, DecryptForViewBuilder, EncryptInputsBuilder, EncryptStep, Encryptable, FheAllUTypes, FheTypes, FheUintUTypes, InitialConnectStore, assertCorrectEncryptedItemInput, createCofheClientBase, createCofheConfigBase, createKeysStore, fetchKeys, fheTypeToString, getCofheConfigItem, isCofheError, isEncryptableItem, isLastEncryptionStep, zkProveWithWorker };
|