@cofhe/sdk 0.5.0 → 0.5.2
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 +16 -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/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/test/decryptBuilders.test.ts +28 -0
- package/core/test/pollCallbacks.test.ts +226 -0
- package/dist/{chunk-S7OKGLFD.js → chunk-YDOK4BDL.js} +253 -147
- package/dist/{clientTypes-BSbwairE.d.cts → clientTypes-BJbFeeno.d.cts} +5 -0
- package/dist/{clientTypes-DDmcgZ0a.d.ts → clientTypes-CEno_BEf.d.ts} +5 -0
- package/dist/core.cjs +253 -147
- package/dist/core.d.cts +2 -2
- package/dist/core.d.ts +2 -2
- package/dist/core.js +1 -1
- package/dist/node.cjs +208 -102
- package/dist/node.d.cts +1 -1
- package/dist/node.d.ts +1 -1
- package/dist/node.js +1 -1
- package/dist/web.cjs +226 -109
- package/dist/web.d.cts +1 -1
- package/dist/web.d.ts +1 -1
- package/dist/web.js +19 -7
- package/dist/zkProve.worker.cjs +69 -64
- package/dist/zkProve.worker.js +69 -64
- package/package.json +2 -2
- package/web/index.ts +22 -7
- package/web/test/tfheinit.web.test.ts +3 -3
- package/web/zkProve.worker.ts +93 -84
|
@@ -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;
|
|
@@ -1977,6 +1977,96 @@ function computeMinuteRampPollIntervalMs(elapsedMs, params) {
|
|
|
1977
1977
|
return Math.min(params.maxIntervalMs, Math.max(params.minIntervalMs, intervalMs));
|
|
1978
1978
|
}
|
|
1979
1979
|
|
|
1980
|
+
// core/decrypt/submitRetry.ts
|
|
1981
|
+
var DEFAULT_404_RETRY_TIMEOUT_MS = 1e4;
|
|
1982
|
+
function isRetryableSubmitStatus(status) {
|
|
1983
|
+
return status === 204 || status === 404;
|
|
1984
|
+
}
|
|
1985
|
+
function normalize404RetryTimeoutMs(params) {
|
|
1986
|
+
const { timeoutMs, operationLabel, errorCode } = params;
|
|
1987
|
+
if (timeoutMs === void 0)
|
|
1988
|
+
return DEFAULT_404_RETRY_TIMEOUT_MS;
|
|
1989
|
+
if (!Number.isFinite(timeoutMs) || timeoutMs < 0) {
|
|
1990
|
+
throw new CofheError({
|
|
1991
|
+
code: errorCode,
|
|
1992
|
+
message: `${operationLabel} submit 404 retry timeout must be a finite number greater than or equal to 0`,
|
|
1993
|
+
context: {
|
|
1994
|
+
timeoutMs
|
|
1995
|
+
}
|
|
1996
|
+
});
|
|
1997
|
+
}
|
|
1998
|
+
return timeoutMs;
|
|
1999
|
+
}
|
|
2000
|
+
async function classifySubmitResponse(params) {
|
|
2001
|
+
const { response, extractErrorMessage } = params;
|
|
2002
|
+
if (isRetryableSubmitStatus(response.status)) {
|
|
2003
|
+
return { kind: "retryable", status: response.status };
|
|
2004
|
+
}
|
|
2005
|
+
if (response.ok) {
|
|
2006
|
+
return { kind: "parse-json" };
|
|
2007
|
+
}
|
|
2008
|
+
let errorMessage = `HTTP ${response.status}`;
|
|
2009
|
+
try {
|
|
2010
|
+
const errorBody = await response.json();
|
|
2011
|
+
const maybeErrorMessage = extractErrorMessage?.(errorBody);
|
|
2012
|
+
if (typeof maybeErrorMessage === "string" && maybeErrorMessage.length > 0) {
|
|
2013
|
+
errorMessage = maybeErrorMessage;
|
|
2014
|
+
} else if (errorBody && typeof errorBody === "object") {
|
|
2015
|
+
const defaultMessage = errorBody.error_message;
|
|
2016
|
+
const fallbackMessage = errorBody.message;
|
|
2017
|
+
if (typeof defaultMessage === "string" && defaultMessage.length > 0) {
|
|
2018
|
+
errorMessage = defaultMessage;
|
|
2019
|
+
} else if (typeof fallbackMessage === "string" && fallbackMessage.length > 0) {
|
|
2020
|
+
errorMessage = fallbackMessage;
|
|
2021
|
+
}
|
|
2022
|
+
}
|
|
2023
|
+
} catch {
|
|
2024
|
+
errorMessage = response.statusText || errorMessage;
|
|
2025
|
+
}
|
|
2026
|
+
return { kind: "fatal-http", errorMessage };
|
|
2027
|
+
}
|
|
2028
|
+
function throwIfSubmitRetryTimedOut(params) {
|
|
2029
|
+
const {
|
|
2030
|
+
operationLabel,
|
|
2031
|
+
errorCode,
|
|
2032
|
+
status,
|
|
2033
|
+
elapsedMs,
|
|
2034
|
+
retry404TimeoutMs,
|
|
2035
|
+
overallTimeoutMs,
|
|
2036
|
+
thresholdNetworkUrl,
|
|
2037
|
+
body,
|
|
2038
|
+
attemptIndex
|
|
2039
|
+
} = params;
|
|
2040
|
+
if (status === 404 && elapsedMs > retry404TimeoutMs) {
|
|
2041
|
+
throw new CofheError({
|
|
2042
|
+
code: errorCode,
|
|
2043
|
+
message: `${operationLabel} submit retried 404 responses without receiving request_id for ${retry404TimeoutMs}ms`,
|
|
2044
|
+
hint: "The ciphertext may not be indexed yet. Increase set404RetryTimeout(...) if the backend is slow to index ciphertexts.",
|
|
2045
|
+
context: {
|
|
2046
|
+
thresholdNetworkUrl,
|
|
2047
|
+
body,
|
|
2048
|
+
attemptIndex,
|
|
2049
|
+
timeoutMs: retry404TimeoutMs,
|
|
2050
|
+
status
|
|
2051
|
+
}
|
|
2052
|
+
});
|
|
2053
|
+
}
|
|
2054
|
+
if (elapsedMs > overallTimeoutMs) {
|
|
2055
|
+
throw new CofheError({
|
|
2056
|
+
code: errorCode,
|
|
2057
|
+
message: `${operationLabel} submit retried without receiving request_id for ${overallTimeoutMs}ms`,
|
|
2058
|
+
hint: "The ciphertext may still be propagating. Try again later.",
|
|
2059
|
+
context: {
|
|
2060
|
+
thresholdNetworkUrl,
|
|
2061
|
+
body,
|
|
2062
|
+
attemptIndex,
|
|
2063
|
+
timeoutMs: overallTimeoutMs,
|
|
2064
|
+
status
|
|
2065
|
+
}
|
|
2066
|
+
});
|
|
2067
|
+
}
|
|
2068
|
+
}
|
|
2069
|
+
|
|
1980
2070
|
// core/decrypt/tnSealOutputV2.ts
|
|
1981
2071
|
var POLL_INTERVAL_MS = 1e3;
|
|
1982
2072
|
var POLL_MAX_INTERVAL_MS = 1e4;
|
|
@@ -2038,7 +2128,7 @@ function parseCompletedSealOutputResponse(params) {
|
|
|
2038
2128
|
}
|
|
2039
2129
|
return convertSealedData(sealed);
|
|
2040
2130
|
}
|
|
2041
|
-
async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, permission, overallStartTime, onPoll) {
|
|
2131
|
+
async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, permission, overallStartTime, retry404TimeoutMs, onPoll) {
|
|
2042
2132
|
const body = {
|
|
2043
2133
|
ct_tempkey: BigInt(ctHash).toString(16).padStart(64, "0"),
|
|
2044
2134
|
host_chain_id: chainId,
|
|
@@ -2068,17 +2158,11 @@ async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, per
|
|
|
2068
2158
|
}
|
|
2069
2159
|
});
|
|
2070
2160
|
}
|
|
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
|
-
}
|
|
2161
|
+
const responseClassification = await classifySubmitResponse({ response });
|
|
2162
|
+
if (responseClassification.kind === "fatal-http") {
|
|
2079
2163
|
throw new CofheError({
|
|
2080
2164
|
code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
|
|
2081
|
-
message: `sealOutput request failed: ${errorMessage}`,
|
|
2165
|
+
message: `sealOutput request failed: ${responseClassification.errorMessage}`,
|
|
2082
2166
|
hint: "Check the threshold network URL and request parameters.",
|
|
2083
2167
|
context: {
|
|
2084
2168
|
thresholdNetworkUrl,
|
|
@@ -2089,8 +2173,8 @@ async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, per
|
|
|
2089
2173
|
}
|
|
2090
2174
|
});
|
|
2091
2175
|
}
|
|
2092
|
-
|
|
2093
|
-
|
|
2176
|
+
if (responseClassification.kind === "parse-json") {
|
|
2177
|
+
let submitResponse;
|
|
2094
2178
|
try {
|
|
2095
2179
|
submitResponse = await response.json();
|
|
2096
2180
|
} catch (e) {
|
|
@@ -2118,46 +2202,39 @@ async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, per
|
|
|
2118
2202
|
if (submitResponse.request_id) {
|
|
2119
2203
|
return { kind: "request_id", requestId: submitResponse.request_id };
|
|
2120
2204
|
}
|
|
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
|
|
2205
|
+
throw new CofheError({
|
|
2206
|
+
code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
|
|
2207
|
+
message: `sealOutput submit response missing request_id`,
|
|
2208
|
+
context: {
|
|
2209
|
+
thresholdNetworkUrl,
|
|
2210
|
+
body,
|
|
2211
|
+
submitResponse,
|
|
2212
|
+
attemptIndex
|
|
2213
|
+
}
|
|
2146
2214
|
});
|
|
2147
|
-
await new Promise((resolve) => setTimeout(resolve, SUBMIT_RETRY_INTERVAL_MS));
|
|
2148
|
-
attemptIndex += 1;
|
|
2149
|
-
continue;
|
|
2150
2215
|
}
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2216
|
+
const elapsedMs = Date.now() - overallStartTime;
|
|
2217
|
+
throwIfSubmitRetryTimedOut({
|
|
2218
|
+
operationLabel: "sealOutput",
|
|
2219
|
+
errorCode: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
|
|
2220
|
+
status: responseClassification.status,
|
|
2221
|
+
elapsedMs,
|
|
2222
|
+
retry404TimeoutMs,
|
|
2223
|
+
overallTimeoutMs: SEAL_OUTPUT_TIMEOUT_MS,
|
|
2224
|
+
thresholdNetworkUrl,
|
|
2225
|
+
body,
|
|
2226
|
+
attemptIndex
|
|
2160
2227
|
});
|
|
2228
|
+
onPoll?.({
|
|
2229
|
+
operation: "sealoutput",
|
|
2230
|
+
requestId: "",
|
|
2231
|
+
attemptIndex,
|
|
2232
|
+
elapsedMs,
|
|
2233
|
+
intervalMs: SUBMIT_RETRY_INTERVAL_MS,
|
|
2234
|
+
timeoutMs: SEAL_OUTPUT_TIMEOUT_MS
|
|
2235
|
+
});
|
|
2236
|
+
await new Promise((resolve) => setTimeout(resolve, SUBMIT_RETRY_INTERVAL_MS));
|
|
2237
|
+
attemptIndex += 1;
|
|
2161
2238
|
}
|
|
2162
2239
|
}
|
|
2163
2240
|
async function pollSealOutputStatus(thresholdNetworkUrl, requestId, overallStartTime, onPoll) {
|
|
@@ -2272,7 +2349,12 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId, overallStart
|
|
|
2272
2349
|
});
|
|
2273
2350
|
}
|
|
2274
2351
|
async function tnSealOutputV2(params) {
|
|
2275
|
-
const { thresholdNetworkUrl, ctHash, chainId, permission, onPoll } = params;
|
|
2352
|
+
const { thresholdNetworkUrl, ctHash, chainId, permission, retry404TimeoutMs, onPoll } = params;
|
|
2353
|
+
const normalized404RetryTimeoutMs = normalize404RetryTimeoutMs({
|
|
2354
|
+
timeoutMs: retry404TimeoutMs,
|
|
2355
|
+
operationLabel: "sealOutput",
|
|
2356
|
+
errorCode: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */
|
|
2357
|
+
});
|
|
2276
2358
|
const overallStartTime = Date.now();
|
|
2277
2359
|
const submitResult = await submitSealOutputRequest(
|
|
2278
2360
|
thresholdNetworkUrl,
|
|
@@ -2280,6 +2362,7 @@ async function tnSealOutputV2(params) {
|
|
|
2280
2362
|
chainId,
|
|
2281
2363
|
permission,
|
|
2282
2364
|
overallStartTime,
|
|
2365
|
+
normalized404RetryTimeoutMs,
|
|
2283
2366
|
onPoll
|
|
2284
2367
|
);
|
|
2285
2368
|
if (submitResult.kind === "completed") {
|
|
@@ -2289,12 +2372,14 @@ async function tnSealOutputV2(params) {
|
|
|
2289
2372
|
}
|
|
2290
2373
|
|
|
2291
2374
|
// core/decrypt/decryptForViewBuilder.ts
|
|
2375
|
+
var DEFAULT_404_RETRY_TIMEOUT_MS2 = 1e4;
|
|
2292
2376
|
var DecryptForViewBuilder = class extends BaseBuilder {
|
|
2293
2377
|
ctHash;
|
|
2294
2378
|
utype;
|
|
2295
2379
|
permitHash;
|
|
2296
2380
|
permit;
|
|
2297
2381
|
pollCallback;
|
|
2382
|
+
retry404TimeoutMs = DEFAULT_404_RETRY_TIMEOUT_MS2;
|
|
2298
2383
|
constructor(params) {
|
|
2299
2384
|
super({
|
|
2300
2385
|
config: params.config,
|
|
@@ -2355,6 +2440,19 @@ var DecryptForViewBuilder = class extends BaseBuilder {
|
|
|
2355
2440
|
this.pollCallback = callback;
|
|
2356
2441
|
return this;
|
|
2357
2442
|
}
|
|
2443
|
+
set404RetryTimeout(timeoutMs) {
|
|
2444
|
+
if (!Number.isFinite(timeoutMs) || timeoutMs < 0) {
|
|
2445
|
+
throw new CofheError({
|
|
2446
|
+
code: "INTERNAL_ERROR" /* InternalError */,
|
|
2447
|
+
message: "decryptForView: set404RetryTimeout(timeoutMs) expects a finite number greater than or equal to 0.",
|
|
2448
|
+
context: {
|
|
2449
|
+
timeoutMs
|
|
2450
|
+
}
|
|
2451
|
+
});
|
|
2452
|
+
}
|
|
2453
|
+
this.retry404TimeoutMs = timeoutMs;
|
|
2454
|
+
return this;
|
|
2455
|
+
}
|
|
2358
2456
|
withPermit(permitOrPermitHash) {
|
|
2359
2457
|
if (typeof permitOrPermitHash === "string") {
|
|
2360
2458
|
this.permitHash = permitOrPermitHash;
|
|
@@ -2483,6 +2581,7 @@ var DecryptForViewBuilder = class extends BaseBuilder {
|
|
|
2483
2581
|
chainId: this.chainId,
|
|
2484
2582
|
permission,
|
|
2485
2583
|
thresholdNetworkUrl,
|
|
2584
|
+
retry404TimeoutMs: this.retry404TimeoutMs,
|
|
2486
2585
|
onPoll: this.pollCallback
|
|
2487
2586
|
});
|
|
2488
2587
|
return PermitUtils.unseal(permit, sealed);
|
|
@@ -2758,7 +2857,7 @@ function assertDecryptStatusResponseV2(value) {
|
|
|
2758
2857
|
}
|
|
2759
2858
|
return value;
|
|
2760
2859
|
}
|
|
2761
|
-
async function submitDecryptRequestV2(thresholdNetworkUrl, ctHash, chainId, permission, overallStartTime, onPoll) {
|
|
2860
|
+
async function submitDecryptRequestV2(thresholdNetworkUrl, ctHash, chainId, permission, overallStartTime, retry404TimeoutMs, onPoll) {
|
|
2762
2861
|
const body = {
|
|
2763
2862
|
ct_tempkey: BigInt(ctHash).toString(16).padStart(64, "0"),
|
|
2764
2863
|
host_chain_id: chainId
|
|
@@ -2790,19 +2889,11 @@ async function submitDecryptRequestV2(thresholdNetworkUrl, ctHash, chainId, perm
|
|
|
2790
2889
|
}
|
|
2791
2890
|
});
|
|
2792
2891
|
}
|
|
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
|
-
}
|
|
2892
|
+
const responseClassification = await classifySubmitResponse({ response });
|
|
2893
|
+
if (responseClassification.kind === "fatal-http") {
|
|
2803
2894
|
throw new CofheError({
|
|
2804
2895
|
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
2805
|
-
message: `decrypt request failed: ${errorMessage}`,
|
|
2896
|
+
message: `decrypt request failed: ${responseClassification.errorMessage}`,
|
|
2806
2897
|
hint: "Check the threshold network URL and request parameters.",
|
|
2807
2898
|
context: {
|
|
2808
2899
|
thresholdNetworkUrl,
|
|
@@ -2813,8 +2904,8 @@ async function submitDecryptRequestV2(thresholdNetworkUrl, ctHash, chainId, perm
|
|
|
2813
2904
|
}
|
|
2814
2905
|
});
|
|
2815
2906
|
}
|
|
2816
|
-
|
|
2817
|
-
|
|
2907
|
+
if (responseClassification.kind === "parse-json") {
|
|
2908
|
+
let submitResponse;
|
|
2818
2909
|
let rawJson;
|
|
2819
2910
|
try {
|
|
2820
2911
|
rawJson = await response.json();
|
|
@@ -2844,46 +2935,39 @@ async function submitDecryptRequestV2(thresholdNetworkUrl, ctHash, chainId, perm
|
|
|
2844
2935
|
if (submitResponse.request_id) {
|
|
2845
2936
|
return { kind: "request_id", requestId: submitResponse.request_id };
|
|
2846
2937
|
}
|
|
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
|
|
2938
|
+
throw new CofheError({
|
|
2939
|
+
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
2940
|
+
message: `decrypt submit response missing request_id`,
|
|
2941
|
+
context: {
|
|
2942
|
+
thresholdNetworkUrl,
|
|
2943
|
+
body,
|
|
2944
|
+
submitResponse,
|
|
2945
|
+
attemptIndex
|
|
2946
|
+
}
|
|
2872
2947
|
});
|
|
2873
|
-
await new Promise((resolve) => setTimeout(resolve, SUBMIT_RETRY_INTERVAL_MS2));
|
|
2874
|
-
attemptIndex += 1;
|
|
2875
|
-
continue;
|
|
2876
2948
|
}
|
|
2877
|
-
|
|
2878
|
-
|
|
2879
|
-
|
|
2880
|
-
|
|
2881
|
-
|
|
2882
|
-
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
|
|
2949
|
+
const elapsedMs = Date.now() - overallStartTime;
|
|
2950
|
+
throwIfSubmitRetryTimedOut({
|
|
2951
|
+
operationLabel: "decrypt",
|
|
2952
|
+
errorCode: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
2953
|
+
status: responseClassification.status,
|
|
2954
|
+
elapsedMs,
|
|
2955
|
+
retry404TimeoutMs,
|
|
2956
|
+
overallTimeoutMs: DECRYPT_TIMEOUT_MS,
|
|
2957
|
+
thresholdNetworkUrl,
|
|
2958
|
+
body,
|
|
2959
|
+
attemptIndex
|
|
2886
2960
|
});
|
|
2961
|
+
onPoll?.({
|
|
2962
|
+
operation: "decrypt",
|
|
2963
|
+
requestId: "",
|
|
2964
|
+
attemptIndex,
|
|
2965
|
+
elapsedMs,
|
|
2966
|
+
intervalMs: SUBMIT_RETRY_INTERVAL_MS2,
|
|
2967
|
+
timeoutMs: DECRYPT_TIMEOUT_MS
|
|
2968
|
+
});
|
|
2969
|
+
await new Promise((resolve) => setTimeout(resolve, SUBMIT_RETRY_INTERVAL_MS2));
|
|
2970
|
+
attemptIndex += 1;
|
|
2887
2971
|
}
|
|
2888
2972
|
}
|
|
2889
2973
|
async function pollDecryptStatusV2(thresholdNetworkUrl, requestId, overallStartTime, onPoll) {
|
|
@@ -3001,7 +3085,12 @@ async function pollDecryptStatusV2(thresholdNetworkUrl, requestId, overallStartT
|
|
|
3001
3085
|
});
|
|
3002
3086
|
}
|
|
3003
3087
|
async function tnDecryptV2(params) {
|
|
3004
|
-
const { thresholdNetworkUrl, ctHash, chainId, permission, onPoll } = params;
|
|
3088
|
+
const { thresholdNetworkUrl, ctHash, chainId, permission, retry404TimeoutMs, onPoll } = params;
|
|
3089
|
+
const normalized404RetryTimeoutMs = normalize404RetryTimeoutMs({
|
|
3090
|
+
timeoutMs: retry404TimeoutMs,
|
|
3091
|
+
operationLabel: "decrypt",
|
|
3092
|
+
errorCode: "DECRYPT_FAILED" /* DecryptFailed */
|
|
3093
|
+
});
|
|
3005
3094
|
const overallStartTime = Date.now();
|
|
3006
3095
|
const submitResult = await submitDecryptRequestV2(
|
|
3007
3096
|
thresholdNetworkUrl,
|
|
@@ -3009,6 +3098,7 @@ async function tnDecryptV2(params) {
|
|
|
3009
3098
|
chainId,
|
|
3010
3099
|
permission,
|
|
3011
3100
|
overallStartTime,
|
|
3101
|
+
normalized404RetryTimeoutMs,
|
|
3012
3102
|
onPoll
|
|
3013
3103
|
);
|
|
3014
3104
|
if (submitResult.kind === "completed") {
|
|
@@ -3018,12 +3108,14 @@ async function tnDecryptV2(params) {
|
|
|
3018
3108
|
}
|
|
3019
3109
|
|
|
3020
3110
|
// core/decrypt/decryptForTxBuilder.ts
|
|
3111
|
+
var DEFAULT_404_RETRY_TIMEOUT_MS3 = 1e4;
|
|
3021
3112
|
var DecryptForTxBuilder = class extends BaseBuilder {
|
|
3022
3113
|
ctHash;
|
|
3023
3114
|
permitHash;
|
|
3024
3115
|
permit;
|
|
3025
3116
|
permitSelection = "unset";
|
|
3026
3117
|
pollCallback;
|
|
3118
|
+
retry404TimeoutMs = DEFAULT_404_RETRY_TIMEOUT_MS3;
|
|
3027
3119
|
constructor(params) {
|
|
3028
3120
|
super({
|
|
3029
3121
|
config: params.config,
|
|
@@ -3053,6 +3145,19 @@ var DecryptForTxBuilder = class extends BaseBuilder {
|
|
|
3053
3145
|
this.pollCallback = callback;
|
|
3054
3146
|
return this;
|
|
3055
3147
|
}
|
|
3148
|
+
set404RetryTimeout(timeoutMs) {
|
|
3149
|
+
if (!Number.isFinite(timeoutMs) || timeoutMs < 0) {
|
|
3150
|
+
throw new CofheError({
|
|
3151
|
+
code: "INTERNAL_ERROR" /* InternalError */,
|
|
3152
|
+
message: "decryptForTx: set404RetryTimeout(timeoutMs) expects a finite number greater than or equal to 0.",
|
|
3153
|
+
context: {
|
|
3154
|
+
timeoutMs
|
|
3155
|
+
}
|
|
3156
|
+
});
|
|
3157
|
+
}
|
|
3158
|
+
this.retry404TimeoutMs = timeoutMs;
|
|
3159
|
+
return this;
|
|
3160
|
+
}
|
|
3056
3161
|
withPermit(permitOrPermitHash) {
|
|
3057
3162
|
if (this.permitSelection === "with-permit") {
|
|
3058
3163
|
throw new CofheError({
|
|
@@ -3185,6 +3290,7 @@ var DecryptForTxBuilder = class extends BaseBuilder {
|
|
|
3185
3290
|
chainId: this.chainId,
|
|
3186
3291
|
permission,
|
|
3187
3292
|
thresholdNetworkUrl,
|
|
3293
|
+
retry404TimeoutMs: this.retry404TimeoutMs,
|
|
3188
3294
|
onPoll: this.pollCallback
|
|
3189
3295
|
});
|
|
3190
3296
|
return {
|
|
@@ -371,6 +371,7 @@ declare class DecryptForViewBuilder<U extends FheTypes> extends BaseBuilder {
|
|
|
371
371
|
private permitHash?;
|
|
372
372
|
private permit?;
|
|
373
373
|
private pollCallback?;
|
|
374
|
+
private retry404TimeoutMs;
|
|
374
375
|
constructor(params: DecryptForViewBuilderParams<U>);
|
|
375
376
|
/**
|
|
376
377
|
* @param chainId - Chain to decrypt values from. Used to fetch the threshold network URL and use the correct permit.
|
|
@@ -405,6 +406,7 @@ declare class DecryptForViewBuilder<U extends FheTypes> extends BaseBuilder {
|
|
|
405
406
|
setAccount(account: string): DecryptForViewBuilder<U>;
|
|
406
407
|
getAccount(): string | undefined;
|
|
407
408
|
onPoll(callback: DecryptPollCallbackFunction): DecryptForViewBuilder<U>;
|
|
409
|
+
set404RetryTimeout(timeoutMs: number): DecryptForViewBuilder<U>;
|
|
408
410
|
/**
|
|
409
411
|
* Select "use permit" mode (optional).
|
|
410
412
|
*
|
|
@@ -507,6 +509,7 @@ declare class DecryptForTxBuilder extends BaseBuilder {
|
|
|
507
509
|
private permit?;
|
|
508
510
|
private permitSelection;
|
|
509
511
|
private pollCallback?;
|
|
512
|
+
private retry404TimeoutMs;
|
|
510
513
|
constructor(params: DecryptForTxBuilderParams);
|
|
511
514
|
/**
|
|
512
515
|
* @param chainId - Chain to decrypt values from. Used to fetch the threshold network URL and use the correct permit.
|
|
@@ -544,6 +547,8 @@ declare class DecryptForTxBuilder extends BaseBuilder {
|
|
|
544
547
|
getAccount(): string | undefined;
|
|
545
548
|
onPoll(this: DecryptForTxBuilderUnset, callback: DecryptPollCallbackFunction): DecryptForTxBuilderUnset;
|
|
546
549
|
onPoll(this: DecryptForTxBuilderSelected, callback: DecryptPollCallbackFunction): DecryptForTxBuilderSelected;
|
|
550
|
+
set404RetryTimeout(this: DecryptForTxBuilderUnset, timeoutMs: number): DecryptForTxBuilderUnset;
|
|
551
|
+
set404RetryTimeout(this: DecryptForTxBuilderSelected, timeoutMs: number): DecryptForTxBuilderSelected;
|
|
547
552
|
/**
|
|
548
553
|
* Select "use permit" mode.
|
|
549
554
|
*
|
|
@@ -371,6 +371,7 @@ declare class DecryptForViewBuilder<U extends FheTypes> extends BaseBuilder {
|
|
|
371
371
|
private permitHash?;
|
|
372
372
|
private permit?;
|
|
373
373
|
private pollCallback?;
|
|
374
|
+
private retry404TimeoutMs;
|
|
374
375
|
constructor(params: DecryptForViewBuilderParams<U>);
|
|
375
376
|
/**
|
|
376
377
|
* @param chainId - Chain to decrypt values from. Used to fetch the threshold network URL and use the correct permit.
|
|
@@ -405,6 +406,7 @@ declare class DecryptForViewBuilder<U extends FheTypes> extends BaseBuilder {
|
|
|
405
406
|
setAccount(account: string): DecryptForViewBuilder<U>;
|
|
406
407
|
getAccount(): string | undefined;
|
|
407
408
|
onPoll(callback: DecryptPollCallbackFunction): DecryptForViewBuilder<U>;
|
|
409
|
+
set404RetryTimeout(timeoutMs: number): DecryptForViewBuilder<U>;
|
|
408
410
|
/**
|
|
409
411
|
* Select "use permit" mode (optional).
|
|
410
412
|
*
|
|
@@ -507,6 +509,7 @@ declare class DecryptForTxBuilder extends BaseBuilder {
|
|
|
507
509
|
private permit?;
|
|
508
510
|
private permitSelection;
|
|
509
511
|
private pollCallback?;
|
|
512
|
+
private retry404TimeoutMs;
|
|
510
513
|
constructor(params: DecryptForTxBuilderParams);
|
|
511
514
|
/**
|
|
512
515
|
* @param chainId - Chain to decrypt values from. Used to fetch the threshold network URL and use the correct permit.
|
|
@@ -544,6 +547,8 @@ declare class DecryptForTxBuilder extends BaseBuilder {
|
|
|
544
547
|
getAccount(): string | undefined;
|
|
545
548
|
onPoll(this: DecryptForTxBuilderUnset, callback: DecryptPollCallbackFunction): DecryptForTxBuilderUnset;
|
|
546
549
|
onPoll(this: DecryptForTxBuilderSelected, callback: DecryptPollCallbackFunction): DecryptForTxBuilderSelected;
|
|
550
|
+
set404RetryTimeout(this: DecryptForTxBuilderUnset, timeoutMs: number): DecryptForTxBuilderUnset;
|
|
551
|
+
set404RetryTimeout(this: DecryptForTxBuilderSelected, timeoutMs: number): DecryptForTxBuilderSelected;
|
|
547
552
|
/**
|
|
548
553
|
* Select "use permit" mode.
|
|
549
554
|
*
|