@cofhe/sdk 0.6.0 → 0.7.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 +49 -0
- package/acps/acp.ts +411 -0
- package/acps/index.ts +70 -0
- package/{permits → acps}/onchain-utils.ts +49 -24
- package/acps/sealing.ts +90 -0
- package/acps/signature.ts +89 -0
- package/acps/store.ts +172 -0
- package/acps/test/acp.test.ts +615 -0
- package/acps/test/localstorage.test.ts +105 -0
- package/acps/test/sealing.test.ts +77 -0
- package/acps/test/store.test.ts +88 -0
- package/acps/test/validation.test.ts +361 -0
- package/acps/test-utils.ts +32 -0
- package/acps/types.ts +252 -0
- package/acps/validation.ts +392 -0
- package/adapters/test/ethers5.test.ts +4 -1
- package/adapters/test/ethers6.test.ts +4 -1
- package/adapters/test/wagmi.test.ts +5 -2
- package/chains/chains/stagingCofhe.ts +21 -0
- package/chains/index.ts +3 -1
- package/chains/test/chains.test.ts +2 -1
- package/core/acps.ts +625 -0
- package/core/client.ts +136 -39
- package/core/clientTypes.ts +52 -41
- package/core/config.ts +66 -5
- package/core/debug.ts +72 -0
- package/core/decrypt/MockThresholdNetworkAbi.ts +20 -11
- package/core/decrypt/apiError.ts +104 -0
- package/core/decrypt/cofheMocksDecryptForTx.ts +11 -11
- package/core/decrypt/cofheMocksDecryptForView.ts +7 -7
- package/core/decrypt/decryptForTxBuilder.ts +102 -102
- package/core/decrypt/decryptForViewBuilder.ts +90 -90
- package/core/decrypt/submitRetry.ts +38 -30
- package/core/decrypt/tnDecryptV1.ts +5 -5
- package/core/decrypt/tnDecryptV2.ts +45 -34
- package/core/decrypt/tnSealOutputV1.ts +4 -3
- package/core/decrypt/tnSealOutputV2.ts +44 -31
- package/core/encrypt/cofheMocksZkVerifySign.ts +59 -74
- package/core/encrypt/encryptInputsBuilder.ts +86 -52
- package/core/encrypt/zkPackProveVerify.ts +25 -18
- package/core/error.ts +34 -6
- package/core/index.ts +14 -14
- package/core/test/acpDefaults.test.ts +52 -0
- package/core/test/acps.test.ts +596 -0
- package/core/test/apiError.test.ts +130 -0
- package/core/test/client.test.ts +22 -19
- package/core/test/config.test.ts +25 -5
- package/core/test/decrypt.test.ts +40 -35
- package/core/test/decryptBuilders.test.ts +68 -68
- package/core/test/decryptErrorCodes.test.ts +217 -0
- package/core/test/encryptInputsBuilder.test.ts +72 -41
- package/core/test/pollCallbacks.test.ts +89 -18
- package/core/test/stagingRedirect.ts +18 -0
- package/core/test/submitRetry.test.ts +182 -0
- package/core/types.ts +9 -69
- package/dist/acp-Wi6isVQI.d.cts +407 -0
- package/dist/acp-Wi6isVQI.d.ts +407 -0
- package/dist/acps.cjs +1081 -0
- package/dist/acps.d.cts +480 -0
- package/dist/acps.d.ts +480 -0
- package/dist/acps.js +2 -0
- package/dist/chains.cjs +14 -1
- package/dist/chains.d.cts +30 -1
- package/dist/chains.d.ts +30 -1
- package/dist/chains.js +1 -1
- package/dist/{chunk-PE5V5CCV.js → chunk-43USWPEH.js} +1000 -604
- package/dist/{chunk-MTRAXQXC.js → chunk-N6IDQRRU.js} +14 -2
- package/dist/chunk-Q7CBWGQX.js +1029 -0
- package/dist/{clientTypes-CyUvRRzA.d.ts → clientTypes-BN3nbzYM.d.ts} +342 -165
- package/dist/{clientTypes-BDy1qIBu.d.cts → clientTypes-CYZjFznO.d.cts} +342 -165
- package/dist/core.cjs +1431 -1026
- package/dist/core.d.cts +55 -10
- package/dist/core.d.ts +55 -10
- package/dist/core.js +3 -3
- package/dist/node.cjs +1356 -976
- package/dist/node.d.cts +2 -2
- package/dist/node.d.ts +2 -2
- package/dist/node.js +3 -3
- package/dist/web.cjs +1356 -976
- package/dist/web.d.cts +2 -2
- package/dist/web.d.ts +2 -2
- package/dist/web.js +3 -3
- package/node/test/inherited.test.ts +75 -65
- package/node/test/tfheinit.test.ts +23 -8
- package/package.json +6 -6
- package/web/test/client.web.test.ts +5 -1
- package/web/test/inherited.web.test.ts +75 -65
- package/web/test/tfheinit.web.test.ts +14 -5
- package/web/test/worker.config.web.test.ts +38 -23
- package/web/test/worker.output.web.test.ts +25 -24
- package/core/encrypt/encryptUtils.ts +0 -67
- package/core/permits.ts +0 -206
- package/core/test/permits.test.ts +0 -534
- package/dist/chunk-VB62WYPL.js +0 -978
- package/dist/permit-DnVMDT5h.d.cts +0 -376
- package/dist/permit-DnVMDT5h.d.ts +0 -376
- package/dist/permits.cjs +0 -1026
- package/dist/permits.d.cts +0 -353
- package/dist/permits.d.ts +0 -353
- package/dist/permits.js +0 -2
- package/permits/index.ts +0 -68
- package/permits/permit.ts +0 -385
- package/permits/sealing.ts +0 -131
- package/permits/signature.ts +0 -79
- package/permits/store.ts +0 -157
- package/permits/test/localstorage.test.ts +0 -113
- package/permits/test/permit.test.ts +0 -557
- package/permits/test/sealing.test.ts +0 -84
- package/permits/test/store.test.ts +0 -88
- package/permits/test/validation.test.ts +0 -361
- package/permits/test-utils.ts +0 -28
- package/permits/types.ts +0 -204
- package/permits/validation.ts +0 -327
- /package/{permits → acps}/utils.ts +0 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { hardhat as hardhat$1 } from './chunk-
|
|
2
|
-
import {
|
|
1
|
+
import { hardhat as hardhat$1 } from './chunk-N6IDQRRU.js';
|
|
2
|
+
import { acpStore, ACPUtils } from './chunk-Q7CBWGQX.js';
|
|
3
3
|
import { TFHE_RS_KEY_VERSION, TASK_MANAGER_ADDRESS, TFHE_RS_ZK_MAX_BITS, TFHE_RS_SAFE_SERIALIZATION_SIZE_LIMIT, MOCKS_THRESHOLD_NETWORK_ADDRESS, MOCKS_DECRYPT_RESULT_SIGNER_PRIVATE_KEY, MOCKS_ZK_VERIFIER_SIGNER_PRIVATE_KEY, MOCKS_ZK_VERIFIER_ADDRESS } from './chunk-ESMZCFJY.js';
|
|
4
4
|
import { createStore } from 'zustand/vanilla';
|
|
5
|
-
import { parseAbi, isAddressEqual, zeroAddress, recoverAddress,
|
|
5
|
+
import { parseAbi, isAddressEqual, zeroAddress, recoverAddress, keccak256, encodeAbiParameters, encodePacked, createWalletClient, http, getAddress, parseSignature, serializeSignature } from 'viem';
|
|
6
6
|
import { hardhat } from 'viem/chains';
|
|
7
7
|
import { sign, privateKeyToAccount } from 'viem/accounts';
|
|
8
8
|
import { z } from 'zod';
|
|
@@ -10,58 +10,78 @@ import { persist, createJSONStorage } from 'zustand/middleware';
|
|
|
10
10
|
import { produce } from 'immer';
|
|
11
11
|
|
|
12
12
|
// core/error.ts
|
|
13
|
-
var CofheErrorCode = /* @__PURE__ */ ((
|
|
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
|
-
|
|
57
|
-
|
|
13
|
+
var CofheErrorCode = /* @__PURE__ */ ((CofheErrorCode2) => {
|
|
14
|
+
CofheErrorCode2["InternalError"] = "INTERNAL_ERROR";
|
|
15
|
+
CofheErrorCode2["UnknownEnvironment"] = "UNKNOWN_ENVIRONMENT";
|
|
16
|
+
CofheErrorCode2["InitTfheFailed"] = "INIT_TFHE_FAILED";
|
|
17
|
+
CofheErrorCode2["InitViemFailed"] = "INIT_VIEM_FAILED";
|
|
18
|
+
CofheErrorCode2["InitEthersFailed"] = "INIT_ETHERS_FAILED";
|
|
19
|
+
CofheErrorCode2["NotConnected"] = "NOT_CONNECTED";
|
|
20
|
+
CofheErrorCode2["MissingPublicClient"] = "MISSING_PUBLIC_CLIENT";
|
|
21
|
+
CofheErrorCode2["MissingWalletClient"] = "MISSING_WALLET_CLIENT";
|
|
22
|
+
CofheErrorCode2["MissingProviderParam"] = "MISSING_PROVIDER_PARAM";
|
|
23
|
+
CofheErrorCode2["EmptySecurityZonesParam"] = "EMPTY_SECURITY_ZONES_PARAM";
|
|
24
|
+
CofheErrorCode2["InvalidACPData"] = "INVALID_ACP_DATA";
|
|
25
|
+
CofheErrorCode2["InvalidACPDomain"] = "INVALID_ACP_DOMAIN";
|
|
26
|
+
CofheErrorCode2["ACPNotFound"] = "ACP_NOT_FOUND";
|
|
27
|
+
CofheErrorCode2["CannotRemoveLastACP"] = "CANNOT_REMOVE_LAST_ACP";
|
|
28
|
+
CofheErrorCode2["AccountUninitialized"] = "ACCOUNT_UNINITIALIZED";
|
|
29
|
+
CofheErrorCode2["ChainIdUninitialized"] = "CHAIN_ID_UNINITIALIZED";
|
|
30
|
+
CofheErrorCode2["ConsumingContractUninitialized"] = "CONSUMING_CONTRACT_UNINITIALIZED";
|
|
31
|
+
CofheErrorCode2["SealOutputFailed"] = "SEAL_OUTPUT_FAILED";
|
|
32
|
+
CofheErrorCode2["SealOutputReturnedNull"] = "SEAL_OUTPUT_RETURNED_NULL";
|
|
33
|
+
CofheErrorCode2["InvalidUtype"] = "INVALID_UTYPE";
|
|
34
|
+
CofheErrorCode2["DecryptFailed"] = "DECRYPT_FAILED";
|
|
35
|
+
CofheErrorCode2["DecryptReturnedNull"] = "DECRYPT_RETURNED_NULL";
|
|
36
|
+
CofheErrorCode2["ZkMocksInsertCtHashesFailed"] = "ZK_MOCKS_INSERT_CT_HASHES_FAILED";
|
|
37
|
+
CofheErrorCode2["ZkMocksCalcCtHashesFailed"] = "ZK_MOCKS_CALC_CT_HASHES_FAILED";
|
|
38
|
+
CofheErrorCode2["ZkMocksVerifySignFailed"] = "ZK_MOCKS_VERIFY_SIGN_FAILED";
|
|
39
|
+
CofheErrorCode2["ZkMocksCreateProofSignatureFailed"] = "ZK_MOCKS_CREATE_PROOF_SIGNATURE_FAILED";
|
|
40
|
+
CofheErrorCode2["ZkVerifyFailed"] = "ZK_VERIFY_FAILED";
|
|
41
|
+
CofheErrorCode2["ZkPackFailed"] = "ZK_PACK_FAILED";
|
|
42
|
+
CofheErrorCode2["ZkProveFailed"] = "ZK_PROVE_FAILED";
|
|
43
|
+
CofheErrorCode2["EncryptRemainingInItems"] = "ENCRYPT_REMAINING_IN_ITEMS";
|
|
44
|
+
CofheErrorCode2["ZkUninitialized"] = "ZK_UNINITIALIZED";
|
|
45
|
+
CofheErrorCode2["ZkVerifierUrlUninitialized"] = "ZK_VERIFIER_URL_UNINITIALIZED";
|
|
46
|
+
CofheErrorCode2["ThresholdNetworkUrlUninitialized"] = "THRESHOLD_NETWORK_URL_UNINITIALIZED";
|
|
47
|
+
CofheErrorCode2["MissingConfig"] = "MISSING_CONFIG";
|
|
48
|
+
CofheErrorCode2["UnsupportedChain"] = "UNSUPPORTED_CHAIN";
|
|
49
|
+
CofheErrorCode2["MissingZkBuilderAndCrsGenerator"] = "MISSING_ZK_BUILDER_AND_CRS_GENERATOR";
|
|
50
|
+
CofheErrorCode2["MissingTfhePublicKeyDeserializer"] = "MISSING_TFHE_PUBLIC_KEY_DESERIALIZER";
|
|
51
|
+
CofheErrorCode2["MissingCompactPkeCrsDeserializer"] = "MISSING_COMPACT_PKE_CRS_DESERIALIZER";
|
|
52
|
+
CofheErrorCode2["MissingFheKey"] = "MISSING_FHE_KEY";
|
|
53
|
+
CofheErrorCode2["MissingCrs"] = "MISSING_CRS";
|
|
54
|
+
CofheErrorCode2["FetchKeysFailed"] = "FETCH_KEYS_FAILED";
|
|
55
|
+
CofheErrorCode2["PublicWalletGetChainIdFailed"] = "PUBLIC_WALLET_GET_CHAIN_ID_FAILED";
|
|
56
|
+
CofheErrorCode2["PublicWalletGetAddressesFailed"] = "PUBLIC_WALLET_GET_ADDRESSES_FAILED";
|
|
57
|
+
CofheErrorCode2["RehydrateKeysStoreFailed"] = "REHYDRATE_KEYS_STORE_FAILED";
|
|
58
|
+
CofheErrorCode2["BadRequest"] = "BAD_REQUEST";
|
|
59
|
+
CofheErrorCode2["UnknownChain"] = "UNKNOWN_CHAIN";
|
|
60
|
+
CofheErrorCode2["ACPMalformed"] = "ACP_MALFORMED";
|
|
61
|
+
CofheErrorCode2["ACPDenied"] = "ACP_DENIED";
|
|
62
|
+
CofheErrorCode2["ACPExpired"] = "ACP_EXPIRED";
|
|
63
|
+
CofheErrorCode2["ACPInvalid"] = "ACP_INVALID";
|
|
64
|
+
CofheErrorCode2["ACPRevoked"] = "ACP_REVOKED";
|
|
65
|
+
CofheErrorCode2["NotPubliclyAllowed"] = "NOT_PUBLICLY_ALLOWED";
|
|
66
|
+
CofheErrorCode2["CtNotFound"] = "CT_NOT_FOUND";
|
|
67
|
+
CofheErrorCode2["UnsupportedSecurityZone"] = "UNSUPPORTED_SECURITY_ZONE";
|
|
68
|
+
CofheErrorCode2["UnsupportedType"] = "UNSUPPORTED_TYPE";
|
|
69
|
+
CofheErrorCode2["SigningFailed"] = "SIGNING_FAILED";
|
|
70
|
+
CofheErrorCode2["CtSourceError"] = "CT_SOURCE_ERROR";
|
|
71
|
+
CofheErrorCode2["ACPVerifierError"] = "ACP_VERIFIER_ERROR";
|
|
72
|
+
CofheErrorCode2["CtSourceTimeout"] = "CT_SOURCE_TIMEOUT";
|
|
73
|
+
CofheErrorCode2["ACPVerifierTimeout"] = "ACP_VERIFIER_TIMEOUT";
|
|
74
|
+
CofheErrorCode2["ACPRequired"] = "ACP_REQUIRED";
|
|
75
|
+
CofheErrorCode2["SealFailed"] = "SEAL_FAILED";
|
|
76
|
+
return CofheErrorCode2;
|
|
58
77
|
})(CofheErrorCode || {});
|
|
59
78
|
var CofheError = class _CofheError extends Error {
|
|
60
79
|
code;
|
|
61
80
|
cause;
|
|
62
81
|
hint;
|
|
63
82
|
context;
|
|
64
|
-
|
|
83
|
+
apiErrorCode;
|
|
84
|
+
constructor({ code, message, cause, hint, context, apiErrorCode }) {
|
|
65
85
|
const fullMessage = cause ? `${message} | Caused by: ${cause.message}` : message;
|
|
66
86
|
super(fullMessage);
|
|
67
87
|
this.name = "CofheError";
|
|
@@ -69,6 +89,7 @@ var CofheError = class _CofheError extends Error {
|
|
|
69
89
|
this.cause = cause;
|
|
70
90
|
this.hint = hint;
|
|
71
91
|
this.context = context;
|
|
92
|
+
this.apiErrorCode = apiErrorCode;
|
|
72
93
|
if (Error.captureStackTrace) {
|
|
73
94
|
Error.captureStackTrace(this, _CofheError);
|
|
74
95
|
}
|
|
@@ -87,6 +108,7 @@ var CofheError = class _CofheError extends Error {
|
|
|
87
108
|
message: wrapperError?.message ?? "An internal error occurred",
|
|
88
109
|
hint: wrapperError?.hint,
|
|
89
110
|
context: wrapperError?.context,
|
|
111
|
+
apiErrorCode: wrapperError?.apiErrorCode,
|
|
90
112
|
cause
|
|
91
113
|
});
|
|
92
114
|
}
|
|
@@ -100,6 +122,7 @@ var CofheError = class _CofheError extends Error {
|
|
|
100
122
|
message: this.message,
|
|
101
123
|
hint: this.hint,
|
|
102
124
|
context: this.context,
|
|
125
|
+
apiErrorCode: this.apiErrorCode,
|
|
103
126
|
cause: this.cause ? {
|
|
104
127
|
name: this.cause.name,
|
|
105
128
|
message: this.cause.message,
|
|
@@ -112,7 +135,8 @@ var CofheError = class _CofheError extends Error {
|
|
|
112
135
|
* Returns a human-readable string representation of the error
|
|
113
136
|
*/
|
|
114
137
|
toString() {
|
|
115
|
-
const
|
|
138
|
+
const codeSuffix = this.apiErrorCode ? ` (api: ${this.apiErrorCode})` : "";
|
|
139
|
+
const parts = [`${this.name} [${this.code}]${codeSuffix}: ${this.message}`];
|
|
116
140
|
if (this.hint) {
|
|
117
141
|
parts.push(`Hint: ${this.hint}`);
|
|
118
142
|
}
|
|
@@ -198,10 +222,6 @@ var FheAllUTypes = [
|
|
|
198
222
|
// FheTypes.Uint256,
|
|
199
223
|
7 /* Uint160 */
|
|
200
224
|
];
|
|
201
|
-
function assertCorrectEncryptedItemInput(input) {
|
|
202
|
-
if (!input.signature.startsWith("0x"))
|
|
203
|
-
throw new Error("Signature must be a hex string starting with 0x");
|
|
204
|
-
}
|
|
205
225
|
var EncryptableFactoriesImpl = {
|
|
206
226
|
bool: (data, securityZone = 0) => ({ data, securityZone, utype: 0 /* Bool */ }),
|
|
207
227
|
address: (data, securityZone = 0) => ({ data, securityZone, utype: 7 /* Uint160 */ }),
|
|
@@ -481,18 +501,19 @@ var constructZkPoKMetadata = (accountAddr, securityZone, chainId) => {
|
|
|
481
501
|
metadata.set(chainIdBytes, 1 + accountBytes.length);
|
|
482
502
|
return metadata;
|
|
483
503
|
};
|
|
484
|
-
var
|
|
504
|
+
var zkVerifyBatch = async (verifierUrl, serializedBytes, address, securityZone, chainId, consumingContract) => {
|
|
485
505
|
const packed_list = toHexString(serializedBytes);
|
|
486
506
|
const sz_byte = new Uint8Array([securityZone]);
|
|
487
507
|
const payload = {
|
|
488
508
|
packed_list,
|
|
489
509
|
account_addr: address,
|
|
490
510
|
security_zone: sz_byte[0],
|
|
491
|
-
chain_id: chainId
|
|
511
|
+
chain_id: chainId,
|
|
512
|
+
contract_address: consumingContract
|
|
492
513
|
};
|
|
493
514
|
const body = JSON.stringify(payload);
|
|
494
515
|
try {
|
|
495
|
-
const response = await fetch(`${verifierUrl}/
|
|
516
|
+
const response = await fetch(`${verifierUrl}/verifyBatch`, {
|
|
496
517
|
method: "POST",
|
|
497
518
|
headers: {
|
|
498
519
|
"Content-Type": "application/json"
|
|
@@ -503,26 +524,25 @@ var zkVerify = async (verifierUrl, serializedBytes, address, securityZone, chain
|
|
|
503
524
|
const errorBody = await response.text();
|
|
504
525
|
throw new CofheError({
|
|
505
526
|
code: "ZK_VERIFY_FAILED" /* ZkVerifyFailed */,
|
|
506
|
-
message: `HTTP error! ZK proof verification failed - ${errorBody}`
|
|
527
|
+
message: `HTTP error! ZK batch proof verification failed - ${errorBody}`
|
|
507
528
|
});
|
|
508
529
|
}
|
|
509
530
|
const json = await response.json();
|
|
510
531
|
if (json.status !== "success") {
|
|
511
532
|
throw new CofheError({
|
|
512
533
|
code: "ZK_VERIFY_FAILED" /* ZkVerifyFailed */,
|
|
513
|
-
message: `ZK proof verification response malformed - ${json.error}`
|
|
534
|
+
message: `ZK batch proof verification response malformed - ${json.error}`
|
|
514
535
|
});
|
|
515
536
|
}
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
});
|
|
537
|
+
const { ciphertexts, signature, recid } = json.data;
|
|
538
|
+
return {
|
|
539
|
+
outputs: ciphertexts,
|
|
540
|
+
signature: concatSigRecid(signature, recid)
|
|
541
|
+
};
|
|
522
542
|
} catch (e) {
|
|
523
543
|
throw new CofheError({
|
|
524
544
|
code: "ZK_VERIFY_FAILED" /* ZkVerifyFailed */,
|
|
525
|
-
message: `ZK proof verification failed`,
|
|
545
|
+
message: `ZK batch proof verification failed`,
|
|
526
546
|
cause: e instanceof Error ? e : void 0
|
|
527
547
|
});
|
|
528
548
|
}
|
|
@@ -767,75 +787,67 @@ async function insertCtHashes(items, walletClient) {
|
|
|
767
787
|
});
|
|
768
788
|
}
|
|
769
789
|
}
|
|
770
|
-
async function
|
|
771
|
-
let signatures = [];
|
|
772
|
-
let encInputSignerClient;
|
|
790
|
+
async function createBatchProofSignature(items, securityZone, account, consumingContract) {
|
|
773
791
|
try {
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
792
|
+
const itemHashes = items.map(
|
|
793
|
+
(item) => keccak256(
|
|
794
|
+
encodePacked(
|
|
795
|
+
["uint256", "uint8", "uint8", "address", "uint256", "address"],
|
|
796
|
+
[
|
|
797
|
+
BigInt(item.ctHash),
|
|
798
|
+
item.utype,
|
|
799
|
+
securityZone,
|
|
800
|
+
account,
|
|
801
|
+
BigInt(hardhat.id),
|
|
802
|
+
consumingContract
|
|
803
|
+
]
|
|
804
|
+
)
|
|
805
|
+
)
|
|
806
|
+
);
|
|
807
|
+
const batchDigest = keccak256(
|
|
808
|
+
encodePacked(
|
|
809
|
+
itemHashes.map(() => "bytes32"),
|
|
810
|
+
itemHashes
|
|
811
|
+
)
|
|
812
|
+
);
|
|
813
|
+
return await sign({
|
|
814
|
+
hash: batchDigest,
|
|
815
|
+
privateKey: MOCKS_ZK_VERIFIER_SIGNER_PRIVATE_KEY,
|
|
816
|
+
to: "hex"
|
|
783
817
|
});
|
|
784
|
-
}
|
|
785
|
-
try {
|
|
786
|
-
for (const item of items) {
|
|
787
|
-
const packedData = encodePacked(
|
|
788
|
-
["uint256", "uint8", "uint8", "address", "uint256"],
|
|
789
|
-
[BigInt(item.ctHash), item.utype, securityZone, account, BigInt(hardhat.id)]
|
|
790
|
-
);
|
|
791
|
-
const messageHash = keccak256(packedData);
|
|
792
|
-
const signature = await sign({
|
|
793
|
-
hash: messageHash,
|
|
794
|
-
privateKey: MOCKS_ZK_VERIFIER_SIGNER_PRIVATE_KEY,
|
|
795
|
-
to: "hex"
|
|
796
|
-
});
|
|
797
|
-
signatures.push(signature);
|
|
798
|
-
}
|
|
799
818
|
} catch (err) {
|
|
800
819
|
throw new CofheError({
|
|
801
820
|
code: "ZK_MOCKS_CREATE_PROOF_SIGNATURE_FAILED" /* ZkMocksCreateProofSignatureFailed */,
|
|
802
|
-
message: `mockZkVerifySign
|
|
821
|
+
message: `mockZkVerifySign createBatchProofSignature failed while signing the batch digest`,
|
|
803
822
|
cause: err instanceof Error ? err : void 0,
|
|
804
823
|
context: {
|
|
805
824
|
items,
|
|
806
|
-
securityZone
|
|
807
|
-
|
|
808
|
-
});
|
|
809
|
-
}
|
|
810
|
-
if (signatures.length !== items.length) {
|
|
811
|
-
throw new CofheError({
|
|
812
|
-
code: "ZK_MOCKS_CREATE_PROOF_SIGNATURE_FAILED" /* ZkMocksCreateProofSignatureFailed */,
|
|
813
|
-
message: `mockZkVerifySign createProofSignatures returned incorrect number of signatures`,
|
|
814
|
-
context: {
|
|
815
|
-
items,
|
|
816
|
-
securityZone
|
|
825
|
+
securityZone,
|
|
826
|
+
consumingContract
|
|
817
827
|
}
|
|
818
828
|
});
|
|
819
829
|
}
|
|
820
|
-
return signatures;
|
|
821
830
|
}
|
|
822
|
-
async function cofheMocksZkVerifySign(items, account, securityZone, publicClient, walletClient, zkvWalletClient) {
|
|
831
|
+
async function cofheMocksZkVerifySign(items, account, securityZone, consumingContract, publicClient, walletClient, zkvWalletClient) {
|
|
823
832
|
const _walletClient = zkvWalletClient ?? createMockZkVerifierSigner();
|
|
824
833
|
const encryptableItems = await calcCtHashes(items, account, securityZone, publicClient);
|
|
825
834
|
await insertCtHashes(encryptableItems, _walletClient);
|
|
826
|
-
const
|
|
827
|
-
return
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
835
|
+
const signature = await createBatchProofSignature(encryptableItems, securityZone, account, consumingContract);
|
|
836
|
+
return {
|
|
837
|
+
outputs: encryptableItems.map((item) => ({
|
|
838
|
+
ct_hash: item.ctHash.toString(),
|
|
839
|
+
ct_type: item.utype
|
|
840
|
+
})),
|
|
841
|
+
signature
|
|
842
|
+
};
|
|
831
843
|
}
|
|
832
844
|
var CofheConfigSchema = z.object({
|
|
833
845
|
/** Environment that the SDK is running in */
|
|
834
846
|
environment: z.enum(["node", "hardhat", "web", "react"]).optional().default("node"),
|
|
835
847
|
/** List of supported chain configurations */
|
|
836
848
|
supportedChains: z.array(z.custom()),
|
|
837
|
-
/** Default
|
|
838
|
-
|
|
849
|
+
/** Default acp expiration in seconds, default is 30 days */
|
|
850
|
+
defaultACPExpiration: z.number().optional().default(60 * 60 * 24 * 30),
|
|
839
851
|
/** Storage method for fhe keys (defaults to indexedDB on web, filesystem on node) */
|
|
840
852
|
fheKeyStorage: z.object({
|
|
841
853
|
getItem: z.custom((val) => typeof val === "function", {
|
|
@@ -850,6 +862,12 @@ var CofheConfigSchema = z.object({
|
|
|
850
862
|
}).or(z.null()).default(null),
|
|
851
863
|
/** Whether to use Web Workers for ZK proof generation (web platform only) */
|
|
852
864
|
useWorkers: z.boolean().optional().default(true),
|
|
865
|
+
/** ACP acp defaults */
|
|
866
|
+
acp: z.object({
|
|
867
|
+
defaultRevoker: z.custom().optional(),
|
|
868
|
+
defaultContractScopes: z.custom().optional(),
|
|
869
|
+
sharingRegistry: z.custom().optional()
|
|
870
|
+
}).optional().default({}),
|
|
853
871
|
/** Mocks configs */
|
|
854
872
|
mocks: z.object({
|
|
855
873
|
decryptDelay: z.number().optional().default(0),
|
|
@@ -860,8 +878,19 @@ var CofheConfigSchema = z.object({
|
|
|
860
878
|
zkvWalletClient: z.any().optional()
|
|
861
879
|
}).optional()
|
|
862
880
|
});
|
|
881
|
+
var RENAMED_COFHE_CONFIG_KEYS = {
|
|
882
|
+
defaultPermitExpiration: "defaultACPExpiration"
|
|
883
|
+
};
|
|
884
|
+
function assertNoRenamedConfigKeys(config, renamedKeys, label) {
|
|
885
|
+
const stale = Object.keys(config).filter((key) => key in renamedKeys);
|
|
886
|
+
if (stale.length === 0)
|
|
887
|
+
return;
|
|
888
|
+
const renames = stale.map((key) => `\`${key}\` is now \`${renamedKeys[key]}\``).join("; ");
|
|
889
|
+
throw new Error(`Invalid ${label}: ${renames}. See the v0.7.0 migration guide.`);
|
|
890
|
+
}
|
|
863
891
|
function createCofheConfigBase(config) {
|
|
864
|
-
|
|
892
|
+
assertNoRenamedConfigKeys(config, RENAMED_COFHE_CONFIG_KEYS, "cofhe configuration");
|
|
893
|
+
const result = CofheConfigSchema.strict().safeParse(config);
|
|
865
894
|
if (!result.success) {
|
|
866
895
|
throw new Error(`Invalid cofhe configuration: ${z.prettifyError(result.error)}`, { cause: result.error });
|
|
867
896
|
}
|
|
@@ -1213,9 +1242,9 @@ var BaseBuilder = class {
|
|
|
1213
1242
|
// core/encrypt/encryptInputsBuilder.ts
|
|
1214
1243
|
var EncryptInputsBuilder = class extends BaseBuilder {
|
|
1215
1244
|
securityZone;
|
|
1245
|
+
consumingContract;
|
|
1216
1246
|
stepCallback;
|
|
1217
1247
|
inputItems;
|
|
1218
|
-
hpp = false;
|
|
1219
1248
|
zkvWalletClient;
|
|
1220
1249
|
tfhePublicKeyDeserializer;
|
|
1221
1250
|
compactPkeCrsDeserializer;
|
|
@@ -1282,20 +1311,6 @@ var EncryptInputsBuilder = class extends BaseBuilder {
|
|
|
1282
1311
|
this.keysStorage = params.keysStorage;
|
|
1283
1312
|
this.useWorker = params.config?.useWorkers ?? true;
|
|
1284
1313
|
}
|
|
1285
|
-
/**
|
|
1286
|
-
* @param account - Account that will create the tx using the encrypted inputs.
|
|
1287
|
-
*
|
|
1288
|
-
* If not provided, the account will be fetched from the connected walletClient.
|
|
1289
|
-
*
|
|
1290
|
-
* Example:
|
|
1291
|
-
* ```typescript
|
|
1292
|
-
* const encrypted = await encryptInputs([Encryptable.uint128(10n)])
|
|
1293
|
-
* .setAccount("0x123")
|
|
1294
|
-
* .execute();
|
|
1295
|
-
* ```
|
|
1296
|
-
*
|
|
1297
|
-
* @returns The chainable EncryptInputsBuilder instance.
|
|
1298
|
-
*/
|
|
1299
1314
|
setAccount(account) {
|
|
1300
1315
|
this.account = account;
|
|
1301
1316
|
return this;
|
|
@@ -1303,20 +1318,6 @@ var EncryptInputsBuilder = class extends BaseBuilder {
|
|
|
1303
1318
|
getAccount() {
|
|
1304
1319
|
return this.account;
|
|
1305
1320
|
}
|
|
1306
|
-
/**
|
|
1307
|
-
* @param chainId - Chain that will consume the encrypted inputs.
|
|
1308
|
-
*
|
|
1309
|
-
* If not provided, the chainId will be fetched from the connected publicClient.
|
|
1310
|
-
*
|
|
1311
|
-
* Example:
|
|
1312
|
-
* ```typescript
|
|
1313
|
-
* const encrypted = await encryptInputs([Encryptable.uint128(10n)])
|
|
1314
|
-
* .setChainId(11155111)
|
|
1315
|
-
* .execute();
|
|
1316
|
-
* ```
|
|
1317
|
-
*
|
|
1318
|
-
* @returns The chainable EncryptInputsBuilder instance.
|
|
1319
|
-
*/
|
|
1320
1321
|
setChainId(chainId) {
|
|
1321
1322
|
this.chainId = chainId;
|
|
1322
1323
|
return this;
|
|
@@ -1324,20 +1325,6 @@ var EncryptInputsBuilder = class extends BaseBuilder {
|
|
|
1324
1325
|
getChainId() {
|
|
1325
1326
|
return this.chainId;
|
|
1326
1327
|
}
|
|
1327
|
-
/**
|
|
1328
|
-
* @param securityZone - Security zone to encrypt the inputs for.
|
|
1329
|
-
*
|
|
1330
|
-
* If not provided, the default securityZone 0 will be used.
|
|
1331
|
-
*
|
|
1332
|
-
* Example:
|
|
1333
|
-
* ```typescript
|
|
1334
|
-
* const encrypted = await encryptInputs([Encryptable.uint128(10n)])
|
|
1335
|
-
* .setSecurityZone(1)
|
|
1336
|
-
* .execute();
|
|
1337
|
-
* ```
|
|
1338
|
-
*
|
|
1339
|
-
* @returns The chainable EncryptInputsBuilder instance.
|
|
1340
|
-
*/
|
|
1341
1328
|
setSecurityZone(securityZone) {
|
|
1342
1329
|
this.securityZone = securityZone;
|
|
1343
1330
|
return this;
|
|
@@ -1346,33 +1333,44 @@ var EncryptInputsBuilder = class extends BaseBuilder {
|
|
|
1346
1333
|
return this.securityZone;
|
|
1347
1334
|
}
|
|
1348
1335
|
/**
|
|
1336
|
+
* @param address - The contract that will consume the resulting hashes+signature (i.e. the
|
|
1337
|
+
* contract that will call `FHE.asEuint*`/`FHE.asEuint*s` with them).
|
|
1338
|
+
*
|
|
1339
|
+
* Required before `execute()` - the verifier binds this address into the signed digest, so a
|
|
1340
|
+
* batch signed for one contract cannot be replayed into another.
|
|
1341
|
+
*
|
|
1349
1342
|
* Example:
|
|
1350
1343
|
* ```typescript
|
|
1351
1344
|
* const encrypted = await encryptInputs([Encryptable.uint128(10n)])
|
|
1352
|
-
* .
|
|
1345
|
+
* .setConsumingContract("0x123...890")
|
|
1353
1346
|
* .execute();
|
|
1354
1347
|
* ```
|
|
1355
1348
|
*
|
|
1356
|
-
* @returns
|
|
1349
|
+
* @returns The chainable EncryptInputsBuilder instance.
|
|
1357
1350
|
*/
|
|
1358
|
-
|
|
1359
|
-
this.
|
|
1351
|
+
setConsumingContract(address) {
|
|
1352
|
+
this.consumingContract = address;
|
|
1360
1353
|
return this;
|
|
1361
1354
|
}
|
|
1355
|
+
getConsumingContract() {
|
|
1356
|
+
return this.consumingContract;
|
|
1357
|
+
}
|
|
1362
1358
|
/**
|
|
1363
|
-
*
|
|
1364
|
-
*
|
|
1365
|
-
* Overrides the config-level useWorkers setting for this specific encryption.
|
|
1366
|
-
*
|
|
1367
|
-
* Example:
|
|
1368
|
-
* ```typescript
|
|
1369
|
-
* const encrypted = await encryptInputs([Encryptable.uint128(10n)])
|
|
1370
|
-
* .setUseWorker(false)
|
|
1371
|
-
* .execute();
|
|
1372
|
-
* ```
|
|
1373
|
-
*
|
|
1374
|
-
* @returns The chainable EncryptInputsBuilder instance.
|
|
1359
|
+
* Asserts that this.consumingContract is populated
|
|
1360
|
+
* @throws {CofheError} If consumingContract is not set
|
|
1375
1361
|
*/
|
|
1362
|
+
assertConsumingContract() {
|
|
1363
|
+
if (this.consumingContract)
|
|
1364
|
+
return;
|
|
1365
|
+
throw new CofheError({
|
|
1366
|
+
code: "CONSUMING_CONTRACT_UNINITIALIZED" /* ConsumingContractUninitialized */,
|
|
1367
|
+
message: "Consuming contract is not set",
|
|
1368
|
+
hint: "Use setConsumingContract(...) to set the contract that will consume the encrypted inputs.",
|
|
1369
|
+
context: {
|
|
1370
|
+
consumingContract: this.consumingContract
|
|
1371
|
+
}
|
|
1372
|
+
});
|
|
1373
|
+
}
|
|
1376
1374
|
setUseWorker(useWorker) {
|
|
1377
1375
|
this.useWorker = useWorker;
|
|
1378
1376
|
return this;
|
|
@@ -1393,21 +1391,6 @@ var EncryptInputsBuilder = class extends BaseBuilder {
|
|
|
1393
1391
|
getUseWorker() {
|
|
1394
1392
|
return this.useWorker;
|
|
1395
1393
|
}
|
|
1396
|
-
/**
|
|
1397
|
-
* @param callback - Function to be called with the encryption step.
|
|
1398
|
-
*
|
|
1399
|
-
* Useful for debugging and tracking the progress of the encryption process.
|
|
1400
|
-
* Useful for a UI element that shows the progress of the encryption process.
|
|
1401
|
-
*
|
|
1402
|
-
* Example:
|
|
1403
|
-
* ```typescript
|
|
1404
|
-
* const encrypted = await encryptInputs([Encryptable.uint128(10n)])
|
|
1405
|
-
* .onStep((step: EncryptStep) => console.log(step))
|
|
1406
|
-
* .execute();
|
|
1407
|
-
* ```
|
|
1408
|
-
*
|
|
1409
|
-
* @returns The EncryptInputsBuilder instance.
|
|
1410
|
-
*/
|
|
1411
1394
|
onStep(callback) {
|
|
1412
1395
|
this.stepCallback = callback;
|
|
1413
1396
|
return this;
|
|
@@ -1546,6 +1529,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
|
|
|
1546
1529
|
this.assertAccount();
|
|
1547
1530
|
this.assertPublicClient();
|
|
1548
1531
|
this.assertWalletClient();
|
|
1532
|
+
this.assertConsumingContract();
|
|
1549
1533
|
const [initTfheDelay, fetchKeysDelay, packDelay, proveDelay, verifyDelay] = this.resolveEncryptDelays();
|
|
1550
1534
|
this.fireStepStart("initTfhe" /* InitTfhe */);
|
|
1551
1535
|
await sleep(initTfheDelay);
|
|
@@ -1571,22 +1555,17 @@ var EncryptInputsBuilder = class extends BaseBuilder {
|
|
|
1571
1555
|
this.fireStepEnd("prove" /* Prove */, { isMocks: true, mockSleep: proveDelay });
|
|
1572
1556
|
this.fireStepStart("verify" /* Verify */);
|
|
1573
1557
|
await sleep(verifyDelay);
|
|
1574
|
-
const
|
|
1558
|
+
const result = await cofheMocksZkVerifySign(
|
|
1575
1559
|
this.inputItems,
|
|
1576
1560
|
this.account,
|
|
1577
1561
|
this.securityZone,
|
|
1562
|
+
this.consumingContract,
|
|
1578
1563
|
this.publicClient,
|
|
1579
1564
|
this.walletClient,
|
|
1580
1565
|
this.zkvWalletClient
|
|
1581
1566
|
);
|
|
1582
|
-
const encryptedInputs = signedResults.map(({ ct_hash, signature }, index) => ({
|
|
1583
|
-
ctHash: BigInt(ct_hash),
|
|
1584
|
-
securityZone: this.securityZone,
|
|
1585
|
-
utype: this.inputItems[index].utype,
|
|
1586
|
-
signature
|
|
1587
|
-
}));
|
|
1588
1567
|
this.fireStepEnd("verify" /* Verify */, { isMocks: true, mockSleep: verifyDelay });
|
|
1589
|
-
return
|
|
1568
|
+
return result;
|
|
1590
1569
|
}
|
|
1591
1570
|
/**
|
|
1592
1571
|
* In the production context, perform a true encryption with the CoFHE coprocessor.
|
|
@@ -1594,6 +1573,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
|
|
|
1594
1573
|
async productionExecute() {
|
|
1595
1574
|
this.assertAccount();
|
|
1596
1575
|
this.assertChainId();
|
|
1576
|
+
this.assertConsumingContract();
|
|
1597
1577
|
this.fireStepStart("initTfhe" /* InitTfhe */);
|
|
1598
1578
|
const tfheInitializationExecuted = await this.initTfheOrThrow();
|
|
1599
1579
|
this.fireStepEnd("initTfhe" /* InitTfhe */, { tfheInitializationExecuted });
|
|
@@ -1628,26 +1608,24 @@ var EncryptInputsBuilder = class extends BaseBuilder {
|
|
|
1628
1608
|
});
|
|
1629
1609
|
this.fireStepStart("verify" /* Verify */);
|
|
1630
1610
|
const zkVerifierUrl = await this.getZkVerifierUrl();
|
|
1631
|
-
const
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
})
|
|
1611
|
+
const result = await zkVerifyBatch(
|
|
1612
|
+
zkVerifierUrl,
|
|
1613
|
+
proof,
|
|
1614
|
+
this.account,
|
|
1615
|
+
this.securityZone,
|
|
1616
|
+
this.chainId,
|
|
1617
|
+
this.consumingContract
|
|
1639
1618
|
);
|
|
1640
1619
|
this.fireStepEnd("verify" /* Verify */);
|
|
1641
|
-
return
|
|
1620
|
+
return result;
|
|
1642
1621
|
}
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
return [...hashes, proof];
|
|
1622
|
+
/**
|
|
1623
|
+
* Converts a batch-verified result (per-item ctHash/ctType + one shared signature) into the
|
|
1624
|
+
* tuple returned by `execute()`: per-item hashes in input order, followed by the single signature.
|
|
1625
|
+
*/
|
|
1626
|
+
buildBatchResult(result) {
|
|
1627
|
+
const hashes = result.outputs.map((output) => "0x" + BigInt(output.ct_hash).toString(16).padStart(64, "0"));
|
|
1628
|
+
return [...hashes, result.signature];
|
|
1651
1629
|
}
|
|
1652
1630
|
/**
|
|
1653
1631
|
* Final step of the encryption process. MUST BE CALLED LAST IN THE CHAIN.
|
|
@@ -1669,102 +1647,329 @@ var EncryptInputsBuilder = class extends BaseBuilder {
|
|
|
1669
1647
|
* @returns The encrypted inputs.
|
|
1670
1648
|
*/
|
|
1671
1649
|
async execute() {
|
|
1672
|
-
let
|
|
1650
|
+
let result;
|
|
1673
1651
|
if (this.chainId === hardhat.id)
|
|
1674
|
-
|
|
1652
|
+
result = await this.mocksExecute();
|
|
1675
1653
|
else
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
return this.structsToHashPlusProof(items);
|
|
1679
|
-
return items;
|
|
1654
|
+
result = await this.productionExecute();
|
|
1655
|
+
return this.buildBatchResult(result);
|
|
1680
1656
|
}
|
|
1681
1657
|
};
|
|
1682
|
-
var
|
|
1658
|
+
var ACP_VALIDATOR_ABI = parseAbi([
|
|
1659
|
+
"function revokeSingle(uint256 id)",
|
|
1660
|
+
"function revokeAllExisting()",
|
|
1661
|
+
"function disabled(address issuer, uint256 id) view returns (bool)"
|
|
1662
|
+
]);
|
|
1663
|
+
var storeACP = async (acp, publicClient, walletClient) => {
|
|
1683
1664
|
const chainId = await publicClient.getChainId();
|
|
1684
1665
|
const account = walletClient.account.address;
|
|
1685
|
-
|
|
1686
|
-
permitStore.setActivePermitHash(chainId, account, permit.hash);
|
|
1666
|
+
acpStore.setACP(chainId, account, acp);
|
|
1687
1667
|
};
|
|
1688
|
-
var
|
|
1689
|
-
|
|
1690
|
-
await
|
|
1691
|
-
|
|
1668
|
+
var storeActiveACP = async (acp, publicClient, walletClient) => {
|
|
1669
|
+
await storeACP(acp, publicClient, walletClient);
|
|
1670
|
+
const chainId = await publicClient.getChainId();
|
|
1671
|
+
const account = walletClient.account.address;
|
|
1672
|
+
acpStore.setActiveACPHash(chainId, account, acp.hash);
|
|
1673
|
+
};
|
|
1674
|
+
var createACPWithSign = async (options, publicClient, walletClient, acpMethod, activate = true) => {
|
|
1675
|
+
const acp = await acpMethod(options, publicClient, walletClient);
|
|
1676
|
+
if (activate) {
|
|
1677
|
+
await storeActiveACP(acp, publicClient, walletClient);
|
|
1678
|
+
} else {
|
|
1679
|
+
await storeACP(acp, publicClient, walletClient);
|
|
1680
|
+
}
|
|
1681
|
+
return acp;
|
|
1692
1682
|
};
|
|
1693
1683
|
var createSelf = async (options, publicClient, walletClient) => {
|
|
1694
|
-
return
|
|
1684
|
+
return createACPWithSign(options, publicClient, walletClient, ACPUtils.createSelfAndSign);
|
|
1695
1685
|
};
|
|
1696
1686
|
var createSharing = async (options, publicClient, walletClient) => {
|
|
1697
|
-
return
|
|
1687
|
+
return createACPWithSign(options, publicClient, walletClient, ACPUtils.createSharingAndSign, false);
|
|
1698
1688
|
};
|
|
1699
1689
|
var importShared = async (options, publicClient, walletClient) => {
|
|
1700
|
-
return
|
|
1690
|
+
return createACPWithSign(options, publicClient, walletClient, ACPUtils.importSharedAndSign);
|
|
1701
1691
|
};
|
|
1702
|
-
var getHash = (
|
|
1703
|
-
return
|
|
1692
|
+
var getHash = (acp) => {
|
|
1693
|
+
return ACPUtils.getHash(acp);
|
|
1704
1694
|
};
|
|
1705
|
-
var exportShared = (
|
|
1706
|
-
return
|
|
1695
|
+
var exportShared = (acp) => {
|
|
1696
|
+
return ACPUtils.export(acp);
|
|
1707
1697
|
};
|
|
1708
|
-
var serialize = (
|
|
1709
|
-
return
|
|
1698
|
+
var serialize = (acp) => {
|
|
1699
|
+
return ACPUtils.serialize(acp);
|
|
1710
1700
|
};
|
|
1711
1701
|
var deserialize = (serialized) => {
|
|
1712
|
-
return
|
|
1702
|
+
return ACPUtils.deserialize(serialized);
|
|
1713
1703
|
};
|
|
1714
|
-
var
|
|
1715
|
-
return
|
|
1704
|
+
var getACP = (chainId, account, hash) => {
|
|
1705
|
+
return acpStore.getACP(chainId, account, hash);
|
|
1716
1706
|
};
|
|
1717
|
-
var
|
|
1718
|
-
return
|
|
1707
|
+
var getACPs = (chainId, account) => {
|
|
1708
|
+
return acpStore.getACPs(chainId, account);
|
|
1719
1709
|
};
|
|
1720
|
-
var
|
|
1721
|
-
return
|
|
1710
|
+
var getActiveACP = (chainId, account) => {
|
|
1711
|
+
return acpStore.getActiveACP(chainId, account);
|
|
1722
1712
|
};
|
|
1723
|
-
var
|
|
1724
|
-
return
|
|
1713
|
+
var getActiveACPHash = (chainId, account) => {
|
|
1714
|
+
return acpStore.getActiveACPHash(chainId, account);
|
|
1725
1715
|
};
|
|
1726
|
-
var
|
|
1727
|
-
|
|
1716
|
+
var selectActiveACP = (chainId, account, hash) => {
|
|
1717
|
+
acpStore.setActiveACPHash(chainId, account, hash);
|
|
1728
1718
|
};
|
|
1729
|
-
var
|
|
1719
|
+
var getOrCreateSelfACP = async (publicClient, walletClient, chainId, account, options) => {
|
|
1730
1720
|
const _chainId = chainId ?? await publicClient.getChainId();
|
|
1731
1721
|
const _account = account ?? walletClient.account.address;
|
|
1732
|
-
const
|
|
1733
|
-
if (
|
|
1734
|
-
return
|
|
1722
|
+
const activeACP = await getActiveACP(_chainId, _account);
|
|
1723
|
+
if (activeACP && activeACP.type === "self" && ACPUtils.isValid(activeACP).valid) {
|
|
1724
|
+
return activeACP;
|
|
1735
1725
|
}
|
|
1736
|
-
return createSelf(options ?? { issuer: _account, name: "Autogenerated Self
|
|
1726
|
+
return createSelf(options ?? { issuer: _account, name: "Autogenerated Self ACP" }, publicClient, walletClient);
|
|
1737
1727
|
};
|
|
1738
|
-
var
|
|
1728
|
+
var getOrCreateSharingACP = async (publicClient, walletClient, options, chainId, account) => {
|
|
1739
1729
|
const _chainId = chainId ?? await publicClient.getChainId();
|
|
1740
1730
|
const _account = account ?? walletClient.account.address;
|
|
1741
|
-
const
|
|
1742
|
-
if (
|
|
1743
|
-
return
|
|
1731
|
+
const activeACP = await getActiveACP(_chainId, _account);
|
|
1732
|
+
if (activeACP && activeACP.type === "sharing" && ACPUtils.isValid(activeACP).valid) {
|
|
1733
|
+
return activeACP;
|
|
1744
1734
|
}
|
|
1745
1735
|
return createSharing(options, publicClient, walletClient);
|
|
1746
1736
|
};
|
|
1747
|
-
var
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1737
|
+
var applyACPDefaults = (options, acpConfig, chainId) => {
|
|
1738
|
+
const result = { ...options };
|
|
1739
|
+
const defaultRevoker = acpConfig?.defaultRevoker?.[chainId];
|
|
1740
|
+
const hasValidatorOptions = options.revokerData != null || options.revokerContract != null;
|
|
1741
|
+
if (defaultRevoker != null && !hasValidatorOptions) {
|
|
1742
|
+
result.revokerContract = defaultRevoker;
|
|
1743
|
+
result.revokerData = Math.round(Date.now() / 1e3) - 60;
|
|
1744
|
+
}
|
|
1745
|
+
const defaultContracts = acpConfig?.defaultContractScopes?.[chainId];
|
|
1746
|
+
const hasScopeOptions = options.scope != null || options.contracts != null || options.handles != null;
|
|
1747
|
+
if (defaultContracts != null && defaultContracts.length > 0 && !hasScopeOptions) {
|
|
1748
|
+
result.contracts = defaultContracts;
|
|
1749
|
+
}
|
|
1750
|
+
return result;
|
|
1751
|
+
};
|
|
1752
|
+
var ACL_SERVED_ADDRESSES_ABI = parseAbi([
|
|
1753
|
+
"function acl() view returns (address)",
|
|
1754
|
+
"function defaultRevokerContract() view returns (address)",
|
|
1755
|
+
"function shareRegistry() view returns (address)"
|
|
1756
|
+
]);
|
|
1757
|
+
var aclServedAddressesCache = /* @__PURE__ */ new Map();
|
|
1758
|
+
var clearAclServedAddresses = () => aclServedAddressesCache.clear();
|
|
1759
|
+
var getAclServedAddresses = async (publicClient, chainId) => {
|
|
1760
|
+
const cached = aclServedAddressesCache.get(chainId);
|
|
1761
|
+
if (cached != null)
|
|
1762
|
+
return cached;
|
|
1763
|
+
let aclAddress;
|
|
1764
|
+
try {
|
|
1765
|
+
aclAddress = await publicClient.readContract({
|
|
1766
|
+
address: TASK_MANAGER_ADDRESS,
|
|
1767
|
+
abi: ACL_SERVED_ADDRESSES_ABI,
|
|
1768
|
+
functionName: "acl"
|
|
1769
|
+
});
|
|
1770
|
+
} catch {
|
|
1771
|
+
return {};
|
|
1772
|
+
}
|
|
1773
|
+
const [defaultRevoker, shareRegistry] = await Promise.all([
|
|
1774
|
+
publicClient.readContract({ address: aclAddress, abi: ACL_SERVED_ADDRESSES_ABI, functionName: "defaultRevokerContract" }).catch(() => void 0),
|
|
1775
|
+
publicClient.readContract({ address: aclAddress, abi: ACL_SERVED_ADDRESSES_ABI, functionName: "shareRegistry" }).catch(() => void 0)
|
|
1776
|
+
]);
|
|
1777
|
+
const resolved = {
|
|
1778
|
+
defaultRevoker: defaultRevoker != null && defaultRevoker !== zeroAddress ? defaultRevoker : void 0,
|
|
1779
|
+
shareRegistry: shareRegistry != null && shareRegistry !== zeroAddress ? shareRegistry : void 0
|
|
1780
|
+
};
|
|
1781
|
+
aclServedAddressesCache.set(chainId, resolved);
|
|
1782
|
+
return resolved;
|
|
1783
|
+
};
|
|
1784
|
+
var applyACPDefaultsFromChain = async (options, acpConfig, publicClient, chainId) => {
|
|
1785
|
+
const hasExplicitRevoker = acpConfig?.defaultRevoker?.[chainId] != null || options.revokerData != null || options.revokerContract != null;
|
|
1786
|
+
if (hasExplicitRevoker)
|
|
1787
|
+
return applyACPDefaults(options, acpConfig, chainId);
|
|
1788
|
+
const served = await getAclServedAddresses(publicClient, chainId);
|
|
1789
|
+
const effectiveConfig = served.defaultRevoker != null ? { ...acpConfig, defaultRevoker: { ...acpConfig?.defaultRevoker, [chainId]: served.defaultRevoker } } : acpConfig;
|
|
1790
|
+
return applyACPDefaults(options, effectiveConfig, chainId);
|
|
1791
|
+
};
|
|
1792
|
+
var revokeACP = async (acp, walletClient) => {
|
|
1793
|
+
if (acp.revokerContract === zeroAddress || acp.revokerData === 0) {
|
|
1794
|
+
throw new Error("ACP is not revocable: it has no revoker (revokerContract/revokerData unset)");
|
|
1795
|
+
}
|
|
1796
|
+
if (walletClient.account == null)
|
|
1797
|
+
throw new Error("Missing walletClient account");
|
|
1798
|
+
if (walletClient.account.address.toLowerCase() !== acp.issuer.toLowerCase()) {
|
|
1799
|
+
throw new Error("Only the acp issuer can revoke it");
|
|
1800
|
+
}
|
|
1801
|
+
return walletClient.writeContract({
|
|
1802
|
+
address: acp.revokerContract,
|
|
1803
|
+
abi: ACP_VALIDATOR_ABI,
|
|
1804
|
+
functionName: "revokeSingle",
|
|
1805
|
+
args: [BigInt(acp.revokerData)],
|
|
1806
|
+
account: walletClient.account,
|
|
1807
|
+
chain: walletClient.chain
|
|
1808
|
+
});
|
|
1809
|
+
};
|
|
1810
|
+
var revokeAllACPs = async (walletClient, publicClient, revokerContract) => {
|
|
1811
|
+
if (walletClient.account == null)
|
|
1812
|
+
throw new Error("Missing walletClient account");
|
|
1813
|
+
let revoker = revokerContract;
|
|
1814
|
+
if (revoker == null) {
|
|
1815
|
+
const chainId = await publicClient.getChainId();
|
|
1816
|
+
const active = getActiveACP(chainId, walletClient.account.address);
|
|
1817
|
+
revoker = active?.revokerContract;
|
|
1818
|
+
}
|
|
1819
|
+
if (revoker == null || revoker === zeroAddress) {
|
|
1820
|
+
throw new Error("No revoker contract: pass `revokerContract` or activate a revocable acp first");
|
|
1821
|
+
}
|
|
1822
|
+
return walletClient.writeContract({
|
|
1823
|
+
address: revoker,
|
|
1824
|
+
abi: ACP_VALIDATOR_ABI,
|
|
1825
|
+
functionName: "revokeAllExisting",
|
|
1826
|
+
args: [],
|
|
1827
|
+
account: walletClient.account,
|
|
1828
|
+
chain: walletClient.chain
|
|
1829
|
+
});
|
|
1830
|
+
};
|
|
1831
|
+
var isACPRevoked = async (acp, publicClient) => {
|
|
1832
|
+
if (acp.revokerContract === zeroAddress || acp.revokerData === 0)
|
|
1833
|
+
return false;
|
|
1834
|
+
return publicClient.readContract({
|
|
1835
|
+
address: acp.revokerContract,
|
|
1836
|
+
abi: ACP_VALIDATOR_ABI,
|
|
1837
|
+
functionName: "disabled",
|
|
1838
|
+
args: [acp.issuer, BigInt(acp.revokerData)]
|
|
1839
|
+
});
|
|
1840
|
+
};
|
|
1841
|
+
var ACP_SHARE_REGISTRY_ABI = parseAbi([
|
|
1842
|
+
"struct ACP { address issuer; uint64 expiration; address recipient; uint256 revokerData; address revokerContract; uint8 scope; address[] contracts; bytes32[] handles; bytes32 sealingKey; bytes issuerSignature; bytes recipientSignature; }",
|
|
1843
|
+
"function share(ACP calldata acp) external returns (bytes32)",
|
|
1844
|
+
"function removeShare(bytes32 shareId) external",
|
|
1845
|
+
"function sharesFor(address recipient) external view returns (ACP[] memory)",
|
|
1846
|
+
"function getShare(bytes32 shareId) external view returns (ACP memory)",
|
|
1847
|
+
"function isShareValid(bytes32 shareId) external view returns (bool)"
|
|
1848
|
+
]);
|
|
1849
|
+
var ACP_TUPLE = [
|
|
1850
|
+
{
|
|
1851
|
+
type: "tuple",
|
|
1852
|
+
components: [
|
|
1853
|
+
{ name: "issuer", type: "address" },
|
|
1854
|
+
{ name: "expiration", type: "uint64" },
|
|
1855
|
+
{ name: "recipient", type: "address" },
|
|
1856
|
+
{ name: "revokerData", type: "uint256" },
|
|
1857
|
+
{ name: "revokerContract", type: "address" },
|
|
1858
|
+
{ name: "scope", type: "uint8" },
|
|
1859
|
+
{ name: "contracts", type: "address[]" },
|
|
1860
|
+
{ name: "handles", type: "bytes32[]" },
|
|
1861
|
+
{ name: "sealingKey", type: "bytes32" },
|
|
1862
|
+
{ name: "issuerSignature", type: "bytes" },
|
|
1863
|
+
{ name: "recipientSignature", type: "bytes" }
|
|
1864
|
+
]
|
|
1865
|
+
}
|
|
1866
|
+
];
|
|
1867
|
+
var ZERO_BYTES32 = `0x${"0".repeat(64)}`;
|
|
1868
|
+
var toChainShare = (acp) => {
|
|
1869
|
+
const pub = ACPUtils.getPublic(acp, true);
|
|
1870
|
+
return {
|
|
1871
|
+
...pub,
|
|
1872
|
+
expiration: BigInt(pub.expiration),
|
|
1873
|
+
revokerData: BigInt(pub.revokerData),
|
|
1874
|
+
sealingKey: ZERO_BYTES32,
|
|
1875
|
+
recipientSignature: "0x"
|
|
1876
|
+
};
|
|
1877
|
+
};
|
|
1878
|
+
var computeShareId = (acp) => {
|
|
1879
|
+
const p = toChainShare(acp);
|
|
1880
|
+
return keccak256(encodeAbiParameters(ACP_TUPLE, [p]));
|
|
1881
|
+
};
|
|
1882
|
+
var shareOnChain = async (acp, walletClient, registry) => {
|
|
1883
|
+
if (acp.type !== "sharing") {
|
|
1884
|
+
throw new Error(`Cannot share a '${acp.type}' ACP on-chain \u2014 only 'sharing' ACPs are shareable.`);
|
|
1885
|
+
}
|
|
1886
|
+
if (acp.issuerSignature === "0x") {
|
|
1887
|
+
throw new Error("Cannot share an unsigned sharing ACP \u2014 sign it first.");
|
|
1888
|
+
}
|
|
1889
|
+
if (walletClient.account == null)
|
|
1890
|
+
throw new Error("Missing walletClient account");
|
|
1891
|
+
if (walletClient.account.address.toLowerCase() !== acp.issuer.toLowerCase()) {
|
|
1892
|
+
throw new Error("Only the ACP issuer can share it on-chain");
|
|
1893
|
+
}
|
|
1894
|
+
const txHash = await walletClient.writeContract({
|
|
1895
|
+
address: registry,
|
|
1896
|
+
abi: ACP_SHARE_REGISTRY_ABI,
|
|
1897
|
+
functionName: "share",
|
|
1898
|
+
args: [toChainShare(acp)],
|
|
1899
|
+
account: walletClient.account,
|
|
1900
|
+
chain: walletClient.chain ?? null
|
|
1901
|
+
});
|
|
1902
|
+
return { txHash, shareId: computeShareId(acp) };
|
|
1903
|
+
};
|
|
1904
|
+
var getIncomingShares = async (publicClient, registry, recipient) => {
|
|
1905
|
+
const raw = await publicClient.readContract({
|
|
1906
|
+
address: registry,
|
|
1907
|
+
abi: ACP_SHARE_REGISTRY_ABI,
|
|
1908
|
+
functionName: "sharesFor",
|
|
1909
|
+
args: [recipient]
|
|
1910
|
+
});
|
|
1911
|
+
return raw.map((s) => ({
|
|
1912
|
+
shareId: keccak256(encodeAbiParameters(ACP_TUPLE, [s])),
|
|
1913
|
+
issuer: s.issuer,
|
|
1914
|
+
expiration: Number(s.expiration),
|
|
1915
|
+
recipient: s.recipient,
|
|
1916
|
+
revokerData: Number(s.revokerData),
|
|
1917
|
+
revokerContract: s.revokerContract,
|
|
1918
|
+
scope: Number(s.scope),
|
|
1919
|
+
contracts: [...s.contracts],
|
|
1920
|
+
handles: [...s.handles],
|
|
1921
|
+
issuerSignature: s.issuerSignature
|
|
1922
|
+
}));
|
|
1923
|
+
};
|
|
1924
|
+
var importFromChain = async (share, publicClient, walletClient) => {
|
|
1925
|
+
const { shareId: _shareId, ...options } = share;
|
|
1926
|
+
return importShared({ ...options, type: "sharing" }, publicClient, walletClient);
|
|
1927
|
+
};
|
|
1928
|
+
var removeShareOnChain = async (shareId, walletClient, registry) => {
|
|
1929
|
+
if (walletClient.account == null)
|
|
1930
|
+
throw new Error("Missing walletClient account");
|
|
1931
|
+
return walletClient.writeContract({
|
|
1932
|
+
address: registry,
|
|
1933
|
+
abi: ACP_SHARE_REGISTRY_ABI,
|
|
1934
|
+
functionName: "removeShare",
|
|
1935
|
+
args: [shareId],
|
|
1936
|
+
account: walletClient.account,
|
|
1937
|
+
chain: walletClient.chain ?? null
|
|
1938
|
+
});
|
|
1939
|
+
};
|
|
1940
|
+
var removeACP = async (chainId, account, hash) => acpStore.removeACP(chainId, account, hash);
|
|
1941
|
+
var removeActiveACP = async (chainId, account) => acpStore.removeActiveACPHash(chainId, account);
|
|
1942
|
+
var acps = {
|
|
1943
|
+
getSnapshot: acpStore.store.getState,
|
|
1944
|
+
subscribe: acpStore.store.subscribe,
|
|
1752
1945
|
createSelf,
|
|
1753
1946
|
createSharing,
|
|
1754
1947
|
importShared,
|
|
1755
|
-
|
|
1756
|
-
|
|
1948
|
+
getOrCreateSelfACP,
|
|
1949
|
+
getOrCreateSharingACP,
|
|
1757
1950
|
getHash,
|
|
1758
1951
|
export: exportShared,
|
|
1759
1952
|
serialize,
|
|
1760
1953
|
deserialize,
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1954
|
+
getACP,
|
|
1955
|
+
getACPs,
|
|
1956
|
+
getActiveACP,
|
|
1957
|
+
getActiveACPHash,
|
|
1958
|
+
removeACP,
|
|
1959
|
+
selectActiveACP,
|
|
1960
|
+
removeActiveACP,
|
|
1961
|
+
revokeACP,
|
|
1962
|
+
revokeAllACPs,
|
|
1963
|
+
isACPRevoked,
|
|
1964
|
+
shareOnChain,
|
|
1965
|
+
getIncomingShares,
|
|
1966
|
+
importFromChain,
|
|
1967
|
+
removeShareOnChain,
|
|
1968
|
+
computeShareId,
|
|
1969
|
+
applyACPDefaults,
|
|
1970
|
+
applyACPDefaultsFromChain,
|
|
1971
|
+
getAclServedAddresses,
|
|
1972
|
+
clearAclServedAddresses
|
|
1768
1973
|
};
|
|
1769
1974
|
function uint160ToAddress(uint160) {
|
|
1770
1975
|
const hexStr = uint160.toString(16).padStart(40, "0");
|
|
@@ -1827,13 +2032,16 @@ var MockThresholdNetworkAbi = [
|
|
|
1827
2032
|
{
|
|
1828
2033
|
name: "permission",
|
|
1829
2034
|
type: "tuple",
|
|
1830
|
-
internalType: "struct
|
|
2035
|
+
internalType: "struct ACPermission",
|
|
1831
2036
|
components: [
|
|
1832
2037
|
{ name: "issuer", type: "address", internalType: "address" },
|
|
1833
2038
|
{ name: "expiration", type: "uint64", internalType: "uint64" },
|
|
1834
2039
|
{ name: "recipient", type: "address", internalType: "address" },
|
|
1835
|
-
{ name: "
|
|
1836
|
-
{ name: "
|
|
2040
|
+
{ name: "revokerData", type: "uint256", internalType: "uint256" },
|
|
2041
|
+
{ name: "revokerContract", type: "address", internalType: "address" },
|
|
2042
|
+
{ name: "scope", type: "uint8", internalType: "uint8" },
|
|
2043
|
+
{ name: "contracts", type: "address[]", internalType: "address[]" },
|
|
2044
|
+
{ name: "handles", type: "bytes32[]", internalType: "bytes32[]" },
|
|
1837
2045
|
{ name: "sealingKey", type: "bytes32", internalType: "bytes32" },
|
|
1838
2046
|
{ name: "issuerSignature", type: "bytes", internalType: "bytes" },
|
|
1839
2047
|
{ name: "recipientSignature", type: "bytes", internalType: "bytes" }
|
|
@@ -1856,13 +2064,16 @@ var MockThresholdNetworkAbi = [
|
|
|
1856
2064
|
{
|
|
1857
2065
|
name: "permission",
|
|
1858
2066
|
type: "tuple",
|
|
1859
|
-
internalType: "struct
|
|
2067
|
+
internalType: "struct ACPermission",
|
|
1860
2068
|
components: [
|
|
1861
2069
|
{ name: "issuer", type: "address", internalType: "address" },
|
|
1862
2070
|
{ name: "expiration", type: "uint64", internalType: "uint64" },
|
|
1863
2071
|
{ name: "recipient", type: "address", internalType: "address" },
|
|
1864
|
-
{ name: "
|
|
1865
|
-
{ name: "
|
|
2072
|
+
{ name: "revokerData", type: "uint256", internalType: "uint256" },
|
|
2073
|
+
{ name: "revokerContract", type: "address", internalType: "address" },
|
|
2074
|
+
{ name: "scope", type: "uint8", internalType: "uint8" },
|
|
2075
|
+
{ name: "contracts", type: "address[]", internalType: "address[]" },
|
|
2076
|
+
{ name: "handles", type: "bytes32[]", internalType: "bytes32[]" },
|
|
1866
2077
|
{ name: "sealingKey", type: "bytes32", internalType: "bytes32" },
|
|
1867
2078
|
{ name: "issuerSignature", type: "bytes", internalType: "bytes" },
|
|
1868
2079
|
{ name: "recipientSignature", type: "bytes", internalType: "bytes" }
|
|
@@ -1927,19 +2138,22 @@ var MockThresholdNetworkAbi = [
|
|
|
1927
2138
|
},
|
|
1928
2139
|
{
|
|
1929
2140
|
type: "function",
|
|
1930
|
-
name: "
|
|
2141
|
+
name: "decryptForTxWithACP",
|
|
1931
2142
|
inputs: [
|
|
1932
2143
|
{ name: "ctHash", type: "uint256", internalType: "uint256" },
|
|
1933
2144
|
{
|
|
1934
2145
|
name: "permission",
|
|
1935
2146
|
type: "tuple",
|
|
1936
|
-
internalType: "struct
|
|
2147
|
+
internalType: "struct ACPermission",
|
|
1937
2148
|
components: [
|
|
1938
2149
|
{ name: "issuer", type: "address", internalType: "address" },
|
|
1939
2150
|
{ name: "expiration", type: "uint64", internalType: "uint64" },
|
|
1940
2151
|
{ name: "recipient", type: "address", internalType: "address" },
|
|
1941
|
-
{ name: "
|
|
1942
|
-
{ name: "
|
|
2152
|
+
{ name: "revokerData", type: "uint256", internalType: "uint256" },
|
|
2153
|
+
{ name: "revokerContract", type: "address", internalType: "address" },
|
|
2154
|
+
{ name: "scope", type: "uint8", internalType: "uint8" },
|
|
2155
|
+
{ name: "contracts", type: "address[]", internalType: "address[]" },
|
|
2156
|
+
{ name: "handles", type: "bytes32[]", internalType: "bytes32[]" },
|
|
1943
2157
|
{ name: "sealingKey", type: "bytes32", internalType: "bytes32" },
|
|
1944
2158
|
{ name: "issuerSignature", type: "bytes", internalType: "bytes" },
|
|
1945
2159
|
{ name: "recipientSignature", type: "bytes", internalType: "bytes" }
|
|
@@ -1955,7 +2169,7 @@ var MockThresholdNetworkAbi = [
|
|
|
1955
2169
|
},
|
|
1956
2170
|
{
|
|
1957
2171
|
type: "function",
|
|
1958
|
-
name: "
|
|
2172
|
+
name: "decryptForTxWithoutACP",
|
|
1959
2173
|
inputs: [{ name: "ctHash", type: "uint256", internalType: "uint256" }],
|
|
1960
2174
|
outputs: [
|
|
1961
2175
|
{ name: "allowed", type: "bool", internalType: "bool" },
|
|
@@ -1967,12 +2181,12 @@ var MockThresholdNetworkAbi = [
|
|
|
1967
2181
|
];
|
|
1968
2182
|
|
|
1969
2183
|
// core/decrypt/cofheMocksDecryptForView.ts
|
|
1970
|
-
async function cofheMocksDecryptForView(ctHash, utype,
|
|
1971
|
-
const
|
|
2184
|
+
async function cofheMocksDecryptForView(ctHash, utype, acp, publicClient) {
|
|
2185
|
+
const wireAcp = ACPUtils.getPublic(acp, true);
|
|
1972
2186
|
const permissionWithBigInts = {
|
|
1973
|
-
...
|
|
1974
|
-
expiration: BigInt(
|
|
1975
|
-
|
|
2187
|
+
...wireAcp,
|
|
2188
|
+
expiration: BigInt(wireAcp.expiration),
|
|
2189
|
+
revokerData: BigInt(wireAcp.revokerData)
|
|
1976
2190
|
};
|
|
1977
2191
|
const [allowed, error, result] = await publicClient.readContract({
|
|
1978
2192
|
address: MOCKS_THRESHOLD_NETWORK_ADDRESS,
|
|
@@ -1993,11 +2207,41 @@ async function cofheMocksDecryptForView(ctHash, utype, permit, publicClient) {
|
|
|
1993
2207
|
});
|
|
1994
2208
|
}
|
|
1995
2209
|
const sealedBigInt = BigInt(result);
|
|
1996
|
-
const sealingKeyBigInt = BigInt(
|
|
2210
|
+
const sealingKeyBigInt = BigInt(acp.sealingKey);
|
|
1997
2211
|
const unsealed = sealedBigInt ^ sealingKeyBigInt;
|
|
1998
2212
|
return unsealed;
|
|
1999
2213
|
}
|
|
2000
2214
|
|
|
2215
|
+
// core/debug.ts
|
|
2216
|
+
var interceptors = {};
|
|
2217
|
+
function setCofheDebugInterceptors(next) {
|
|
2218
|
+
interceptors.onRequest = next?.onRequest;
|
|
2219
|
+
interceptors.onResponse = next?.onResponse;
|
|
2220
|
+
}
|
|
2221
|
+
function getCofheDebugInterceptors() {
|
|
2222
|
+
return interceptors;
|
|
2223
|
+
}
|
|
2224
|
+
async function cofheFetch(url, init, ctx = { op: "request" }) {
|
|
2225
|
+
let finalUrl = url;
|
|
2226
|
+
let finalInit = init;
|
|
2227
|
+
if (interceptors.onRequest) {
|
|
2228
|
+
const override = await interceptors.onRequest(finalUrl, finalInit, ctx);
|
|
2229
|
+
if (override) {
|
|
2230
|
+
if (override.url !== void 0)
|
|
2231
|
+
finalUrl = override.url;
|
|
2232
|
+
if (override.init !== void 0)
|
|
2233
|
+
finalInit = override.init;
|
|
2234
|
+
}
|
|
2235
|
+
}
|
|
2236
|
+
let response = await fetch(finalUrl, finalInit);
|
|
2237
|
+
if (interceptors.onResponse) {
|
|
2238
|
+
const replaced = await interceptors.onResponse(response, ctx);
|
|
2239
|
+
if (replaced)
|
|
2240
|
+
response = replaced;
|
|
2241
|
+
}
|
|
2242
|
+
return response;
|
|
2243
|
+
}
|
|
2244
|
+
|
|
2001
2245
|
// core/decrypt/polling.ts
|
|
2002
2246
|
function computeMinuteRampPollIntervalMs(elapsedMs, params) {
|
|
2003
2247
|
const elapsedSeconds = Math.floor(elapsedMs / 1e3);
|
|
@@ -2006,11 +2250,61 @@ function computeMinuteRampPollIntervalMs(elapsedMs, params) {
|
|
|
2006
2250
|
return Math.min(params.maxIntervalMs, Math.max(params.minIntervalMs, intervalMs));
|
|
2007
2251
|
}
|
|
2008
2252
|
|
|
2253
|
+
// core/decrypt/apiError.ts
|
|
2254
|
+
var BACKEND_ERROR_CODE_TO_COFHE_ERROR_CODE = {
|
|
2255
|
+
bad_request: "BAD_REQUEST" /* BadRequest */,
|
|
2256
|
+
unknown_chain: "UNKNOWN_CHAIN" /* UnknownChain */,
|
|
2257
|
+
acp_malformed: "ACP_MALFORMED" /* ACPMalformed */,
|
|
2258
|
+
acp_denied: "ACP_DENIED" /* ACPDenied */,
|
|
2259
|
+
// ACP-era backends fold revoked into denied
|
|
2260
|
+
acp_expired: "ACP_EXPIRED" /* ACPExpired */,
|
|
2261
|
+
acp_invalid: "ACP_INVALID" /* ACPInvalid */,
|
|
2262
|
+
acp_required: "ACP_REQUIRED" /* ACPRequired */,
|
|
2263
|
+
acp_verifier_error: "ACP_VERIFIER_ERROR" /* ACPVerifierError */,
|
|
2264
|
+
acp_verifier_timeout: "ACP_VERIFIER_TIMEOUT" /* ACPVerifierTimeout */,
|
|
2265
|
+
not_publicly_allowed: "NOT_PUBLICLY_ALLOWED" /* NotPubliclyAllowed */,
|
|
2266
|
+
ct_not_found: "CT_NOT_FOUND" /* CtNotFound */,
|
|
2267
|
+
unsupported_security_zone: "UNSUPPORTED_SECURITY_ZONE" /* UnsupportedSecurityZone */,
|
|
2268
|
+
unsupported_type: "UNSUPPORTED_TYPE" /* UnsupportedType */,
|
|
2269
|
+
internal_error: "INTERNAL_ERROR" /* InternalError */,
|
|
2270
|
+
signing_failed: "SIGNING_FAILED" /* SigningFailed */,
|
|
2271
|
+
ct_source_error: "CT_SOURCE_ERROR" /* CtSourceError */,
|
|
2272
|
+
ct_source_timeout: "CT_SOURCE_TIMEOUT" /* CtSourceTimeout */,
|
|
2273
|
+
seal_failed: "SEAL_FAILED" /* SealFailed */
|
|
2274
|
+
};
|
|
2275
|
+
function isBackendApiErrorCode(value) {
|
|
2276
|
+
return value in BACKEND_ERROR_CODE_TO_COFHE_ERROR_CODE;
|
|
2277
|
+
}
|
|
2278
|
+
async function parseApiErrorResponseBody(response) {
|
|
2279
|
+
let errorMessage = `HTTP ${response.status}`;
|
|
2280
|
+
let apiErrorCode;
|
|
2281
|
+
try {
|
|
2282
|
+
const body = await response.json();
|
|
2283
|
+
if (body && typeof body === "object") {
|
|
2284
|
+
const record = body;
|
|
2285
|
+
if (typeof record.error === "string" && record.error.length > 0) {
|
|
2286
|
+
apiErrorCode = record.error;
|
|
2287
|
+
}
|
|
2288
|
+
if (typeof record.error_message === "string" && record.error_message.length > 0) {
|
|
2289
|
+
errorMessage = record.error_message;
|
|
2290
|
+
} else if (typeof record.message === "string" && record.message.length > 0) {
|
|
2291
|
+
errorMessage = record.message;
|
|
2292
|
+
}
|
|
2293
|
+
}
|
|
2294
|
+
} catch {
|
|
2295
|
+
errorMessage = response.statusText || errorMessage;
|
|
2296
|
+
}
|
|
2297
|
+
return { apiErrorCode, errorMessage };
|
|
2298
|
+
}
|
|
2299
|
+
function mapApiErrorCodeToCofheErrorCode(apiErrorCode, fallback) {
|
|
2300
|
+
if (apiErrorCode && isBackendApiErrorCode(apiErrorCode)) {
|
|
2301
|
+
return BACKEND_ERROR_CODE_TO_COFHE_ERROR_CODE[apiErrorCode];
|
|
2302
|
+
}
|
|
2303
|
+
return fallback;
|
|
2304
|
+
}
|
|
2305
|
+
|
|
2009
2306
|
// core/decrypt/submitRetry.ts
|
|
2010
2307
|
var DEFAULT_404_RETRY_TIMEOUT_MS = 1e4;
|
|
2011
|
-
function isRetryableSubmitStatus(status) {
|
|
2012
|
-
return status === 204 || status === 404;
|
|
2013
|
-
}
|
|
2014
2308
|
function normalize404RetryTimeoutMs(params) {
|
|
2015
2309
|
const { timeoutMs, operationLabel, errorCode } = params;
|
|
2016
2310
|
if (timeoutMs === void 0)
|
|
@@ -2027,32 +2321,24 @@ function normalize404RetryTimeoutMs(params) {
|
|
|
2027
2321
|
return timeoutMs;
|
|
2028
2322
|
}
|
|
2029
2323
|
async function classifySubmitResponse(params) {
|
|
2030
|
-
const { response,
|
|
2031
|
-
if (
|
|
2032
|
-
return { kind: "retryable", status:
|
|
2324
|
+
const { response, fallbackErrorCode } = params;
|
|
2325
|
+
if (response.status === 204) {
|
|
2326
|
+
return { kind: "retryable", status: 204 };
|
|
2033
2327
|
}
|
|
2034
2328
|
if (response.ok) {
|
|
2035
2329
|
return { kind: "parse-json" };
|
|
2036
2330
|
}
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
const maybeErrorMessage = extractErrorMessage?.(errorBody);
|
|
2041
|
-
if (typeof maybeErrorMessage === "string" && maybeErrorMessage.length > 0) {
|
|
2042
|
-
errorMessage = maybeErrorMessage;
|
|
2043
|
-
} else if (errorBody && typeof errorBody === "object") {
|
|
2044
|
-
const defaultMessage = errorBody.error_message;
|
|
2045
|
-
const fallbackMessage = errorBody.message;
|
|
2046
|
-
if (typeof defaultMessage === "string" && defaultMessage.length > 0) {
|
|
2047
|
-
errorMessage = defaultMessage;
|
|
2048
|
-
} else if (typeof fallbackMessage === "string" && fallbackMessage.length > 0) {
|
|
2049
|
-
errorMessage = fallbackMessage;
|
|
2050
|
-
}
|
|
2051
|
-
}
|
|
2052
|
-
} catch {
|
|
2053
|
-
errorMessage = response.statusText || errorMessage;
|
|
2331
|
+
const { apiErrorCode, errorMessage } = await parseApiErrorResponseBody(response);
|
|
2332
|
+
if (response.status === 404) {
|
|
2333
|
+
return { kind: "retryable", status: 404, apiErrorMessage: errorMessage };
|
|
2054
2334
|
}
|
|
2055
|
-
return {
|
|
2335
|
+
return {
|
|
2336
|
+
kind: "fatal-http",
|
|
2337
|
+
status: response.status,
|
|
2338
|
+
cofheErrorCode: mapApiErrorCodeToCofheErrorCode(apiErrorCode, fallbackErrorCode),
|
|
2339
|
+
apiErrorCode,
|
|
2340
|
+
errorMessage
|
|
2341
|
+
};
|
|
2056
2342
|
}
|
|
2057
2343
|
function throwIfSubmitRetryTimedOut(params) {
|
|
2058
2344
|
const {
|
|
@@ -2064,12 +2350,14 @@ function throwIfSubmitRetryTimedOut(params) {
|
|
|
2064
2350
|
overallTimeoutMs,
|
|
2065
2351
|
thresholdNetworkUrl,
|
|
2066
2352
|
body,
|
|
2067
|
-
attemptIndex
|
|
2353
|
+
attemptIndex,
|
|
2354
|
+
lastKnownErrorMessage
|
|
2068
2355
|
} = params;
|
|
2069
2356
|
if (status === 404 && elapsedMs > retry404TimeoutMs) {
|
|
2070
2357
|
throw new CofheError({
|
|
2071
|
-
code:
|
|
2072
|
-
|
|
2358
|
+
code: "CT_NOT_FOUND" /* CtNotFound */,
|
|
2359
|
+
apiErrorCode: "ct_not_found",
|
|
2360
|
+
message: `${operationLabel} ciphertext not found after retrying for ${retry404TimeoutMs}ms` + (lastKnownErrorMessage ? `: ${lastKnownErrorMessage}` : ""),
|
|
2073
2361
|
hint: "The ciphertext may not be indexed yet. Increase set404RetryTimeout(...) if the backend is slow to index ciphertexts.",
|
|
2074
2362
|
context: {
|
|
2075
2363
|
thresholdNetworkUrl,
|
|
@@ -2095,6 +2383,62 @@ function throwIfSubmitRetryTimedOut(params) {
|
|
|
2095
2383
|
});
|
|
2096
2384
|
}
|
|
2097
2385
|
}
|
|
2386
|
+
function normalizeTnSignature(signature) {
|
|
2387
|
+
if (typeof signature !== "string") {
|
|
2388
|
+
throw new CofheError({
|
|
2389
|
+
code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
|
|
2390
|
+
message: "decrypt response missing signature",
|
|
2391
|
+
context: {
|
|
2392
|
+
signature
|
|
2393
|
+
}
|
|
2394
|
+
});
|
|
2395
|
+
}
|
|
2396
|
+
const trimmed = signature.trim();
|
|
2397
|
+
if (trimmed.length === 0) {
|
|
2398
|
+
throw new CofheError({
|
|
2399
|
+
code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
|
|
2400
|
+
message: "decrypt response returned empty signature"
|
|
2401
|
+
});
|
|
2402
|
+
}
|
|
2403
|
+
const prefixed = trimmed.startsWith("0x") ? trimmed : `0x${trimmed}`;
|
|
2404
|
+
const parsed = parseSignature(prefixed);
|
|
2405
|
+
return serializeSignature(parsed);
|
|
2406
|
+
}
|
|
2407
|
+
function parseDecryptedBytesToBigInt(decrypted) {
|
|
2408
|
+
if (!Array.isArray(decrypted)) {
|
|
2409
|
+
throw new CofheError({
|
|
2410
|
+
code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
|
|
2411
|
+
message: "decrypt response field <decrypted> must be a byte array",
|
|
2412
|
+
context: {
|
|
2413
|
+
decrypted
|
|
2414
|
+
}
|
|
2415
|
+
});
|
|
2416
|
+
}
|
|
2417
|
+
if (decrypted.length === 0) {
|
|
2418
|
+
throw new CofheError({
|
|
2419
|
+
code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
|
|
2420
|
+
message: "decrypt response field <decrypted> was an empty byte array",
|
|
2421
|
+
context: {
|
|
2422
|
+
decrypted
|
|
2423
|
+
}
|
|
2424
|
+
});
|
|
2425
|
+
}
|
|
2426
|
+
let hex = "";
|
|
2427
|
+
for (const b of decrypted) {
|
|
2428
|
+
if (typeof b !== "number" || !Number.isInteger(b) || b < 0 || b > 255) {
|
|
2429
|
+
throw new CofheError({
|
|
2430
|
+
code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
|
|
2431
|
+
message: "decrypt response field <decrypted> contained a non-byte value",
|
|
2432
|
+
context: {
|
|
2433
|
+
badElement: b,
|
|
2434
|
+
decrypted
|
|
2435
|
+
}
|
|
2436
|
+
});
|
|
2437
|
+
}
|
|
2438
|
+
hex += b.toString(16).padStart(2, "0");
|
|
2439
|
+
}
|
|
2440
|
+
return BigInt(`0x${hex}`);
|
|
2441
|
+
}
|
|
2098
2442
|
|
|
2099
2443
|
// core/decrypt/tnSealOutputV2.ts
|
|
2100
2444
|
var POLL_INTERVAL_MS = 1e3;
|
|
@@ -2157,23 +2501,28 @@ function parseCompletedSealOutputResponse(params) {
|
|
|
2157
2501
|
}
|
|
2158
2502
|
return convertSealedData(sealed);
|
|
2159
2503
|
}
|
|
2160
|
-
async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId,
|
|
2504
|
+
async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, acp, overallStartTime, retry404TimeoutMs, onPoll) {
|
|
2161
2505
|
const body = {
|
|
2162
2506
|
ct_tempkey: BigInt(ctHash).toString(16).padStart(64, "0"),
|
|
2163
2507
|
host_chain_id: chainId,
|
|
2164
|
-
|
|
2508
|
+
acp
|
|
2165
2509
|
};
|
|
2166
2510
|
let attemptIndex = 0;
|
|
2511
|
+
let last404ApiErrorMessage;
|
|
2167
2512
|
for (; ; ) {
|
|
2168
2513
|
let response;
|
|
2169
2514
|
try {
|
|
2170
|
-
response = await
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2515
|
+
response = await cofheFetch(
|
|
2516
|
+
`${thresholdNetworkUrl}/v2/sealoutput`,
|
|
2517
|
+
/*op:sealoutput*/
|
|
2518
|
+
{
|
|
2519
|
+
method: "POST",
|
|
2520
|
+
headers: {
|
|
2521
|
+
"Content-Type": "application/json"
|
|
2522
|
+
},
|
|
2523
|
+
body: JSON.stringify(body)
|
|
2524
|
+
}
|
|
2525
|
+
);
|
|
2177
2526
|
} catch (e) {
|
|
2178
2527
|
throw new CofheError({
|
|
2179
2528
|
code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
|
|
@@ -2187,16 +2536,19 @@ async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, per
|
|
|
2187
2536
|
}
|
|
2188
2537
|
});
|
|
2189
2538
|
}
|
|
2190
|
-
const responseClassification = await classifySubmitResponse({
|
|
2539
|
+
const responseClassification = await classifySubmitResponse({
|
|
2540
|
+
response,
|
|
2541
|
+
fallbackErrorCode: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */
|
|
2542
|
+
});
|
|
2191
2543
|
if (responseClassification.kind === "fatal-http") {
|
|
2192
2544
|
throw new CofheError({
|
|
2193
|
-
code:
|
|
2545
|
+
code: responseClassification.cofheErrorCode,
|
|
2546
|
+
apiErrorCode: responseClassification.apiErrorCode,
|
|
2194
2547
|
message: `sealOutput request failed: ${responseClassification.errorMessage}`,
|
|
2195
2548
|
hint: "Check the threshold network URL and request parameters.",
|
|
2196
2549
|
context: {
|
|
2197
2550
|
thresholdNetworkUrl,
|
|
2198
|
-
status:
|
|
2199
|
-
statusText: response.statusText,
|
|
2551
|
+
status: responseClassification.status,
|
|
2200
2552
|
body,
|
|
2201
2553
|
attemptIndex
|
|
2202
2554
|
}
|
|
@@ -2242,6 +2594,9 @@ async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, per
|
|
|
2242
2594
|
}
|
|
2243
2595
|
});
|
|
2244
2596
|
}
|
|
2597
|
+
if (responseClassification.status === 404) {
|
|
2598
|
+
last404ApiErrorMessage = responseClassification.apiErrorMessage;
|
|
2599
|
+
}
|
|
2245
2600
|
const elapsedMs = Date.now() - overallStartTime;
|
|
2246
2601
|
throwIfSubmitRetryTimedOut({
|
|
2247
2602
|
operationLabel: "sealOutput",
|
|
@@ -2252,7 +2607,8 @@ async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, per
|
|
|
2252
2607
|
overallTimeoutMs: SEAL_OUTPUT_TIMEOUT_MS,
|
|
2253
2608
|
thresholdNetworkUrl,
|
|
2254
2609
|
body,
|
|
2255
|
-
attemptIndex
|
|
2610
|
+
attemptIndex,
|
|
2611
|
+
lastKnownErrorMessage: last404ApiErrorMessage
|
|
2256
2612
|
});
|
|
2257
2613
|
onPoll?.({
|
|
2258
2614
|
operation: "sealoutput",
|
|
@@ -2296,12 +2652,16 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId, overallStart
|
|
|
2296
2652
|
}
|
|
2297
2653
|
let response;
|
|
2298
2654
|
try {
|
|
2299
|
-
response = await
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2655
|
+
response = await cofheFetch(
|
|
2656
|
+
`${thresholdNetworkUrl}/v2/sealoutput/${requestId}`,
|
|
2657
|
+
/*op:sealoutput-poll*/
|
|
2658
|
+
{
|
|
2659
|
+
method: "GET",
|
|
2660
|
+
headers: {
|
|
2661
|
+
"Content-Type": "application/json"
|
|
2662
|
+
}
|
|
2303
2663
|
}
|
|
2304
|
-
|
|
2664
|
+
);
|
|
2305
2665
|
} catch (e) {
|
|
2306
2666
|
throw new CofheError({
|
|
2307
2667
|
code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
|
|
@@ -2326,15 +2686,10 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId, overallStart
|
|
|
2326
2686
|
});
|
|
2327
2687
|
}
|
|
2328
2688
|
if (!response.ok) {
|
|
2329
|
-
|
|
2330
|
-
try {
|
|
2331
|
-
const errorBody = await response.json();
|
|
2332
|
-
errorMessage = errorBody.error_message || errorBody.message || errorMessage;
|
|
2333
|
-
} catch {
|
|
2334
|
-
errorMessage = response.statusText || errorMessage;
|
|
2335
|
-
}
|
|
2689
|
+
const { apiErrorCode, errorMessage } = await parseApiErrorResponseBody(response);
|
|
2336
2690
|
throw new CofheError({
|
|
2337
|
-
code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed
|
|
2691
|
+
code: mapApiErrorCodeToCofheErrorCode(apiErrorCode, "SEAL_OUTPUT_FAILED" /* SealOutputFailed */),
|
|
2692
|
+
apiErrorCode,
|
|
2338
2693
|
message: `sealOutput status poll failed: ${errorMessage}`,
|
|
2339
2694
|
context: {
|
|
2340
2695
|
thresholdNetworkUrl,
|
|
@@ -2378,7 +2733,7 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId, overallStart
|
|
|
2378
2733
|
});
|
|
2379
2734
|
}
|
|
2380
2735
|
async function tnSealOutputV2(params) {
|
|
2381
|
-
const { thresholdNetworkUrl, ctHash, chainId,
|
|
2736
|
+
const { thresholdNetworkUrl, ctHash, chainId, acp, retry404TimeoutMs, onPoll } = params;
|
|
2382
2737
|
const normalized404RetryTimeoutMs = normalize404RetryTimeoutMs({
|
|
2383
2738
|
timeoutMs: retry404TimeoutMs,
|
|
2384
2739
|
operationLabel: "sealOutput",
|
|
@@ -2389,7 +2744,7 @@ async function tnSealOutputV2(params) {
|
|
|
2389
2744
|
thresholdNetworkUrl,
|
|
2390
2745
|
ctHash,
|
|
2391
2746
|
chainId,
|
|
2392
|
-
|
|
2747
|
+
acp,
|
|
2393
2748
|
overallStartTime,
|
|
2394
2749
|
normalized404RetryTimeoutMs,
|
|
2395
2750
|
onPoll
|
|
@@ -2405,8 +2760,8 @@ var DEFAULT_404_RETRY_TIMEOUT_MS2 = 1e4;
|
|
|
2405
2760
|
var DecryptForViewBuilder = class extends BaseBuilder {
|
|
2406
2761
|
ctHash;
|
|
2407
2762
|
utype;
|
|
2408
|
-
|
|
2409
|
-
|
|
2763
|
+
acpHash;
|
|
2764
|
+
acp;
|
|
2410
2765
|
pollCallback;
|
|
2411
2766
|
retry404TimeoutMs = DEFAULT_404_RETRY_TIMEOUT_MS2;
|
|
2412
2767
|
constructor(params) {
|
|
@@ -2420,11 +2775,11 @@ var DecryptForViewBuilder = class extends BaseBuilder {
|
|
|
2420
2775
|
});
|
|
2421
2776
|
this.ctHash = params.ctHash;
|
|
2422
2777
|
this.utype = params.utype;
|
|
2423
|
-
this.
|
|
2424
|
-
this.
|
|
2778
|
+
this.acpHash = params.acpHash;
|
|
2779
|
+
this.acp = params.acp;
|
|
2425
2780
|
}
|
|
2426
2781
|
/**
|
|
2427
|
-
* @param chainId - Chain to decrypt values from. Used to fetch the threshold network URL and use the correct
|
|
2782
|
+
* @param chainId - Chain to decrypt values from. Used to fetch the threshold network URL and use the correct acp.
|
|
2428
2783
|
*
|
|
2429
2784
|
* If not provided, the chainId will be fetched from the connected publicClient.
|
|
2430
2785
|
*
|
|
@@ -2445,7 +2800,7 @@ var DecryptForViewBuilder = class extends BaseBuilder {
|
|
|
2445
2800
|
return this.chainId;
|
|
2446
2801
|
}
|
|
2447
2802
|
/**
|
|
2448
|
-
* @param account - Account to decrypt values from. Used to fetch the correct
|
|
2803
|
+
* @param account - Account to decrypt values from. Used to fetch the correct acp.
|
|
2449
2804
|
*
|
|
2450
2805
|
* If not provided, the account will be fetched from the connected walletClient.
|
|
2451
2806
|
*
|
|
@@ -2482,61 +2837,61 @@ var DecryptForViewBuilder = class extends BaseBuilder {
|
|
|
2482
2837
|
this.retry404TimeoutMs = timeoutMs;
|
|
2483
2838
|
return this;
|
|
2484
2839
|
}
|
|
2485
|
-
|
|
2486
|
-
if (typeof
|
|
2487
|
-
this.
|
|
2488
|
-
this.
|
|
2489
|
-
} else if (
|
|
2490
|
-
this.
|
|
2491
|
-
this.
|
|
2840
|
+
withACP(acpOrACPHash) {
|
|
2841
|
+
if (typeof acpOrACPHash === "string") {
|
|
2842
|
+
this.acpHash = acpOrACPHash;
|
|
2843
|
+
this.acp = void 0;
|
|
2844
|
+
} else if (acpOrACPHash === void 0) {
|
|
2845
|
+
this.acpHash = void 0;
|
|
2846
|
+
this.acp = void 0;
|
|
2492
2847
|
} else {
|
|
2493
|
-
this.
|
|
2494
|
-
this.
|
|
2848
|
+
this.acp = acpOrACPHash;
|
|
2849
|
+
this.acpHash = void 0;
|
|
2495
2850
|
}
|
|
2496
2851
|
return this;
|
|
2497
2852
|
}
|
|
2498
2853
|
/**
|
|
2499
|
-
* @param
|
|
2854
|
+
* @param acpHash - ACP hash to decrypt values from. Used to fetch the correct acp.
|
|
2500
2855
|
*
|
|
2501
|
-
* If not provided, the active
|
|
2502
|
-
* If `
|
|
2856
|
+
* If not provided, the active acp for the chainId and account will be used.
|
|
2857
|
+
* If `setACP()` is called, it will be used regardless of chainId, account, or acpHash.
|
|
2503
2858
|
*
|
|
2504
2859
|
* Example:
|
|
2505
2860
|
* ```typescript
|
|
2506
2861
|
* const unsealed = await client.decryptForView(ctHash, utype)
|
|
2507
|
-
* .
|
|
2862
|
+
* .setACPHash('0x1234567890123456789012345678901234567890')
|
|
2508
2863
|
* .execute();
|
|
2509
2864
|
* ```
|
|
2510
2865
|
*
|
|
2511
2866
|
* @returns The chainable DecryptForViewBuilder instance.
|
|
2512
2867
|
*/
|
|
2513
|
-
/** @deprecated Use `
|
|
2514
|
-
|
|
2515
|
-
return this.
|
|
2868
|
+
/** @deprecated Use `withACP(acpHash)` instead. */
|
|
2869
|
+
setACPHash(acpHash) {
|
|
2870
|
+
return this.withACP(acpHash);
|
|
2516
2871
|
}
|
|
2517
|
-
|
|
2518
|
-
return this.
|
|
2872
|
+
getACPHash() {
|
|
2873
|
+
return this.acpHash;
|
|
2519
2874
|
}
|
|
2520
2875
|
/**
|
|
2521
|
-
* @param
|
|
2876
|
+
* @param acp - ACP to decrypt values with. If provided, it will be used regardless of chainId, account, or acpHash.
|
|
2522
2877
|
*
|
|
2523
|
-
* If not provided, the
|
|
2878
|
+
* If not provided, the acp will be determined by chainId, account, and acpHash.
|
|
2524
2879
|
*
|
|
2525
2880
|
* Example:
|
|
2526
2881
|
* ```typescript
|
|
2527
2882
|
* const unsealed = await client.decryptForView(ctHash, utype)
|
|
2528
|
-
* .
|
|
2883
|
+
* .setACP(acp)
|
|
2529
2884
|
* .execute();
|
|
2530
2885
|
* ```
|
|
2531
2886
|
*
|
|
2532
2887
|
* @returns The chainable DecryptForViewBuilder instance.
|
|
2533
2888
|
*/
|
|
2534
|
-
/** @deprecated Use `
|
|
2535
|
-
|
|
2536
|
-
return this.
|
|
2889
|
+
/** @deprecated Use `withACP(acp)` instead. */
|
|
2890
|
+
setACP(acp) {
|
|
2891
|
+
return this.withACP(acp);
|
|
2537
2892
|
}
|
|
2538
|
-
|
|
2539
|
-
return this.
|
|
2893
|
+
getACP() {
|
|
2894
|
+
return this.acp;
|
|
2540
2895
|
}
|
|
2541
2896
|
async getThresholdNetworkUrl() {
|
|
2542
2897
|
this.assertChainId();
|
|
@@ -2552,77 +2907,77 @@ var DecryptForViewBuilder = class extends BaseBuilder {
|
|
|
2552
2907
|
}
|
|
2553
2908
|
});
|
|
2554
2909
|
}
|
|
2555
|
-
async
|
|
2556
|
-
if (this.
|
|
2557
|
-
return this.
|
|
2910
|
+
async getResolvedACP() {
|
|
2911
|
+
if (this.acp)
|
|
2912
|
+
return this.acp;
|
|
2558
2913
|
this.assertChainId();
|
|
2559
2914
|
this.assertAccount();
|
|
2560
|
-
if (this.
|
|
2561
|
-
const
|
|
2562
|
-
if (!
|
|
2915
|
+
if (this.acpHash) {
|
|
2916
|
+
const acp2 = await acps.getACP(this.chainId, this.account, this.acpHash);
|
|
2917
|
+
if (!acp2) {
|
|
2563
2918
|
throw new CofheError({
|
|
2564
|
-
code: "
|
|
2565
|
-
message: `
|
|
2566
|
-
hint: "Ensure the
|
|
2919
|
+
code: "ACP_NOT_FOUND" /* ACPNotFound */,
|
|
2920
|
+
message: `ACP with hash <${this.acpHash}> not found for account <${this.account}> and chainId <${this.chainId}>`,
|
|
2921
|
+
hint: "Ensure the acp exists and is valid.",
|
|
2567
2922
|
context: {
|
|
2568
2923
|
chainId: this.chainId,
|
|
2569
2924
|
account: this.account,
|
|
2570
|
-
|
|
2925
|
+
acpHash: this.acpHash
|
|
2571
2926
|
}
|
|
2572
2927
|
});
|
|
2573
2928
|
}
|
|
2574
|
-
return
|
|
2929
|
+
return acp2;
|
|
2575
2930
|
}
|
|
2576
|
-
const
|
|
2577
|
-
if (!
|
|
2931
|
+
const acp = await acps.getActiveACP(this.chainId, this.account);
|
|
2932
|
+
if (!acp) {
|
|
2578
2933
|
throw new CofheError({
|
|
2579
|
-
code: "
|
|
2580
|
-
message: `Active
|
|
2581
|
-
hint: "Ensure
|
|
2934
|
+
code: "ACP_NOT_FOUND" /* ACPNotFound */,
|
|
2935
|
+
message: `Active acp not found for chainId <${this.chainId}> and account <${this.account}>`,
|
|
2936
|
+
hint: "Ensure an ACP exists for this account on this chain.",
|
|
2582
2937
|
context: {
|
|
2583
2938
|
chainId: this.chainId,
|
|
2584
2939
|
account: this.account
|
|
2585
2940
|
}
|
|
2586
2941
|
});
|
|
2587
2942
|
}
|
|
2588
|
-
return
|
|
2943
|
+
return acp;
|
|
2589
2944
|
}
|
|
2590
2945
|
/**
|
|
2591
2946
|
* On hardhat, interact with MockZkVerifier contract instead of CoFHE
|
|
2592
2947
|
*/
|
|
2593
|
-
async mocksSealOutput(
|
|
2948
|
+
async mocksSealOutput(acp) {
|
|
2594
2949
|
this.assertPublicClient();
|
|
2595
2950
|
const mocksDecryptDelay = this.config.mocks.decryptDelay;
|
|
2596
2951
|
if (mocksDecryptDelay > 0)
|
|
2597
2952
|
await sleep(mocksDecryptDelay);
|
|
2598
|
-
return cofheMocksDecryptForView(this.ctHash, this.utype,
|
|
2953
|
+
return cofheMocksDecryptForView(this.ctHash, this.utype, acp, this.publicClient);
|
|
2599
2954
|
}
|
|
2600
2955
|
/**
|
|
2601
2956
|
* In the production context, perform a true decryption with the CoFHE coprocessor.
|
|
2602
2957
|
*/
|
|
2603
|
-
async productionSealOutput(
|
|
2958
|
+
async productionSealOutput(acp) {
|
|
2604
2959
|
this.assertChainId();
|
|
2605
2960
|
this.assertPublicClient();
|
|
2606
2961
|
const thresholdNetworkUrl = await this.getThresholdNetworkUrl();
|
|
2607
|
-
const
|
|
2962
|
+
const wireAcp = ACPUtils.getPublic(acp, true);
|
|
2608
2963
|
const sealed = await tnSealOutputV2({
|
|
2609
2964
|
ctHash: this.ctHash,
|
|
2610
2965
|
chainId: this.chainId,
|
|
2611
|
-
|
|
2966
|
+
acp: wireAcp,
|
|
2612
2967
|
thresholdNetworkUrl,
|
|
2613
2968
|
retry404TimeoutMs: this.retry404TimeoutMs,
|
|
2614
2969
|
onPoll: this.pollCallback
|
|
2615
2970
|
});
|
|
2616
|
-
return
|
|
2971
|
+
return ACPUtils.unseal(acp, sealed);
|
|
2617
2972
|
}
|
|
2618
2973
|
/**
|
|
2619
2974
|
* Final step of the decryption process. MUST BE CALLED LAST IN THE CHAIN.
|
|
2620
2975
|
*
|
|
2621
2976
|
* This will:
|
|
2622
|
-
* - Use
|
|
2623
|
-
* - Check
|
|
2624
|
-
* - Call CoFHE `/sealoutput` with the
|
|
2625
|
-
* - Unseal the sealed item with the
|
|
2977
|
+
* - Use an ACP based on provided acp OR chainId + account + acpHash
|
|
2978
|
+
* - Check acp validity
|
|
2979
|
+
* - Call CoFHE `/sealoutput` with the acp, which returns a sealed (encrypted) item
|
|
2980
|
+
* - Unseal the sealed item with the acp
|
|
2626
2981
|
* - Return the unsealed item
|
|
2627
2982
|
*
|
|
2628
2983
|
* Example:
|
|
@@ -2630,7 +2985,7 @@ var DecryptForViewBuilder = class extends BaseBuilder {
|
|
|
2630
2985
|
* const unsealed = await client.decryptForView(ctHash, utype)
|
|
2631
2986
|
* .setChainId(11155111) // optional
|
|
2632
2987
|
* .setAccount('0x123...890') // optional
|
|
2633
|
-
* .
|
|
2988
|
+
* .withACP() // optional
|
|
2634
2989
|
* .execute(); // execute
|
|
2635
2990
|
* ```
|
|
2636
2991
|
*
|
|
@@ -2638,14 +2993,14 @@ var DecryptForViewBuilder = class extends BaseBuilder {
|
|
|
2638
2993
|
*/
|
|
2639
2994
|
async execute() {
|
|
2640
2995
|
this.validateUtypeOrThrow();
|
|
2641
|
-
const
|
|
2642
|
-
|
|
2643
|
-
const chainId =
|
|
2996
|
+
const acp = await this.getResolvedACP();
|
|
2997
|
+
ACPUtils.validate(acp);
|
|
2998
|
+
const chainId = acp._signedDomain.chainId;
|
|
2644
2999
|
let unsealed;
|
|
2645
3000
|
if (chainId === hardhat$1.id) {
|
|
2646
|
-
unsealed = await this.mocksSealOutput(
|
|
3001
|
+
unsealed = await this.mocksSealOutput(acp);
|
|
2647
3002
|
} else {
|
|
2648
|
-
unsealed = await this.productionSealOutput(
|
|
3003
|
+
unsealed = await this.productionSealOutput(acp);
|
|
2649
3004
|
}
|
|
2650
3005
|
return convertViaUtype(this.utype, unsealed);
|
|
2651
3006
|
}
|
|
@@ -2653,28 +3008,28 @@ var DecryptForViewBuilder = class extends BaseBuilder {
|
|
|
2653
3008
|
var UINT_TYPE_MASK = 0x7fn;
|
|
2654
3009
|
var TYPE_BYTE_OFFSET = 8n;
|
|
2655
3010
|
var getEncryptionTypeFromCtHash = (ctHash) => Number(ctHash >> TYPE_BYTE_OFFSET & UINT_TYPE_MASK);
|
|
2656
|
-
async function cofheMocksDecryptForTx(ctHash, utype,
|
|
3011
|
+
async function cofheMocksDecryptForTx(ctHash, utype, acp, publicClient) {
|
|
2657
3012
|
let allowed;
|
|
2658
3013
|
let error;
|
|
2659
3014
|
let decryptedValue;
|
|
2660
|
-
if (
|
|
2661
|
-
|
|
3015
|
+
if (acp !== null) {
|
|
3016
|
+
const wireAcp = ACPUtils.getPublic(acp, true);
|
|
2662
3017
|
const permissionWithBigInts = {
|
|
2663
|
-
...
|
|
2664
|
-
expiration: BigInt(
|
|
2665
|
-
|
|
3018
|
+
...wireAcp,
|
|
3019
|
+
expiration: BigInt(wireAcp.expiration),
|
|
3020
|
+
revokerData: BigInt(wireAcp.revokerData)
|
|
2666
3021
|
};
|
|
2667
3022
|
[allowed, error, decryptedValue] = await publicClient.readContract({
|
|
2668
3023
|
address: MOCKS_THRESHOLD_NETWORK_ADDRESS,
|
|
2669
3024
|
abi: MockThresholdNetworkAbi,
|
|
2670
|
-
functionName: "
|
|
3025
|
+
functionName: "decryptForTxWithACP",
|
|
2671
3026
|
args: [BigInt(ctHash), permissionWithBigInts]
|
|
2672
3027
|
});
|
|
2673
3028
|
} else {
|
|
2674
3029
|
[allowed, error, decryptedValue] = await publicClient.readContract({
|
|
2675
3030
|
address: MOCKS_THRESHOLD_NETWORK_ADDRESS,
|
|
2676
3031
|
abi: MockThresholdNetworkAbi,
|
|
2677
|
-
functionName: "
|
|
3032
|
+
functionName: "decryptForTxWithoutACP",
|
|
2678
3033
|
args: [BigInt(ctHash)]
|
|
2679
3034
|
});
|
|
2680
3035
|
}
|
|
@@ -2709,62 +3064,6 @@ async function cofheMocksDecryptForTx(ctHash, utype, permit, publicClient) {
|
|
|
2709
3064
|
signature
|
|
2710
3065
|
};
|
|
2711
3066
|
}
|
|
2712
|
-
function normalizeTnSignature(signature) {
|
|
2713
|
-
if (typeof signature !== "string") {
|
|
2714
|
-
throw new CofheError({
|
|
2715
|
-
code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
|
|
2716
|
-
message: "decrypt response missing signature",
|
|
2717
|
-
context: {
|
|
2718
|
-
signature
|
|
2719
|
-
}
|
|
2720
|
-
});
|
|
2721
|
-
}
|
|
2722
|
-
const trimmed = signature.trim();
|
|
2723
|
-
if (trimmed.length === 0) {
|
|
2724
|
-
throw new CofheError({
|
|
2725
|
-
code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
|
|
2726
|
-
message: "decrypt response returned empty signature"
|
|
2727
|
-
});
|
|
2728
|
-
}
|
|
2729
|
-
const prefixed = trimmed.startsWith("0x") ? trimmed : `0x${trimmed}`;
|
|
2730
|
-
const parsed = parseSignature(prefixed);
|
|
2731
|
-
return serializeSignature(parsed);
|
|
2732
|
-
}
|
|
2733
|
-
function parseDecryptedBytesToBigInt(decrypted) {
|
|
2734
|
-
if (!Array.isArray(decrypted)) {
|
|
2735
|
-
throw new CofheError({
|
|
2736
|
-
code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
|
|
2737
|
-
message: "decrypt response field <decrypted> must be a byte array",
|
|
2738
|
-
context: {
|
|
2739
|
-
decrypted
|
|
2740
|
-
}
|
|
2741
|
-
});
|
|
2742
|
-
}
|
|
2743
|
-
if (decrypted.length === 0) {
|
|
2744
|
-
throw new CofheError({
|
|
2745
|
-
code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
|
|
2746
|
-
message: "decrypt response field <decrypted> was an empty byte array",
|
|
2747
|
-
context: {
|
|
2748
|
-
decrypted
|
|
2749
|
-
}
|
|
2750
|
-
});
|
|
2751
|
-
}
|
|
2752
|
-
let hex = "";
|
|
2753
|
-
for (const b of decrypted) {
|
|
2754
|
-
if (typeof b !== "number" || !Number.isInteger(b) || b < 0 || b > 255) {
|
|
2755
|
-
throw new CofheError({
|
|
2756
|
-
code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
|
|
2757
|
-
message: "decrypt response field <decrypted> contained a non-byte value",
|
|
2758
|
-
context: {
|
|
2759
|
-
badElement: b,
|
|
2760
|
-
decrypted
|
|
2761
|
-
}
|
|
2762
|
-
});
|
|
2763
|
-
}
|
|
2764
|
-
hex += b.toString(16).padStart(2, "0");
|
|
2765
|
-
}
|
|
2766
|
-
return BigInt(`0x${hex}`);
|
|
2767
|
-
}
|
|
2768
3067
|
|
|
2769
3068
|
// core/decrypt/tnDecryptV2.ts
|
|
2770
3069
|
var POLL_INTERVAL_MS2 = 1e3;
|
|
@@ -2886,25 +3185,30 @@ function assertDecryptStatusResponseV2(value) {
|
|
|
2886
3185
|
}
|
|
2887
3186
|
return value;
|
|
2888
3187
|
}
|
|
2889
|
-
async function submitDecryptRequestV2(thresholdNetworkUrl, ctHash, chainId,
|
|
3188
|
+
async function submitDecryptRequestV2(thresholdNetworkUrl, ctHash, chainId, acp, overallStartTime, retry404TimeoutMs, onPoll) {
|
|
2890
3189
|
const body = {
|
|
2891
3190
|
ct_tempkey: BigInt(ctHash).toString(16).padStart(64, "0"),
|
|
2892
3191
|
host_chain_id: chainId
|
|
2893
3192
|
};
|
|
2894
|
-
if (
|
|
2895
|
-
body.
|
|
3193
|
+
if (acp) {
|
|
3194
|
+
body.acp = acp;
|
|
2896
3195
|
}
|
|
2897
3196
|
let attemptIndex = 0;
|
|
3197
|
+
let last404ApiErrorMessage;
|
|
2898
3198
|
for (; ; ) {
|
|
2899
3199
|
let response;
|
|
2900
3200
|
try {
|
|
2901
|
-
response = await
|
|
2902
|
-
|
|
2903
|
-
|
|
2904
|
-
|
|
2905
|
-
|
|
2906
|
-
|
|
2907
|
-
|
|
3201
|
+
response = await cofheFetch(
|
|
3202
|
+
`${thresholdNetworkUrl}/v2/decrypt`,
|
|
3203
|
+
/*op:decrypt*/
|
|
3204
|
+
{
|
|
3205
|
+
method: "POST",
|
|
3206
|
+
headers: {
|
|
3207
|
+
"Content-Type": "application/json"
|
|
3208
|
+
},
|
|
3209
|
+
body: JSON.stringify(body)
|
|
3210
|
+
}
|
|
3211
|
+
);
|
|
2908
3212
|
} catch (e) {
|
|
2909
3213
|
throw new CofheError({
|
|
2910
3214
|
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
@@ -2918,16 +3222,19 @@ async function submitDecryptRequestV2(thresholdNetworkUrl, ctHash, chainId, perm
|
|
|
2918
3222
|
}
|
|
2919
3223
|
});
|
|
2920
3224
|
}
|
|
2921
|
-
const responseClassification = await classifySubmitResponse({
|
|
3225
|
+
const responseClassification = await classifySubmitResponse({
|
|
3226
|
+
response,
|
|
3227
|
+
fallbackErrorCode: "DECRYPT_FAILED" /* DecryptFailed */
|
|
3228
|
+
});
|
|
2922
3229
|
if (responseClassification.kind === "fatal-http") {
|
|
2923
3230
|
throw new CofheError({
|
|
2924
|
-
code:
|
|
3231
|
+
code: responseClassification.cofheErrorCode,
|
|
3232
|
+
apiErrorCode: responseClassification.apiErrorCode,
|
|
2925
3233
|
message: `decrypt request failed: ${responseClassification.errorMessage}`,
|
|
2926
3234
|
hint: "Check the threshold network URL and request parameters.",
|
|
2927
3235
|
context: {
|
|
2928
3236
|
thresholdNetworkUrl,
|
|
2929
|
-
status:
|
|
2930
|
-
statusText: response.statusText,
|
|
3237
|
+
status: responseClassification.status,
|
|
2931
3238
|
body,
|
|
2932
3239
|
attemptIndex
|
|
2933
3240
|
}
|
|
@@ -2975,6 +3282,9 @@ async function submitDecryptRequestV2(thresholdNetworkUrl, ctHash, chainId, perm
|
|
|
2975
3282
|
}
|
|
2976
3283
|
});
|
|
2977
3284
|
}
|
|
3285
|
+
if (responseClassification.status === 404) {
|
|
3286
|
+
last404ApiErrorMessage = responseClassification.apiErrorMessage;
|
|
3287
|
+
}
|
|
2978
3288
|
const elapsedMs = Date.now() - overallStartTime;
|
|
2979
3289
|
throwIfSubmitRetryTimedOut({
|
|
2980
3290
|
operationLabel: "decrypt",
|
|
@@ -2985,7 +3295,8 @@ async function submitDecryptRequestV2(thresholdNetworkUrl, ctHash, chainId, perm
|
|
|
2985
3295
|
overallTimeoutMs: DECRYPT_TIMEOUT_MS,
|
|
2986
3296
|
thresholdNetworkUrl,
|
|
2987
3297
|
body,
|
|
2988
|
-
attemptIndex
|
|
3298
|
+
attemptIndex,
|
|
3299
|
+
lastKnownErrorMessage: last404ApiErrorMessage
|
|
2989
3300
|
});
|
|
2990
3301
|
onPoll?.({
|
|
2991
3302
|
operation: "decrypt",
|
|
@@ -3029,12 +3340,16 @@ async function pollDecryptStatusV2(thresholdNetworkUrl, requestId, overallStartT
|
|
|
3029
3340
|
}
|
|
3030
3341
|
let response;
|
|
3031
3342
|
try {
|
|
3032
|
-
response = await
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
|
|
3343
|
+
response = await cofheFetch(
|
|
3344
|
+
`${thresholdNetworkUrl}/v2/decrypt/${requestId}`,
|
|
3345
|
+
/*op:decrypt-poll*/
|
|
3346
|
+
{
|
|
3347
|
+
method: "GET",
|
|
3348
|
+
headers: {
|
|
3349
|
+
"Content-Type": "application/json"
|
|
3350
|
+
}
|
|
3036
3351
|
}
|
|
3037
|
-
|
|
3352
|
+
);
|
|
3038
3353
|
} catch (e) {
|
|
3039
3354
|
throw new CofheError({
|
|
3040
3355
|
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
@@ -3059,17 +3374,10 @@ async function pollDecryptStatusV2(thresholdNetworkUrl, requestId, overallStartT
|
|
|
3059
3374
|
});
|
|
3060
3375
|
}
|
|
3061
3376
|
if (!response.ok) {
|
|
3062
|
-
|
|
3063
|
-
try {
|
|
3064
|
-
const errorBody = await response.json();
|
|
3065
|
-
const maybeMessage = errorBody.error_message || errorBody.message;
|
|
3066
|
-
if (typeof maybeMessage === "string" && maybeMessage.length > 0)
|
|
3067
|
-
errorMessage = maybeMessage;
|
|
3068
|
-
} catch {
|
|
3069
|
-
errorMessage = response.statusText || errorMessage;
|
|
3070
|
-
}
|
|
3377
|
+
const { apiErrorCode, errorMessage } = await parseApiErrorResponseBody(response);
|
|
3071
3378
|
throw new CofheError({
|
|
3072
|
-
code: "DECRYPT_FAILED" /* DecryptFailed
|
|
3379
|
+
code: mapApiErrorCodeToCofheErrorCode(apiErrorCode, "DECRYPT_FAILED" /* DecryptFailed */),
|
|
3380
|
+
apiErrorCode,
|
|
3073
3381
|
message: `decrypt status poll failed: ${errorMessage}`,
|
|
3074
3382
|
context: {
|
|
3075
3383
|
thresholdNetworkUrl,
|
|
@@ -3114,7 +3422,7 @@ async function pollDecryptStatusV2(thresholdNetworkUrl, requestId, overallStartT
|
|
|
3114
3422
|
});
|
|
3115
3423
|
}
|
|
3116
3424
|
async function tnDecryptV2(params) {
|
|
3117
|
-
const { thresholdNetworkUrl, ctHash, chainId,
|
|
3425
|
+
const { thresholdNetworkUrl, ctHash, chainId, acp, retry404TimeoutMs, onPoll } = params;
|
|
3118
3426
|
const normalized404RetryTimeoutMs = normalize404RetryTimeoutMs({
|
|
3119
3427
|
timeoutMs: retry404TimeoutMs,
|
|
3120
3428
|
operationLabel: "decrypt",
|
|
@@ -3125,7 +3433,7 @@ async function tnDecryptV2(params) {
|
|
|
3125
3433
|
thresholdNetworkUrl,
|
|
3126
3434
|
ctHash,
|
|
3127
3435
|
chainId,
|
|
3128
|
-
|
|
3436
|
+
acp,
|
|
3129
3437
|
overallStartTime,
|
|
3130
3438
|
normalized404RetryTimeoutMs,
|
|
3131
3439
|
onPoll
|
|
@@ -3140,9 +3448,9 @@ async function tnDecryptV2(params) {
|
|
|
3140
3448
|
var DEFAULT_404_RETRY_TIMEOUT_MS3 = 1e4;
|
|
3141
3449
|
var DecryptForTxBuilder = class extends BaseBuilder {
|
|
3142
3450
|
ctHash;
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
|
|
3451
|
+
acpHash;
|
|
3452
|
+
acp;
|
|
3453
|
+
acpSelection = "unset";
|
|
3146
3454
|
pollCallback;
|
|
3147
3455
|
retry404TimeoutMs = DEFAULT_404_RETRY_TIMEOUT_MS3;
|
|
3148
3456
|
constructor(params) {
|
|
@@ -3187,137 +3495,137 @@ var DecryptForTxBuilder = class extends BaseBuilder {
|
|
|
3187
3495
|
this.retry404TimeoutMs = timeoutMs;
|
|
3188
3496
|
return this;
|
|
3189
3497
|
}
|
|
3190
|
-
|
|
3191
|
-
if (this.
|
|
3498
|
+
withACP(acpOrACPHash) {
|
|
3499
|
+
if (this.acpSelection === "with-acp") {
|
|
3192
3500
|
throw new CofheError({
|
|
3193
3501
|
code: "INTERNAL_ERROR" /* InternalError */,
|
|
3194
|
-
message: "decryptForTx:
|
|
3195
|
-
hint: "Choose the
|
|
3502
|
+
message: "decryptForTx: withACP() can only be selected once.",
|
|
3503
|
+
hint: "Choose the acp mode once. If you need a different acp, start a new decryptForTx() builder chain."
|
|
3196
3504
|
});
|
|
3197
3505
|
}
|
|
3198
|
-
if (this.
|
|
3506
|
+
if (this.acpSelection === "without-acp") {
|
|
3199
3507
|
throw new CofheError({
|
|
3200
3508
|
code: "INTERNAL_ERROR" /* InternalError */,
|
|
3201
|
-
message: "decryptForTx: cannot call
|
|
3202
|
-
hint: "Choose exactly one
|
|
3509
|
+
message: "decryptForTx: cannot call withACP() after withoutACP() has been selected.",
|
|
3510
|
+
hint: "Choose exactly one acp mode: either call .withACP(...) or .withoutACP(), but not both."
|
|
3203
3511
|
});
|
|
3204
3512
|
}
|
|
3205
|
-
this.
|
|
3206
|
-
if (typeof
|
|
3207
|
-
this.
|
|
3208
|
-
this.
|
|
3209
|
-
} else if (
|
|
3210
|
-
this.
|
|
3211
|
-
this.
|
|
3513
|
+
this.acpSelection = "with-acp";
|
|
3514
|
+
if (typeof acpOrACPHash === "string") {
|
|
3515
|
+
this.acpHash = acpOrACPHash;
|
|
3516
|
+
this.acp = void 0;
|
|
3517
|
+
} else if (acpOrACPHash === void 0) {
|
|
3518
|
+
this.acpHash = void 0;
|
|
3519
|
+
this.acp = void 0;
|
|
3212
3520
|
} else {
|
|
3213
|
-
this.
|
|
3214
|
-
this.
|
|
3521
|
+
this.acp = acpOrACPHash;
|
|
3522
|
+
this.acpHash = void 0;
|
|
3215
3523
|
}
|
|
3216
3524
|
return this;
|
|
3217
3525
|
}
|
|
3218
3526
|
/**
|
|
3219
|
-
* Select "no
|
|
3527
|
+
* Select "no acp" mode.
|
|
3220
3528
|
*
|
|
3221
|
-
* This uses global allowance (no
|
|
3529
|
+
* This uses global allowance (no acp required) and sends an empty permission payload to `/decrypt`.
|
|
3222
3530
|
*/
|
|
3223
|
-
|
|
3224
|
-
if (this.
|
|
3531
|
+
withoutACP() {
|
|
3532
|
+
if (this.acpSelection === "without-acp") {
|
|
3225
3533
|
throw new CofheError({
|
|
3226
3534
|
code: "INTERNAL_ERROR" /* InternalError */,
|
|
3227
|
-
message: "decryptForTx:
|
|
3228
|
-
hint: "Choose the
|
|
3535
|
+
message: "decryptForTx: withoutACP() can only be selected once.",
|
|
3536
|
+
hint: "Choose the acp mode once. If you need a different mode, start a new decryptForTx() builder chain."
|
|
3229
3537
|
});
|
|
3230
3538
|
}
|
|
3231
|
-
if (this.
|
|
3539
|
+
if (this.acpSelection === "with-acp") {
|
|
3232
3540
|
throw new CofheError({
|
|
3233
3541
|
code: "INTERNAL_ERROR" /* InternalError */,
|
|
3234
|
-
message: "decryptForTx: cannot call
|
|
3235
|
-
hint: "Choose exactly one
|
|
3542
|
+
message: "decryptForTx: cannot call withoutACP() after withACP() has been selected.",
|
|
3543
|
+
hint: "Choose exactly one acp mode: either call .withACP(...) or .withoutACP(), but not both."
|
|
3236
3544
|
});
|
|
3237
3545
|
}
|
|
3238
|
-
this.
|
|
3239
|
-
this.
|
|
3240
|
-
this.
|
|
3546
|
+
this.acpSelection = "without-acp";
|
|
3547
|
+
this.acpHash = void 0;
|
|
3548
|
+
this.acp = void 0;
|
|
3241
3549
|
return this;
|
|
3242
3550
|
}
|
|
3243
|
-
|
|
3244
|
-
return this.
|
|
3551
|
+
getACP() {
|
|
3552
|
+
return this.acp;
|
|
3245
3553
|
}
|
|
3246
|
-
|
|
3247
|
-
return this.
|
|
3554
|
+
getACPHash() {
|
|
3555
|
+
return this.acpHash;
|
|
3248
3556
|
}
|
|
3249
3557
|
async getThresholdNetworkUrl() {
|
|
3250
3558
|
this.assertChainId();
|
|
3251
3559
|
return getThresholdNetworkUrlOrThrow(this.config, this.chainId);
|
|
3252
3560
|
}
|
|
3253
|
-
async
|
|
3254
|
-
if (this.
|
|
3561
|
+
async getResolvedACP() {
|
|
3562
|
+
if (this.acpSelection === "unset") {
|
|
3255
3563
|
throw new CofheError({
|
|
3256
3564
|
code: "INTERNAL_ERROR" /* InternalError */,
|
|
3257
|
-
message: "decryptForTx: missing
|
|
3258
|
-
hint: "Call .
|
|
3565
|
+
message: "decryptForTx: missing acp selection; call withACP(...) or withoutACP() before execute().",
|
|
3566
|
+
hint: "Call .withACP() to use the active acp, or .withoutACP() for global allowance."
|
|
3259
3567
|
});
|
|
3260
3568
|
}
|
|
3261
|
-
if (this.
|
|
3569
|
+
if (this.acpSelection === "without-acp") {
|
|
3262
3570
|
return null;
|
|
3263
3571
|
}
|
|
3264
|
-
if (this.
|
|
3265
|
-
return this.
|
|
3572
|
+
if (this.acp)
|
|
3573
|
+
return this.acp;
|
|
3266
3574
|
this.assertChainId();
|
|
3267
3575
|
this.assertAccount();
|
|
3268
|
-
if (this.
|
|
3269
|
-
const
|
|
3270
|
-
if (!
|
|
3576
|
+
if (this.acpHash) {
|
|
3577
|
+
const acp2 = await acps.getACP(this.chainId, this.account, this.acpHash);
|
|
3578
|
+
if (!acp2) {
|
|
3271
3579
|
throw new CofheError({
|
|
3272
|
-
code: "
|
|
3273
|
-
message: `
|
|
3274
|
-
hint: "Ensure the
|
|
3580
|
+
code: "ACP_NOT_FOUND" /* ACPNotFound */,
|
|
3581
|
+
message: `ACP with hash <${this.acpHash}> not found for account <${this.account}> and chainId <${this.chainId}>`,
|
|
3582
|
+
hint: "Ensure the acp exists and is valid.",
|
|
3275
3583
|
context: {
|
|
3276
3584
|
chainId: this.chainId,
|
|
3277
3585
|
account: this.account,
|
|
3278
|
-
|
|
3586
|
+
acpHash: this.acpHash
|
|
3279
3587
|
}
|
|
3280
3588
|
});
|
|
3281
3589
|
}
|
|
3282
|
-
return
|
|
3590
|
+
return acp2;
|
|
3283
3591
|
}
|
|
3284
|
-
const
|
|
3285
|
-
if (!
|
|
3592
|
+
const acp = await acps.getActiveACP(this.chainId, this.account);
|
|
3593
|
+
if (!acp) {
|
|
3286
3594
|
throw new CofheError({
|
|
3287
|
-
code: "
|
|
3288
|
-
message: `Active
|
|
3289
|
-
hint: "Create
|
|
3595
|
+
code: "ACP_NOT_FOUND" /* ACPNotFound */,
|
|
3596
|
+
message: `Active acp not found for chainId <${this.chainId}> and account <${this.account}>`,
|
|
3597
|
+
hint: "Create an ACP (e.g. client.acp.createSelf(...)) and/or set it active (client.acp.selectActiveACP(hash)).",
|
|
3290
3598
|
context: {
|
|
3291
3599
|
chainId: this.chainId,
|
|
3292
3600
|
account: this.account
|
|
3293
3601
|
}
|
|
3294
3602
|
});
|
|
3295
3603
|
}
|
|
3296
|
-
return
|
|
3604
|
+
return acp;
|
|
3297
3605
|
}
|
|
3298
3606
|
/**
|
|
3299
3607
|
* On hardhat, interact with MockThresholdNetwork contract
|
|
3300
3608
|
*/
|
|
3301
|
-
async mocksDecryptForTx(
|
|
3609
|
+
async mocksDecryptForTx(acp) {
|
|
3302
3610
|
this.assertPublicClient();
|
|
3303
3611
|
const delay = this.config.mocks.decryptDelay;
|
|
3304
3612
|
if (delay > 0)
|
|
3305
3613
|
await sleep(delay);
|
|
3306
|
-
const result = await cofheMocksDecryptForTx(this.ctHash, 0,
|
|
3614
|
+
const result = await cofheMocksDecryptForTx(this.ctHash, 0, acp, this.publicClient);
|
|
3307
3615
|
return result;
|
|
3308
3616
|
}
|
|
3309
3617
|
/**
|
|
3310
3618
|
* In the production context, perform a true decryption with the CoFHE coprocessor.
|
|
3311
3619
|
*/
|
|
3312
|
-
async productionDecryptForTx(
|
|
3620
|
+
async productionDecryptForTx(acp) {
|
|
3313
3621
|
this.assertChainId();
|
|
3314
3622
|
this.assertPublicClient();
|
|
3315
3623
|
const thresholdNetworkUrl = await this.getThresholdNetworkUrl();
|
|
3316
|
-
const
|
|
3624
|
+
const wireAcp = acp ? ACPUtils.getPublic(acp, true) : null;
|
|
3317
3625
|
const { decryptedValue, signature } = await tnDecryptV2({
|
|
3318
3626
|
ctHash: this.ctHash,
|
|
3319
3627
|
chainId: this.chainId,
|
|
3320
|
-
|
|
3628
|
+
acp: wireAcp,
|
|
3321
3629
|
thresholdNetworkUrl,
|
|
3322
3630
|
retry404TimeoutMs: this.retry404TimeoutMs,
|
|
3323
3631
|
onPoll: this.pollCallback
|
|
@@ -3331,19 +3639,19 @@ var DecryptForTxBuilder = class extends BaseBuilder {
|
|
|
3331
3639
|
/**
|
|
3332
3640
|
* Final step of the decryptForTx process. MUST BE CALLED LAST IN THE CHAIN.
|
|
3333
3641
|
*
|
|
3334
|
-
* You must explicitly choose one
|
|
3335
|
-
* - `
|
|
3336
|
-
* - `
|
|
3642
|
+
* You must explicitly choose one acp mode before calling `execute()`:
|
|
3643
|
+
* - `withACP(acp)` / `withACP(acpHash)` / `withACP()` (active acp)
|
|
3644
|
+
* - `withoutACP()` (global allowance)
|
|
3337
3645
|
*/
|
|
3338
3646
|
async execute() {
|
|
3339
|
-
const
|
|
3340
|
-
if (
|
|
3341
|
-
|
|
3342
|
-
const chainId =
|
|
3647
|
+
const acp = await this.getResolvedACP();
|
|
3648
|
+
if (acp !== null) {
|
|
3649
|
+
ACPUtils.validate(acp);
|
|
3650
|
+
const chainId = acp._signedDomain.chainId;
|
|
3343
3651
|
if (chainId === hardhat$1.id) {
|
|
3344
|
-
return await this.mocksDecryptForTx(
|
|
3652
|
+
return await this.mocksDecryptForTx(acp);
|
|
3345
3653
|
} else {
|
|
3346
|
-
return await this.productionDecryptForTx(
|
|
3654
|
+
return await this.productionDecryptForTx(acp);
|
|
3347
3655
|
}
|
|
3348
3656
|
} else {
|
|
3349
3657
|
if (!this.chainId) {
|
|
@@ -3406,6 +3714,21 @@ function createCofheClientBase(opts) {
|
|
|
3406
3714
|
const updateConnectState = (partial) => {
|
|
3407
3715
|
connectStore.setState((state) => ({ ...state, ...partial }));
|
|
3408
3716
|
};
|
|
3717
|
+
const _resolveSharingRegistry = async (publicClient, chainId) => {
|
|
3718
|
+
const configured = opts.config.acp?.sharingRegistry?.[chainId];
|
|
3719
|
+
if (configured != null)
|
|
3720
|
+
return configured;
|
|
3721
|
+
const registry = (await acps.getAclServedAddresses(publicClient, chainId)).shareRegistry;
|
|
3722
|
+
if (registry == null) {
|
|
3723
|
+
throw new CofheError({
|
|
3724
|
+
code: "MISSING_CONFIG" /* MissingConfig */,
|
|
3725
|
+
message: `No ACP share registry available for chainId <${chainId}>`,
|
|
3726
|
+
hint: "The ACL on this chain does not serve a share registry address. Set `acp.sharingRegistry` in the cofhe config to use on-chain sharing.",
|
|
3727
|
+
context: { chainId }
|
|
3728
|
+
});
|
|
3729
|
+
}
|
|
3730
|
+
return registry;
|
|
3731
|
+
};
|
|
3409
3732
|
const _requireConnected = () => {
|
|
3410
3733
|
const state = connectStore.getState();
|
|
3411
3734
|
const notConnected = !state.connected || !state.account || !state.chainId || !state.publicClient || !state.walletClient;
|
|
@@ -3528,74 +3851,147 @@ function createCofheClientBase(opts) {
|
|
|
3528
3851
|
}
|
|
3529
3852
|
return { chainId: _chainId, account: _account };
|
|
3530
3853
|
};
|
|
3531
|
-
const
|
|
3854
|
+
const clientACPs = {
|
|
3532
3855
|
// Pass through store access
|
|
3533
|
-
getSnapshot:
|
|
3534
|
-
subscribe:
|
|
3856
|
+
getSnapshot: acps.getSnapshot,
|
|
3857
|
+
subscribe: acps.subscribe,
|
|
3535
3858
|
// Creation methods (require connection)
|
|
3536
3859
|
createSelf: async (options, clients) => {
|
|
3537
3860
|
_requireConnected();
|
|
3538
3861
|
const { publicClient, walletClient } = clients ?? connectStore.getState();
|
|
3539
|
-
|
|
3862
|
+
const chainId = await publicClient.getChainId();
|
|
3863
|
+
return acps.createSelf(
|
|
3864
|
+
await acps.applyACPDefaultsFromChain(options, opts.config.acp, publicClient, chainId),
|
|
3865
|
+
publicClient,
|
|
3866
|
+
walletClient
|
|
3867
|
+
);
|
|
3540
3868
|
},
|
|
3541
3869
|
createSharing: async (options, clients) => {
|
|
3542
3870
|
_requireConnected();
|
|
3543
3871
|
const { publicClient, walletClient } = clients ?? connectStore.getState();
|
|
3544
|
-
|
|
3872
|
+
const chainId = await publicClient.getChainId();
|
|
3873
|
+
return acps.createSharing(
|
|
3874
|
+
await acps.applyACPDefaultsFromChain(options, opts.config.acp, publicClient, chainId),
|
|
3875
|
+
publicClient,
|
|
3876
|
+
walletClient
|
|
3877
|
+
);
|
|
3545
3878
|
},
|
|
3546
3879
|
importShared: async (options, clients) => {
|
|
3547
3880
|
_requireConnected();
|
|
3548
3881
|
const { publicClient, walletClient } = clients ?? connectStore.getState();
|
|
3549
|
-
return
|
|
3882
|
+
return acps.importShared(options, publicClient, walletClient);
|
|
3550
3883
|
},
|
|
3551
3884
|
// Get or create methods (require connection)
|
|
3552
|
-
|
|
3885
|
+
getOrCreateSelfACP: async (chainId, account, options) => {
|
|
3553
3886
|
_requireConnected();
|
|
3554
3887
|
const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
|
|
3555
3888
|
const { publicClient, walletClient } = connectStore.getState();
|
|
3556
|
-
|
|
3889
|
+
const optionsWithDefaults = await acps.applyACPDefaultsFromChain(
|
|
3890
|
+
options ?? { issuer: _account, name: "Autogenerated Self ACP" },
|
|
3891
|
+
opts.config.acp,
|
|
3892
|
+
publicClient,
|
|
3893
|
+
_chainId
|
|
3894
|
+
);
|
|
3895
|
+
return acps.getOrCreateSelfACP(publicClient, walletClient, _chainId, _account, optionsWithDefaults);
|
|
3557
3896
|
},
|
|
3558
|
-
|
|
3897
|
+
getOrCreateSharingACP: async (options, chainId, account) => {
|
|
3559
3898
|
_requireConnected();
|
|
3560
3899
|
const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
|
|
3561
3900
|
const { publicClient, walletClient } = connectStore.getState();
|
|
3562
|
-
return
|
|
3901
|
+
return acps.getOrCreateSharingACP(
|
|
3902
|
+
publicClient,
|
|
3903
|
+
walletClient,
|
|
3904
|
+
await acps.applyACPDefaultsFromChain(options, opts.config.acp, publicClient, _chainId),
|
|
3905
|
+
_chainId,
|
|
3906
|
+
_account
|
|
3907
|
+
);
|
|
3908
|
+
},
|
|
3909
|
+
// Revocation (require connection)
|
|
3910
|
+
revokeACP: async (acp) => {
|
|
3911
|
+
_requireConnected();
|
|
3912
|
+
const { walletClient } = connectStore.getState();
|
|
3913
|
+
return acps.revokeACP(acp, walletClient);
|
|
3914
|
+
},
|
|
3915
|
+
revokeAllACPs: async (revokerContract) => {
|
|
3916
|
+
_requireConnected();
|
|
3917
|
+
const { publicClient, walletClient } = connectStore.getState();
|
|
3918
|
+
return acps.revokeAllACPs(walletClient, publicClient, revokerContract);
|
|
3919
|
+
},
|
|
3920
|
+
isACPRevoked: async (acp) => {
|
|
3921
|
+
_requireConnected();
|
|
3922
|
+
const { publicClient } = connectStore.getState();
|
|
3923
|
+
return acps.isACPRevoked(acp, publicClient);
|
|
3924
|
+
},
|
|
3925
|
+
// On-chain sharing (require connection + config.acp.sharingRegistry)
|
|
3926
|
+
shareOnChain: async (acp) => {
|
|
3927
|
+
_requireConnected();
|
|
3928
|
+
const { publicClient, walletClient } = connectStore.getState();
|
|
3929
|
+
const chainId = await publicClient.getChainId();
|
|
3930
|
+
const sharingRegistry = await _resolveSharingRegistry(publicClient, chainId);
|
|
3931
|
+
return acps.shareOnChain(acp, walletClient, sharingRegistry);
|
|
3932
|
+
},
|
|
3933
|
+
getIncomingShares: async () => {
|
|
3934
|
+
_requireConnected();
|
|
3935
|
+
const { publicClient, walletClient } = connectStore.getState();
|
|
3936
|
+
const chainId = await publicClient.getChainId();
|
|
3937
|
+
const account = walletClient.account.address;
|
|
3938
|
+
const sharingRegistry = await _resolveSharingRegistry(publicClient, chainId);
|
|
3939
|
+
return acps.getIncomingShares(publicClient, sharingRegistry, account);
|
|
3940
|
+
},
|
|
3941
|
+
importFromChain: async (share) => {
|
|
3942
|
+
_requireConnected();
|
|
3943
|
+
const { publicClient, walletClient } = connectStore.getState();
|
|
3944
|
+
return acps.importFromChain(share, publicClient, walletClient);
|
|
3945
|
+
},
|
|
3946
|
+
dismissShare: async (shareId) => {
|
|
3947
|
+
_requireConnected();
|
|
3948
|
+
const { publicClient, walletClient } = connectStore.getState();
|
|
3949
|
+
const chainId = await publicClient.getChainId();
|
|
3950
|
+
const sharingRegistry = await _resolveSharingRegistry(publicClient, chainId);
|
|
3951
|
+
return acps.removeShareOnChain(shareId, walletClient, sharingRegistry);
|
|
3952
|
+
},
|
|
3953
|
+
cancelShare: async (shareId) => {
|
|
3954
|
+
_requireConnected();
|
|
3955
|
+
const { publicClient, walletClient } = connectStore.getState();
|
|
3956
|
+
const chainId = await publicClient.getChainId();
|
|
3957
|
+
const sharingRegistry = await _resolveSharingRegistry(publicClient, chainId);
|
|
3958
|
+
return acps.removeShareOnChain(shareId, walletClient, sharingRegistry);
|
|
3563
3959
|
},
|
|
3564
3960
|
// Retrieval methods (auto-fill chainId/account)
|
|
3565
|
-
|
|
3961
|
+
getACP: (hash, chainId, account) => {
|
|
3566
3962
|
const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
|
|
3567
|
-
return
|
|
3963
|
+
return acps.getACP(_chainId, _account, hash);
|
|
3568
3964
|
},
|
|
3569
|
-
|
|
3965
|
+
getACPs: (chainId, account) => {
|
|
3570
3966
|
const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
|
|
3571
|
-
return
|
|
3967
|
+
return acps.getACPs(_chainId, _account);
|
|
3572
3968
|
},
|
|
3573
|
-
|
|
3969
|
+
getActiveACP: (chainId, account) => {
|
|
3574
3970
|
const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
|
|
3575
|
-
return
|
|
3971
|
+
return acps.getActiveACP(_chainId, _account);
|
|
3576
3972
|
},
|
|
3577
|
-
|
|
3973
|
+
getActiveACPHash: (chainId, account) => {
|
|
3578
3974
|
const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
|
|
3579
|
-
return
|
|
3975
|
+
return acps.getActiveACPHash(_chainId, _account);
|
|
3580
3976
|
},
|
|
3581
3977
|
// Mutation methods (auto-fill chainId/account)
|
|
3582
|
-
|
|
3978
|
+
selectActiveACP: (hash, chainId, account) => {
|
|
3583
3979
|
const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
|
|
3584
|
-
return
|
|
3980
|
+
return acps.selectActiveACP(_chainId, _account, hash);
|
|
3585
3981
|
},
|
|
3586
|
-
|
|
3982
|
+
removeACP: async (hash, chainId, account) => {
|
|
3587
3983
|
const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
|
|
3588
|
-
return
|
|
3984
|
+
return acps.removeACP(_chainId, _account, hash);
|
|
3589
3985
|
},
|
|
3590
|
-
|
|
3986
|
+
removeActiveACP: async (chainId, account) => {
|
|
3591
3987
|
const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
|
|
3592
|
-
return
|
|
3988
|
+
return acps.removeActiveACP(_chainId, _account);
|
|
3593
3989
|
},
|
|
3594
3990
|
// Utils (no context needed)
|
|
3595
|
-
getHash:
|
|
3596
|
-
export:
|
|
3597
|
-
serialize:
|
|
3598
|
-
deserialize:
|
|
3991
|
+
getHash: acps.getHash,
|
|
3992
|
+
export: acps.export,
|
|
3993
|
+
serialize: acps.serialize,
|
|
3994
|
+
deserialize: acps.deserialize
|
|
3599
3995
|
};
|
|
3600
3996
|
return {
|
|
3601
3997
|
// Zustand reactive accessors (don't export store directly to prevent mutation)
|
|
@@ -3623,7 +4019,7 @@ function createCofheClientBase(opts) {
|
|
|
3623
4019
|
decryptHandle: decryptForView,
|
|
3624
4020
|
decryptForTx,
|
|
3625
4021
|
verifyDecryptResult: verifyDecryptResult2,
|
|
3626
|
-
|
|
4022
|
+
acp: clientACPs
|
|
3627
4023
|
// Add SDK-specific methods below that require connection
|
|
3628
4024
|
// Example:
|
|
3629
4025
|
// async encryptData(data: unknown) {
|
|
@@ -3633,4 +4029,4 @@ function createCofheClientBase(opts) {
|
|
|
3633
4029
|
};
|
|
3634
4030
|
}
|
|
3635
4031
|
|
|
3636
|
-
export { CofheError, CofheErrorCode, DecryptForTxBuilder, DecryptForViewBuilder, EncryptInputsBuilder, EncryptStep, Encryptable, FheAllUTypes, FheTypes, FheUintUTypes, InitialConnectStore,
|
|
4032
|
+
export { CofheError, CofheErrorCode, DecryptForTxBuilder, DecryptForViewBuilder, EncryptInputsBuilder, EncryptStep, Encryptable, FheAllUTypes, FheTypes, FheUintUTypes, InitialConnectStore, assertNoRenamedConfigKeys, cofheFetch, createCofheClientBase, createCofheConfigBase, createKeysStore, fetchKeys, fheTypeToString, getCofheConfigItem, getCofheDebugInterceptors, isCofheError, isEncryptableItem, isLastEncryptionStep, setCofheDebugInterceptors, verifyDecryptResult, zkProveWithWorker };
|