@cofhe/sdk 0.5.1 → 0.6.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 +34 -0
- package/adapters/test/ethers5.test.ts +1 -1
- package/adapters/test/ethers6.test.ts +1 -1
- package/adapters/test/wagmi.test.ts +1 -1
- package/chains/chains/hardhat.ts +3 -3
- package/core/consts.ts +0 -3
- package/core/decrypt/decryptForTxBuilder.ts +21 -0
- package/core/decrypt/decryptForViewBuilder.ts +19 -0
- package/core/decrypt/submitRetry.ts +126 -0
- package/core/decrypt/tnDecryptV2.ts +48 -53
- package/core/decrypt/tnSealOutputV2.ts +48 -54
- package/core/encrypt/cofheMocksZkVerifySign.ts +2 -2
- package/core/encrypt/encryptInputsBuilder.ts +46 -11
- package/core/encrypt/zkPackProveVerify.ts +3 -3
- package/core/index.ts +13 -1
- package/core/test/decryptBuilders.test.ts +28 -0
- package/core/test/encryptInputsBuilder.test.ts +35 -0
- package/core/test/pollCallbacks.test.ts +226 -0
- package/core/types.ts +65 -5
- package/dist/chains.cjs +3 -3
- package/dist/chains.js +1 -1
- package/dist/{chunk-4FP4V35O.js → chunk-ESMZCFJY.js} +1 -2
- package/dist/{chunk-TBLR7NNE.js → chunk-MTRAXQXC.js} +3 -3
- package/dist/{chunk-S7OKGLFD.js → chunk-PE5V5CCV.js} +288 -153
- package/dist/{chunk-MRCKUMOS.js → chunk-VB62WYPL.js} +1 -1
- package/dist/{clientTypes-BSbwairE.d.cts → clientTypes-BDy1qIBu.d.cts} +78 -11
- package/dist/{clientTypes-DDmcgZ0a.d.ts → clientTypes-CyUvRRzA.d.ts} +78 -11
- package/dist/core.cjs +288 -155
- package/dist/core.d.cts +3 -5
- package/dist/core.d.ts +3 -5
- package/dist/core.js +4 -4
- package/dist/node.cjs +243 -108
- package/dist/node.d.cts +1 -1
- package/dist/node.d.ts +1 -1
- package/dist/node.js +4 -4
- package/dist/permits.d.cts +10 -6
- package/dist/permits.d.ts +10 -6
- package/dist/permits.js +2 -2
- package/dist/web.cjs +243 -108
- package/dist/web.d.cts +1 -1
- package/dist/web.d.ts +1 -1
- package/dist/web.js +4 -4
- package/dist/zkProve.worker.js +1 -1
- package/package.json +2 -2
- package/permits/store.ts +1 -0
- package/web/test/ssr.test.ts +23 -0
- package/web/test/tfheinit.web.test.ts +81 -5
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { hardhat as hardhat$1 } from './chunk-
|
|
2
|
-
import { permitStore, PermitUtils } from './chunk-
|
|
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-
|
|
1
|
+
import { hardhat as hardhat$1 } from './chunk-MTRAXQXC.js';
|
|
2
|
+
import { permitStore, PermitUtils } from './chunk-VB62WYPL.js';
|
|
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
5
|
import { parseAbi, isAddressEqual, zeroAddress, recoverAddress, encodePacked, keccak256, createWalletClient, http, getAddress, parseSignature, serializeSignature } from 'viem';
|
|
6
6
|
import { hardhat } from 'viem/chains';
|
|
@@ -10,51 +10,51 @@ 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
|
-
return
|
|
13
|
+
var CofheErrorCode = /* @__PURE__ */ ((CofheErrorCode3) => {
|
|
14
|
+
CofheErrorCode3["InternalError"] = "INTERNAL_ERROR";
|
|
15
|
+
CofheErrorCode3["UnknownEnvironment"] = "UNKNOWN_ENVIRONMENT";
|
|
16
|
+
CofheErrorCode3["InitTfheFailed"] = "INIT_TFHE_FAILED";
|
|
17
|
+
CofheErrorCode3["InitViemFailed"] = "INIT_VIEM_FAILED";
|
|
18
|
+
CofheErrorCode3["InitEthersFailed"] = "INIT_ETHERS_FAILED";
|
|
19
|
+
CofheErrorCode3["NotConnected"] = "NOT_CONNECTED";
|
|
20
|
+
CofheErrorCode3["MissingPublicClient"] = "MISSING_PUBLIC_CLIENT";
|
|
21
|
+
CofheErrorCode3["MissingWalletClient"] = "MISSING_WALLET_CLIENT";
|
|
22
|
+
CofheErrorCode3["MissingProviderParam"] = "MISSING_PROVIDER_PARAM";
|
|
23
|
+
CofheErrorCode3["EmptySecurityZonesParam"] = "EMPTY_SECURITY_ZONES_PARAM";
|
|
24
|
+
CofheErrorCode3["InvalidPermitData"] = "INVALID_PERMIT_DATA";
|
|
25
|
+
CofheErrorCode3["InvalidPermitDomain"] = "INVALID_PERMIT_DOMAIN";
|
|
26
|
+
CofheErrorCode3["PermitNotFound"] = "PERMIT_NOT_FOUND";
|
|
27
|
+
CofheErrorCode3["CannotRemoveLastPermit"] = "CANNOT_REMOVE_LAST_PERMIT";
|
|
28
|
+
CofheErrorCode3["AccountUninitialized"] = "ACCOUNT_UNINITIALIZED";
|
|
29
|
+
CofheErrorCode3["ChainIdUninitialized"] = "CHAIN_ID_UNINITIALIZED";
|
|
30
|
+
CofheErrorCode3["SealOutputFailed"] = "SEAL_OUTPUT_FAILED";
|
|
31
|
+
CofheErrorCode3["SealOutputReturnedNull"] = "SEAL_OUTPUT_RETURNED_NULL";
|
|
32
|
+
CofheErrorCode3["InvalidUtype"] = "INVALID_UTYPE";
|
|
33
|
+
CofheErrorCode3["DecryptFailed"] = "DECRYPT_FAILED";
|
|
34
|
+
CofheErrorCode3["DecryptReturnedNull"] = "DECRYPT_RETURNED_NULL";
|
|
35
|
+
CofheErrorCode3["ZkMocksInsertCtHashesFailed"] = "ZK_MOCKS_INSERT_CT_HASHES_FAILED";
|
|
36
|
+
CofheErrorCode3["ZkMocksCalcCtHashesFailed"] = "ZK_MOCKS_CALC_CT_HASHES_FAILED";
|
|
37
|
+
CofheErrorCode3["ZkMocksVerifySignFailed"] = "ZK_MOCKS_VERIFY_SIGN_FAILED";
|
|
38
|
+
CofheErrorCode3["ZkMocksCreateProofSignatureFailed"] = "ZK_MOCKS_CREATE_PROOF_SIGNATURE_FAILED";
|
|
39
|
+
CofheErrorCode3["ZkVerifyFailed"] = "ZK_VERIFY_FAILED";
|
|
40
|
+
CofheErrorCode3["ZkPackFailed"] = "ZK_PACK_FAILED";
|
|
41
|
+
CofheErrorCode3["ZkProveFailed"] = "ZK_PROVE_FAILED";
|
|
42
|
+
CofheErrorCode3["EncryptRemainingInItems"] = "ENCRYPT_REMAINING_IN_ITEMS";
|
|
43
|
+
CofheErrorCode3["ZkUninitialized"] = "ZK_UNINITIALIZED";
|
|
44
|
+
CofheErrorCode3["ZkVerifierUrlUninitialized"] = "ZK_VERIFIER_URL_UNINITIALIZED";
|
|
45
|
+
CofheErrorCode3["ThresholdNetworkUrlUninitialized"] = "THRESHOLD_NETWORK_URL_UNINITIALIZED";
|
|
46
|
+
CofheErrorCode3["MissingConfig"] = "MISSING_CONFIG";
|
|
47
|
+
CofheErrorCode3["UnsupportedChain"] = "UNSUPPORTED_CHAIN";
|
|
48
|
+
CofheErrorCode3["MissingZkBuilderAndCrsGenerator"] = "MISSING_ZK_BUILDER_AND_CRS_GENERATOR";
|
|
49
|
+
CofheErrorCode3["MissingTfhePublicKeyDeserializer"] = "MISSING_TFHE_PUBLIC_KEY_DESERIALIZER";
|
|
50
|
+
CofheErrorCode3["MissingCompactPkeCrsDeserializer"] = "MISSING_COMPACT_PKE_CRS_DESERIALIZER";
|
|
51
|
+
CofheErrorCode3["MissingFheKey"] = "MISSING_FHE_KEY";
|
|
52
|
+
CofheErrorCode3["MissingCrs"] = "MISSING_CRS";
|
|
53
|
+
CofheErrorCode3["FetchKeysFailed"] = "FETCH_KEYS_FAILED";
|
|
54
|
+
CofheErrorCode3["PublicWalletGetChainIdFailed"] = "PUBLIC_WALLET_GET_CHAIN_ID_FAILED";
|
|
55
|
+
CofheErrorCode3["PublicWalletGetAddressesFailed"] = "PUBLIC_WALLET_GET_ADDRESSES_FAILED";
|
|
56
|
+
CofheErrorCode3["RehydrateKeysStoreFailed"] = "REHYDRATE_KEYS_STORE_FAILED";
|
|
57
|
+
return CofheErrorCode3;
|
|
58
58
|
})(CofheErrorCode || {});
|
|
59
59
|
var CofheError = class _CofheError extends Error {
|
|
60
60
|
code;
|
|
@@ -528,7 +528,7 @@ var zkVerify = async (verifierUrl, serializedBytes, address, securityZone, chain
|
|
|
528
528
|
}
|
|
529
529
|
};
|
|
530
530
|
var concatSigRecid = (signature, recid) => {
|
|
531
|
-
return signature
|
|
531
|
+
return `${signature}${(recid + 27).toString(16).padStart(2, "0")}`;
|
|
532
532
|
};
|
|
533
533
|
|
|
534
534
|
// core/encrypt/MockZkVerifierAbi.ts
|
|
@@ -1215,6 +1215,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
|
|
|
1215
1215
|
securityZone;
|
|
1216
1216
|
stepCallback;
|
|
1217
1217
|
inputItems;
|
|
1218
|
+
hpp = false;
|
|
1218
1219
|
zkvWalletClient;
|
|
1219
1220
|
tfhePublicKeyDeserializer;
|
|
1220
1221
|
compactPkeCrsDeserializer;
|
|
@@ -1344,6 +1345,20 @@ var EncryptInputsBuilder = class extends BaseBuilder {
|
|
|
1344
1345
|
getSecurityZone() {
|
|
1345
1346
|
return this.securityZone;
|
|
1346
1347
|
}
|
|
1348
|
+
/**
|
|
1349
|
+
* Example:
|
|
1350
|
+
* ```typescript
|
|
1351
|
+
* const encrypted = await encryptInputs([Encryptable.uint128(10n)])
|
|
1352
|
+
* .asHashPlusProof()
|
|
1353
|
+
* .execute();
|
|
1354
|
+
* ```
|
|
1355
|
+
*
|
|
1356
|
+
* @returns Chainable EncryptInputsBuilder instance that will return a HashPlusProofResult instead of an array of EncryptedItemInputs.
|
|
1357
|
+
*/
|
|
1358
|
+
asHashPlusProof() {
|
|
1359
|
+
this.hpp = true;
|
|
1360
|
+
return this;
|
|
1361
|
+
}
|
|
1347
1362
|
/**
|
|
1348
1363
|
* @param useWorker - Whether to use Web Workers for ZK proof generation.
|
|
1349
1364
|
*
|
|
@@ -1625,6 +1640,15 @@ var EncryptInputsBuilder = class extends BaseBuilder {
|
|
|
1625
1640
|
this.fireStepEnd("verify" /* Verify */);
|
|
1626
1641
|
return encryptedInputs;
|
|
1627
1642
|
}
|
|
1643
|
+
structsToHashPlusProof(inItems) {
|
|
1644
|
+
let hashes = [];
|
|
1645
|
+
let proof = "";
|
|
1646
|
+
for (const item of inItems) {
|
|
1647
|
+
hashes.push("0x" + item.ctHash.toString(16).padStart(64, "0"));
|
|
1648
|
+
proof += item.signature;
|
|
1649
|
+
}
|
|
1650
|
+
return [...hashes, proof];
|
|
1651
|
+
}
|
|
1628
1652
|
/**
|
|
1629
1653
|
* Final step of the encryption process. MUST BE CALLED LAST IN THE CHAIN.
|
|
1630
1654
|
*
|
|
@@ -1645,9 +1669,14 @@ var EncryptInputsBuilder = class extends BaseBuilder {
|
|
|
1645
1669
|
* @returns The encrypted inputs.
|
|
1646
1670
|
*/
|
|
1647
1671
|
async execute() {
|
|
1672
|
+
let items;
|
|
1648
1673
|
if (this.chainId === hardhat.id)
|
|
1649
|
-
|
|
1650
|
-
|
|
1674
|
+
items = await this.mocksExecute();
|
|
1675
|
+
else
|
|
1676
|
+
items = await this.productionExecute();
|
|
1677
|
+
if (this.hpp)
|
|
1678
|
+
return this.structsToHashPlusProof(items);
|
|
1679
|
+
return items;
|
|
1651
1680
|
}
|
|
1652
1681
|
};
|
|
1653
1682
|
var storeActivePermit = async (permit, publicClient, walletClient) => {
|
|
@@ -1977,6 +2006,96 @@ function computeMinuteRampPollIntervalMs(elapsedMs, params) {
|
|
|
1977
2006
|
return Math.min(params.maxIntervalMs, Math.max(params.minIntervalMs, intervalMs));
|
|
1978
2007
|
}
|
|
1979
2008
|
|
|
2009
|
+
// core/decrypt/submitRetry.ts
|
|
2010
|
+
var DEFAULT_404_RETRY_TIMEOUT_MS = 1e4;
|
|
2011
|
+
function isRetryableSubmitStatus(status) {
|
|
2012
|
+
return status === 204 || status === 404;
|
|
2013
|
+
}
|
|
2014
|
+
function normalize404RetryTimeoutMs(params) {
|
|
2015
|
+
const { timeoutMs, operationLabel, errorCode } = params;
|
|
2016
|
+
if (timeoutMs === void 0)
|
|
2017
|
+
return DEFAULT_404_RETRY_TIMEOUT_MS;
|
|
2018
|
+
if (!Number.isFinite(timeoutMs) || timeoutMs < 0) {
|
|
2019
|
+
throw new CofheError({
|
|
2020
|
+
code: errorCode,
|
|
2021
|
+
message: `${operationLabel} submit 404 retry timeout must be a finite number greater than or equal to 0`,
|
|
2022
|
+
context: {
|
|
2023
|
+
timeoutMs
|
|
2024
|
+
}
|
|
2025
|
+
});
|
|
2026
|
+
}
|
|
2027
|
+
return timeoutMs;
|
|
2028
|
+
}
|
|
2029
|
+
async function classifySubmitResponse(params) {
|
|
2030
|
+
const { response, extractErrorMessage } = params;
|
|
2031
|
+
if (isRetryableSubmitStatus(response.status)) {
|
|
2032
|
+
return { kind: "retryable", status: response.status };
|
|
2033
|
+
}
|
|
2034
|
+
if (response.ok) {
|
|
2035
|
+
return { kind: "parse-json" };
|
|
2036
|
+
}
|
|
2037
|
+
let errorMessage = `HTTP ${response.status}`;
|
|
2038
|
+
try {
|
|
2039
|
+
const errorBody = await response.json();
|
|
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;
|
|
2054
|
+
}
|
|
2055
|
+
return { kind: "fatal-http", errorMessage };
|
|
2056
|
+
}
|
|
2057
|
+
function throwIfSubmitRetryTimedOut(params) {
|
|
2058
|
+
const {
|
|
2059
|
+
operationLabel,
|
|
2060
|
+
errorCode,
|
|
2061
|
+
status,
|
|
2062
|
+
elapsedMs,
|
|
2063
|
+
retry404TimeoutMs,
|
|
2064
|
+
overallTimeoutMs,
|
|
2065
|
+
thresholdNetworkUrl,
|
|
2066
|
+
body,
|
|
2067
|
+
attemptIndex
|
|
2068
|
+
} = params;
|
|
2069
|
+
if (status === 404 && elapsedMs > retry404TimeoutMs) {
|
|
2070
|
+
throw new CofheError({
|
|
2071
|
+
code: errorCode,
|
|
2072
|
+
message: `${operationLabel} submit retried 404 responses without receiving request_id for ${retry404TimeoutMs}ms`,
|
|
2073
|
+
hint: "The ciphertext may not be indexed yet. Increase set404RetryTimeout(...) if the backend is slow to index ciphertexts.",
|
|
2074
|
+
context: {
|
|
2075
|
+
thresholdNetworkUrl,
|
|
2076
|
+
body,
|
|
2077
|
+
attemptIndex,
|
|
2078
|
+
timeoutMs: retry404TimeoutMs,
|
|
2079
|
+
status
|
|
2080
|
+
}
|
|
2081
|
+
});
|
|
2082
|
+
}
|
|
2083
|
+
if (elapsedMs > overallTimeoutMs) {
|
|
2084
|
+
throw new CofheError({
|
|
2085
|
+
code: errorCode,
|
|
2086
|
+
message: `${operationLabel} submit retried without receiving request_id for ${overallTimeoutMs}ms`,
|
|
2087
|
+
hint: "The ciphertext may still be propagating. Try again later.",
|
|
2088
|
+
context: {
|
|
2089
|
+
thresholdNetworkUrl,
|
|
2090
|
+
body,
|
|
2091
|
+
attemptIndex,
|
|
2092
|
+
timeoutMs: overallTimeoutMs,
|
|
2093
|
+
status
|
|
2094
|
+
}
|
|
2095
|
+
});
|
|
2096
|
+
}
|
|
2097
|
+
}
|
|
2098
|
+
|
|
1980
2099
|
// core/decrypt/tnSealOutputV2.ts
|
|
1981
2100
|
var POLL_INTERVAL_MS = 1e3;
|
|
1982
2101
|
var POLL_MAX_INTERVAL_MS = 1e4;
|
|
@@ -2038,7 +2157,7 @@ function parseCompletedSealOutputResponse(params) {
|
|
|
2038
2157
|
}
|
|
2039
2158
|
return convertSealedData(sealed);
|
|
2040
2159
|
}
|
|
2041
|
-
async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, permission, overallStartTime, onPoll) {
|
|
2160
|
+
async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, permission, overallStartTime, retry404TimeoutMs, onPoll) {
|
|
2042
2161
|
const body = {
|
|
2043
2162
|
ct_tempkey: BigInt(ctHash).toString(16).padStart(64, "0"),
|
|
2044
2163
|
host_chain_id: chainId,
|
|
@@ -2068,17 +2187,11 @@ async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, per
|
|
|
2068
2187
|
}
|
|
2069
2188
|
});
|
|
2070
2189
|
}
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
try {
|
|
2074
|
-
const errorBody = await response.json();
|
|
2075
|
-
errorMessage = errorBody.error_message || errorBody.message || errorMessage;
|
|
2076
|
-
} catch {
|
|
2077
|
-
errorMessage = response.statusText || errorMessage;
|
|
2078
|
-
}
|
|
2190
|
+
const responseClassification = await classifySubmitResponse({ response });
|
|
2191
|
+
if (responseClassification.kind === "fatal-http") {
|
|
2079
2192
|
throw new CofheError({
|
|
2080
2193
|
code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
|
|
2081
|
-
message: `sealOutput request failed: ${errorMessage}`,
|
|
2194
|
+
message: `sealOutput request failed: ${responseClassification.errorMessage}`,
|
|
2082
2195
|
hint: "Check the threshold network URL and request parameters.",
|
|
2083
2196
|
context: {
|
|
2084
2197
|
thresholdNetworkUrl,
|
|
@@ -2089,8 +2202,8 @@ async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, per
|
|
|
2089
2202
|
}
|
|
2090
2203
|
});
|
|
2091
2204
|
}
|
|
2092
|
-
|
|
2093
|
-
|
|
2205
|
+
if (responseClassification.kind === "parse-json") {
|
|
2206
|
+
let submitResponse;
|
|
2094
2207
|
try {
|
|
2095
2208
|
submitResponse = await response.json();
|
|
2096
2209
|
} catch (e) {
|
|
@@ -2118,46 +2231,39 @@ async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, per
|
|
|
2118
2231
|
if (submitResponse.request_id) {
|
|
2119
2232
|
return { kind: "request_id", requestId: submitResponse.request_id };
|
|
2120
2233
|
}
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
thresholdNetworkUrl,
|
|
2131
|
-
body,
|
|
2132
|
-
attemptIndex,
|
|
2133
|
-
timeoutMs: SEAL_OUTPUT_TIMEOUT_MS,
|
|
2134
|
-
submitResponse,
|
|
2135
|
-
status: response.status
|
|
2136
|
-
}
|
|
2137
|
-
});
|
|
2138
|
-
}
|
|
2139
|
-
onPoll?.({
|
|
2140
|
-
operation: "sealoutput",
|
|
2141
|
-
requestId: "",
|
|
2142
|
-
attemptIndex,
|
|
2143
|
-
elapsedMs,
|
|
2144
|
-
intervalMs: SUBMIT_RETRY_INTERVAL_MS,
|
|
2145
|
-
timeoutMs: SEAL_OUTPUT_TIMEOUT_MS
|
|
2234
|
+
throw new CofheError({
|
|
2235
|
+
code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
|
|
2236
|
+
message: `sealOutput submit response missing request_id`,
|
|
2237
|
+
context: {
|
|
2238
|
+
thresholdNetworkUrl,
|
|
2239
|
+
body,
|
|
2240
|
+
submitResponse,
|
|
2241
|
+
attemptIndex
|
|
2242
|
+
}
|
|
2146
2243
|
});
|
|
2147
|
-
await new Promise((resolve) => setTimeout(resolve, SUBMIT_RETRY_INTERVAL_MS));
|
|
2148
|
-
attemptIndex += 1;
|
|
2149
|
-
continue;
|
|
2150
2244
|
}
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2245
|
+
const elapsedMs = Date.now() - overallStartTime;
|
|
2246
|
+
throwIfSubmitRetryTimedOut({
|
|
2247
|
+
operationLabel: "sealOutput",
|
|
2248
|
+
errorCode: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
|
|
2249
|
+
status: responseClassification.status,
|
|
2250
|
+
elapsedMs,
|
|
2251
|
+
retry404TimeoutMs,
|
|
2252
|
+
overallTimeoutMs: SEAL_OUTPUT_TIMEOUT_MS,
|
|
2253
|
+
thresholdNetworkUrl,
|
|
2254
|
+
body,
|
|
2255
|
+
attemptIndex
|
|
2160
2256
|
});
|
|
2257
|
+
onPoll?.({
|
|
2258
|
+
operation: "sealoutput",
|
|
2259
|
+
requestId: "",
|
|
2260
|
+
attemptIndex,
|
|
2261
|
+
elapsedMs,
|
|
2262
|
+
intervalMs: SUBMIT_RETRY_INTERVAL_MS,
|
|
2263
|
+
timeoutMs: SEAL_OUTPUT_TIMEOUT_MS
|
|
2264
|
+
});
|
|
2265
|
+
await new Promise((resolve) => setTimeout(resolve, SUBMIT_RETRY_INTERVAL_MS));
|
|
2266
|
+
attemptIndex += 1;
|
|
2161
2267
|
}
|
|
2162
2268
|
}
|
|
2163
2269
|
async function pollSealOutputStatus(thresholdNetworkUrl, requestId, overallStartTime, onPoll) {
|
|
@@ -2272,7 +2378,12 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId, overallStart
|
|
|
2272
2378
|
});
|
|
2273
2379
|
}
|
|
2274
2380
|
async function tnSealOutputV2(params) {
|
|
2275
|
-
const { thresholdNetworkUrl, ctHash, chainId, permission, onPoll } = params;
|
|
2381
|
+
const { thresholdNetworkUrl, ctHash, chainId, permission, retry404TimeoutMs, onPoll } = params;
|
|
2382
|
+
const normalized404RetryTimeoutMs = normalize404RetryTimeoutMs({
|
|
2383
|
+
timeoutMs: retry404TimeoutMs,
|
|
2384
|
+
operationLabel: "sealOutput",
|
|
2385
|
+
errorCode: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */
|
|
2386
|
+
});
|
|
2276
2387
|
const overallStartTime = Date.now();
|
|
2277
2388
|
const submitResult = await submitSealOutputRequest(
|
|
2278
2389
|
thresholdNetworkUrl,
|
|
@@ -2280,6 +2391,7 @@ async function tnSealOutputV2(params) {
|
|
|
2280
2391
|
chainId,
|
|
2281
2392
|
permission,
|
|
2282
2393
|
overallStartTime,
|
|
2394
|
+
normalized404RetryTimeoutMs,
|
|
2283
2395
|
onPoll
|
|
2284
2396
|
);
|
|
2285
2397
|
if (submitResult.kind === "completed") {
|
|
@@ -2289,12 +2401,14 @@ async function tnSealOutputV2(params) {
|
|
|
2289
2401
|
}
|
|
2290
2402
|
|
|
2291
2403
|
// core/decrypt/decryptForViewBuilder.ts
|
|
2404
|
+
var DEFAULT_404_RETRY_TIMEOUT_MS2 = 1e4;
|
|
2292
2405
|
var DecryptForViewBuilder = class extends BaseBuilder {
|
|
2293
2406
|
ctHash;
|
|
2294
2407
|
utype;
|
|
2295
2408
|
permitHash;
|
|
2296
2409
|
permit;
|
|
2297
2410
|
pollCallback;
|
|
2411
|
+
retry404TimeoutMs = DEFAULT_404_RETRY_TIMEOUT_MS2;
|
|
2298
2412
|
constructor(params) {
|
|
2299
2413
|
super({
|
|
2300
2414
|
config: params.config,
|
|
@@ -2355,6 +2469,19 @@ var DecryptForViewBuilder = class extends BaseBuilder {
|
|
|
2355
2469
|
this.pollCallback = callback;
|
|
2356
2470
|
return this;
|
|
2357
2471
|
}
|
|
2472
|
+
set404RetryTimeout(timeoutMs) {
|
|
2473
|
+
if (!Number.isFinite(timeoutMs) || timeoutMs < 0) {
|
|
2474
|
+
throw new CofheError({
|
|
2475
|
+
code: "INTERNAL_ERROR" /* InternalError */,
|
|
2476
|
+
message: "decryptForView: set404RetryTimeout(timeoutMs) expects a finite number greater than or equal to 0.",
|
|
2477
|
+
context: {
|
|
2478
|
+
timeoutMs
|
|
2479
|
+
}
|
|
2480
|
+
});
|
|
2481
|
+
}
|
|
2482
|
+
this.retry404TimeoutMs = timeoutMs;
|
|
2483
|
+
return this;
|
|
2484
|
+
}
|
|
2358
2485
|
withPermit(permitOrPermitHash) {
|
|
2359
2486
|
if (typeof permitOrPermitHash === "string") {
|
|
2360
2487
|
this.permitHash = permitOrPermitHash;
|
|
@@ -2483,6 +2610,7 @@ var DecryptForViewBuilder = class extends BaseBuilder {
|
|
|
2483
2610
|
chainId: this.chainId,
|
|
2484
2611
|
permission,
|
|
2485
2612
|
thresholdNetworkUrl,
|
|
2613
|
+
retry404TimeoutMs: this.retry404TimeoutMs,
|
|
2486
2614
|
onPoll: this.pollCallback
|
|
2487
2615
|
});
|
|
2488
2616
|
return PermitUtils.unseal(permit, sealed);
|
|
@@ -2758,7 +2886,7 @@ function assertDecryptStatusResponseV2(value) {
|
|
|
2758
2886
|
}
|
|
2759
2887
|
return value;
|
|
2760
2888
|
}
|
|
2761
|
-
async function submitDecryptRequestV2(thresholdNetworkUrl, ctHash, chainId, permission, overallStartTime, onPoll) {
|
|
2889
|
+
async function submitDecryptRequestV2(thresholdNetworkUrl, ctHash, chainId, permission, overallStartTime, retry404TimeoutMs, onPoll) {
|
|
2762
2890
|
const body = {
|
|
2763
2891
|
ct_tempkey: BigInt(ctHash).toString(16).padStart(64, "0"),
|
|
2764
2892
|
host_chain_id: chainId
|
|
@@ -2790,19 +2918,11 @@ async function submitDecryptRequestV2(thresholdNetworkUrl, ctHash, chainId, perm
|
|
|
2790
2918
|
}
|
|
2791
2919
|
});
|
|
2792
2920
|
}
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
try {
|
|
2796
|
-
const errorBody = await response.json();
|
|
2797
|
-
const maybeMessage = errorBody.error_message || errorBody.message;
|
|
2798
|
-
if (typeof maybeMessage === "string" && maybeMessage.length > 0)
|
|
2799
|
-
errorMessage = maybeMessage;
|
|
2800
|
-
} catch {
|
|
2801
|
-
errorMessage = response.statusText || errorMessage;
|
|
2802
|
-
}
|
|
2921
|
+
const responseClassification = await classifySubmitResponse({ response });
|
|
2922
|
+
if (responseClassification.kind === "fatal-http") {
|
|
2803
2923
|
throw new CofheError({
|
|
2804
2924
|
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
2805
|
-
message: `decrypt request failed: ${errorMessage}`,
|
|
2925
|
+
message: `decrypt request failed: ${responseClassification.errorMessage}`,
|
|
2806
2926
|
hint: "Check the threshold network URL and request parameters.",
|
|
2807
2927
|
context: {
|
|
2808
2928
|
thresholdNetworkUrl,
|
|
@@ -2813,8 +2933,8 @@ async function submitDecryptRequestV2(thresholdNetworkUrl, ctHash, chainId, perm
|
|
|
2813
2933
|
}
|
|
2814
2934
|
});
|
|
2815
2935
|
}
|
|
2816
|
-
|
|
2817
|
-
|
|
2936
|
+
if (responseClassification.kind === "parse-json") {
|
|
2937
|
+
let submitResponse;
|
|
2818
2938
|
let rawJson;
|
|
2819
2939
|
try {
|
|
2820
2940
|
rawJson = await response.json();
|
|
@@ -2844,46 +2964,39 @@ async function submitDecryptRequestV2(thresholdNetworkUrl, ctHash, chainId, perm
|
|
|
2844
2964
|
if (submitResponse.request_id) {
|
|
2845
2965
|
return { kind: "request_id", requestId: submitResponse.request_id };
|
|
2846
2966
|
}
|
|
2847
|
-
|
|
2848
|
-
|
|
2849
|
-
|
|
2850
|
-
|
|
2851
|
-
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
|
|
2856
|
-
thresholdNetworkUrl,
|
|
2857
|
-
body,
|
|
2858
|
-
attemptIndex,
|
|
2859
|
-
timeoutMs: DECRYPT_TIMEOUT_MS,
|
|
2860
|
-
submitResponse,
|
|
2861
|
-
status: response.status
|
|
2862
|
-
}
|
|
2863
|
-
});
|
|
2864
|
-
}
|
|
2865
|
-
onPoll?.({
|
|
2866
|
-
operation: "decrypt",
|
|
2867
|
-
requestId: "",
|
|
2868
|
-
attemptIndex,
|
|
2869
|
-
elapsedMs,
|
|
2870
|
-
intervalMs: SUBMIT_RETRY_INTERVAL_MS2,
|
|
2871
|
-
timeoutMs: DECRYPT_TIMEOUT_MS
|
|
2967
|
+
throw new CofheError({
|
|
2968
|
+
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
2969
|
+
message: `decrypt submit response missing request_id`,
|
|
2970
|
+
context: {
|
|
2971
|
+
thresholdNetworkUrl,
|
|
2972
|
+
body,
|
|
2973
|
+
submitResponse,
|
|
2974
|
+
attemptIndex
|
|
2975
|
+
}
|
|
2872
2976
|
});
|
|
2873
|
-
await new Promise((resolve) => setTimeout(resolve, SUBMIT_RETRY_INTERVAL_MS2));
|
|
2874
|
-
attemptIndex += 1;
|
|
2875
|
-
continue;
|
|
2876
2977
|
}
|
|
2877
|
-
|
|
2878
|
-
|
|
2879
|
-
|
|
2880
|
-
|
|
2881
|
-
|
|
2882
|
-
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
|
|
2978
|
+
const elapsedMs = Date.now() - overallStartTime;
|
|
2979
|
+
throwIfSubmitRetryTimedOut({
|
|
2980
|
+
operationLabel: "decrypt",
|
|
2981
|
+
errorCode: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
2982
|
+
status: responseClassification.status,
|
|
2983
|
+
elapsedMs,
|
|
2984
|
+
retry404TimeoutMs,
|
|
2985
|
+
overallTimeoutMs: DECRYPT_TIMEOUT_MS,
|
|
2986
|
+
thresholdNetworkUrl,
|
|
2987
|
+
body,
|
|
2988
|
+
attemptIndex
|
|
2886
2989
|
});
|
|
2990
|
+
onPoll?.({
|
|
2991
|
+
operation: "decrypt",
|
|
2992
|
+
requestId: "",
|
|
2993
|
+
attemptIndex,
|
|
2994
|
+
elapsedMs,
|
|
2995
|
+
intervalMs: SUBMIT_RETRY_INTERVAL_MS2,
|
|
2996
|
+
timeoutMs: DECRYPT_TIMEOUT_MS
|
|
2997
|
+
});
|
|
2998
|
+
await new Promise((resolve) => setTimeout(resolve, SUBMIT_RETRY_INTERVAL_MS2));
|
|
2999
|
+
attemptIndex += 1;
|
|
2887
3000
|
}
|
|
2888
3001
|
}
|
|
2889
3002
|
async function pollDecryptStatusV2(thresholdNetworkUrl, requestId, overallStartTime, onPoll) {
|
|
@@ -3001,7 +3114,12 @@ async function pollDecryptStatusV2(thresholdNetworkUrl, requestId, overallStartT
|
|
|
3001
3114
|
});
|
|
3002
3115
|
}
|
|
3003
3116
|
async function tnDecryptV2(params) {
|
|
3004
|
-
const { thresholdNetworkUrl, ctHash, chainId, permission, onPoll } = params;
|
|
3117
|
+
const { thresholdNetworkUrl, ctHash, chainId, permission, retry404TimeoutMs, onPoll } = params;
|
|
3118
|
+
const normalized404RetryTimeoutMs = normalize404RetryTimeoutMs({
|
|
3119
|
+
timeoutMs: retry404TimeoutMs,
|
|
3120
|
+
operationLabel: "decrypt",
|
|
3121
|
+
errorCode: "DECRYPT_FAILED" /* DecryptFailed */
|
|
3122
|
+
});
|
|
3005
3123
|
const overallStartTime = Date.now();
|
|
3006
3124
|
const submitResult = await submitDecryptRequestV2(
|
|
3007
3125
|
thresholdNetworkUrl,
|
|
@@ -3009,6 +3127,7 @@ async function tnDecryptV2(params) {
|
|
|
3009
3127
|
chainId,
|
|
3010
3128
|
permission,
|
|
3011
3129
|
overallStartTime,
|
|
3130
|
+
normalized404RetryTimeoutMs,
|
|
3012
3131
|
onPoll
|
|
3013
3132
|
);
|
|
3014
3133
|
if (submitResult.kind === "completed") {
|
|
@@ -3018,12 +3137,14 @@ async function tnDecryptV2(params) {
|
|
|
3018
3137
|
}
|
|
3019
3138
|
|
|
3020
3139
|
// core/decrypt/decryptForTxBuilder.ts
|
|
3140
|
+
var DEFAULT_404_RETRY_TIMEOUT_MS3 = 1e4;
|
|
3021
3141
|
var DecryptForTxBuilder = class extends BaseBuilder {
|
|
3022
3142
|
ctHash;
|
|
3023
3143
|
permitHash;
|
|
3024
3144
|
permit;
|
|
3025
3145
|
permitSelection = "unset";
|
|
3026
3146
|
pollCallback;
|
|
3147
|
+
retry404TimeoutMs = DEFAULT_404_RETRY_TIMEOUT_MS3;
|
|
3027
3148
|
constructor(params) {
|
|
3028
3149
|
super({
|
|
3029
3150
|
config: params.config,
|
|
@@ -3053,6 +3174,19 @@ var DecryptForTxBuilder = class extends BaseBuilder {
|
|
|
3053
3174
|
this.pollCallback = callback;
|
|
3054
3175
|
return this;
|
|
3055
3176
|
}
|
|
3177
|
+
set404RetryTimeout(timeoutMs) {
|
|
3178
|
+
if (!Number.isFinite(timeoutMs) || timeoutMs < 0) {
|
|
3179
|
+
throw new CofheError({
|
|
3180
|
+
code: "INTERNAL_ERROR" /* InternalError */,
|
|
3181
|
+
message: "decryptForTx: set404RetryTimeout(timeoutMs) expects a finite number greater than or equal to 0.",
|
|
3182
|
+
context: {
|
|
3183
|
+
timeoutMs
|
|
3184
|
+
}
|
|
3185
|
+
});
|
|
3186
|
+
}
|
|
3187
|
+
this.retry404TimeoutMs = timeoutMs;
|
|
3188
|
+
return this;
|
|
3189
|
+
}
|
|
3056
3190
|
withPermit(permitOrPermitHash) {
|
|
3057
3191
|
if (this.permitSelection === "with-permit") {
|
|
3058
3192
|
throw new CofheError({
|
|
@@ -3185,6 +3319,7 @@ var DecryptForTxBuilder = class extends BaseBuilder {
|
|
|
3185
3319
|
chainId: this.chainId,
|
|
3186
3320
|
permission,
|
|
3187
3321
|
thresholdNetworkUrl,
|
|
3322
|
+
retry404TimeoutMs: this.retry404TimeoutMs,
|
|
3188
3323
|
onPoll: this.pollCallback
|
|
3189
3324
|
});
|
|
3190
3325
|
return {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { TASK_MANAGER_ADDRESS } from './chunk-
|
|
1
|
+
import { TASK_MANAGER_ADDRESS } from './chunk-ESMZCFJY.js';
|
|
2
2
|
import { isAddress, getAddress, zeroAddress, isHex, keccak256, toHex, BaseError, ContractFunctionRevertedError, decodeErrorResult, parseAbi } from 'viem';
|
|
3
3
|
import nacl from 'tweetnacl';
|
|
4
4
|
import { z } from 'zod';
|