@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
package/dist/core.cjs
CHANGED
|
@@ -16,51 +16,51 @@ var nacl__default = /*#__PURE__*/_interopDefault(nacl);
|
|
|
16
16
|
// core/client.ts
|
|
17
17
|
|
|
18
18
|
// core/error.ts
|
|
19
|
-
var CofheErrorCode = /* @__PURE__ */ ((
|
|
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
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
return
|
|
19
|
+
var CofheErrorCode = /* @__PURE__ */ ((CofheErrorCode3) => {
|
|
20
|
+
CofheErrorCode3["InternalError"] = "INTERNAL_ERROR";
|
|
21
|
+
CofheErrorCode3["UnknownEnvironment"] = "UNKNOWN_ENVIRONMENT";
|
|
22
|
+
CofheErrorCode3["InitTfheFailed"] = "INIT_TFHE_FAILED";
|
|
23
|
+
CofheErrorCode3["InitViemFailed"] = "INIT_VIEM_FAILED";
|
|
24
|
+
CofheErrorCode3["InitEthersFailed"] = "INIT_ETHERS_FAILED";
|
|
25
|
+
CofheErrorCode3["NotConnected"] = "NOT_CONNECTED";
|
|
26
|
+
CofheErrorCode3["MissingPublicClient"] = "MISSING_PUBLIC_CLIENT";
|
|
27
|
+
CofheErrorCode3["MissingWalletClient"] = "MISSING_WALLET_CLIENT";
|
|
28
|
+
CofheErrorCode3["MissingProviderParam"] = "MISSING_PROVIDER_PARAM";
|
|
29
|
+
CofheErrorCode3["EmptySecurityZonesParam"] = "EMPTY_SECURITY_ZONES_PARAM";
|
|
30
|
+
CofheErrorCode3["InvalidPermitData"] = "INVALID_PERMIT_DATA";
|
|
31
|
+
CofheErrorCode3["InvalidPermitDomain"] = "INVALID_PERMIT_DOMAIN";
|
|
32
|
+
CofheErrorCode3["PermitNotFound"] = "PERMIT_NOT_FOUND";
|
|
33
|
+
CofheErrorCode3["CannotRemoveLastPermit"] = "CANNOT_REMOVE_LAST_PERMIT";
|
|
34
|
+
CofheErrorCode3["AccountUninitialized"] = "ACCOUNT_UNINITIALIZED";
|
|
35
|
+
CofheErrorCode3["ChainIdUninitialized"] = "CHAIN_ID_UNINITIALIZED";
|
|
36
|
+
CofheErrorCode3["SealOutputFailed"] = "SEAL_OUTPUT_FAILED";
|
|
37
|
+
CofheErrorCode3["SealOutputReturnedNull"] = "SEAL_OUTPUT_RETURNED_NULL";
|
|
38
|
+
CofheErrorCode3["InvalidUtype"] = "INVALID_UTYPE";
|
|
39
|
+
CofheErrorCode3["DecryptFailed"] = "DECRYPT_FAILED";
|
|
40
|
+
CofheErrorCode3["DecryptReturnedNull"] = "DECRYPT_RETURNED_NULL";
|
|
41
|
+
CofheErrorCode3["ZkMocksInsertCtHashesFailed"] = "ZK_MOCKS_INSERT_CT_HASHES_FAILED";
|
|
42
|
+
CofheErrorCode3["ZkMocksCalcCtHashesFailed"] = "ZK_MOCKS_CALC_CT_HASHES_FAILED";
|
|
43
|
+
CofheErrorCode3["ZkMocksVerifySignFailed"] = "ZK_MOCKS_VERIFY_SIGN_FAILED";
|
|
44
|
+
CofheErrorCode3["ZkMocksCreateProofSignatureFailed"] = "ZK_MOCKS_CREATE_PROOF_SIGNATURE_FAILED";
|
|
45
|
+
CofheErrorCode3["ZkVerifyFailed"] = "ZK_VERIFY_FAILED";
|
|
46
|
+
CofheErrorCode3["ZkPackFailed"] = "ZK_PACK_FAILED";
|
|
47
|
+
CofheErrorCode3["ZkProveFailed"] = "ZK_PROVE_FAILED";
|
|
48
|
+
CofheErrorCode3["EncryptRemainingInItems"] = "ENCRYPT_REMAINING_IN_ITEMS";
|
|
49
|
+
CofheErrorCode3["ZkUninitialized"] = "ZK_UNINITIALIZED";
|
|
50
|
+
CofheErrorCode3["ZkVerifierUrlUninitialized"] = "ZK_VERIFIER_URL_UNINITIALIZED";
|
|
51
|
+
CofheErrorCode3["ThresholdNetworkUrlUninitialized"] = "THRESHOLD_NETWORK_URL_UNINITIALIZED";
|
|
52
|
+
CofheErrorCode3["MissingConfig"] = "MISSING_CONFIG";
|
|
53
|
+
CofheErrorCode3["UnsupportedChain"] = "UNSUPPORTED_CHAIN";
|
|
54
|
+
CofheErrorCode3["MissingZkBuilderAndCrsGenerator"] = "MISSING_ZK_BUILDER_AND_CRS_GENERATOR";
|
|
55
|
+
CofheErrorCode3["MissingTfhePublicKeyDeserializer"] = "MISSING_TFHE_PUBLIC_KEY_DESERIALIZER";
|
|
56
|
+
CofheErrorCode3["MissingCompactPkeCrsDeserializer"] = "MISSING_COMPACT_PKE_CRS_DESERIALIZER";
|
|
57
|
+
CofheErrorCode3["MissingFheKey"] = "MISSING_FHE_KEY";
|
|
58
|
+
CofheErrorCode3["MissingCrs"] = "MISSING_CRS";
|
|
59
|
+
CofheErrorCode3["FetchKeysFailed"] = "FETCH_KEYS_FAILED";
|
|
60
|
+
CofheErrorCode3["PublicWalletGetChainIdFailed"] = "PUBLIC_WALLET_GET_CHAIN_ID_FAILED";
|
|
61
|
+
CofheErrorCode3["PublicWalletGetAddressesFailed"] = "PUBLIC_WALLET_GET_ADDRESSES_FAILED";
|
|
62
|
+
CofheErrorCode3["RehydrateKeysStoreFailed"] = "REHYDRATE_KEYS_STORE_FAILED";
|
|
63
|
+
return CofheErrorCode3;
|
|
64
64
|
})(CofheErrorCode || {});
|
|
65
65
|
var CofheError = class _CofheError extends Error {
|
|
66
66
|
code;
|
|
@@ -154,7 +154,6 @@ var isCofheError = (error) => error instanceof CofheError;
|
|
|
154
154
|
var TASK_MANAGER_ADDRESS = "0xeA30c4B8b44078Bbf8a6ef5b9f1eC1626C7848D9";
|
|
155
155
|
var MOCKS_ZK_VERIFIER_ADDRESS = "0x0000000000000000000000000000000000005001";
|
|
156
156
|
var MOCKS_THRESHOLD_NETWORK_ADDRESS = "0x0000000000000000000000000000000000005002";
|
|
157
|
-
var TEST_BED_ADDRESS = "0x0000000000000000000000000000000000005003";
|
|
158
157
|
var MOCKS_ZK_VERIFIER_SIGNER_PRIVATE_KEY = "0x6C8D7F768A6BB4AAFE85E8A2F5A9680355239C7E14646ED62B044E39DE154512";
|
|
159
158
|
var MOCKS_ZK_VERIFIER_SIGNER_ADDRESS = "0x6E12D8C87503D4287c294f2Fdef96ACd9DFf6bd2";
|
|
160
159
|
var MOCKS_DECRYPT_RESULT_SIGNER_PRIVATE_KEY = "0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d";
|
|
@@ -546,7 +545,7 @@ var zkVerify = async (verifierUrl, serializedBytes, address, securityZone, chain
|
|
|
546
545
|
}
|
|
547
546
|
};
|
|
548
547
|
var concatSigRecid = (signature, recid) => {
|
|
549
|
-
return signature
|
|
548
|
+
return `${signature}${(recid + 27).toString(16).padStart(2, "0")}`;
|
|
550
549
|
};
|
|
551
550
|
|
|
552
551
|
// core/encrypt/MockZkVerifierAbi.ts
|
|
@@ -878,9 +877,9 @@ var hardhat2 = defineChain({
|
|
|
878
877
|
name: "Hardhat",
|
|
879
878
|
network: "localhost",
|
|
880
879
|
// These are unused in the mock environment
|
|
881
|
-
coFheUrl: "http://
|
|
882
|
-
verifierUrl: "http://
|
|
883
|
-
thresholdNetworkUrl: "http://
|
|
880
|
+
coFheUrl: "http://ignored-in-mock-environment",
|
|
881
|
+
verifierUrl: "http://ignored-in-mock-environment",
|
|
882
|
+
thresholdNetworkUrl: "http://ignored-in-mock-environment",
|
|
884
883
|
environment: "MOCK"
|
|
885
884
|
});
|
|
886
885
|
var CofheConfigSchema = zod.z.object({
|
|
@@ -1269,6 +1268,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
|
|
|
1269
1268
|
securityZone;
|
|
1270
1269
|
stepCallback;
|
|
1271
1270
|
inputItems;
|
|
1271
|
+
hpp = false;
|
|
1272
1272
|
zkvWalletClient;
|
|
1273
1273
|
tfhePublicKeyDeserializer;
|
|
1274
1274
|
compactPkeCrsDeserializer;
|
|
@@ -1398,6 +1398,20 @@ var EncryptInputsBuilder = class extends BaseBuilder {
|
|
|
1398
1398
|
getSecurityZone() {
|
|
1399
1399
|
return this.securityZone;
|
|
1400
1400
|
}
|
|
1401
|
+
/**
|
|
1402
|
+
* Example:
|
|
1403
|
+
* ```typescript
|
|
1404
|
+
* const encrypted = await encryptInputs([Encryptable.uint128(10n)])
|
|
1405
|
+
* .asHashPlusProof()
|
|
1406
|
+
* .execute();
|
|
1407
|
+
* ```
|
|
1408
|
+
*
|
|
1409
|
+
* @returns Chainable EncryptInputsBuilder instance that will return a HashPlusProofResult instead of an array of EncryptedItemInputs.
|
|
1410
|
+
*/
|
|
1411
|
+
asHashPlusProof() {
|
|
1412
|
+
this.hpp = true;
|
|
1413
|
+
return this;
|
|
1414
|
+
}
|
|
1401
1415
|
/**
|
|
1402
1416
|
* @param useWorker - Whether to use Web Workers for ZK proof generation.
|
|
1403
1417
|
*
|
|
@@ -1679,6 +1693,15 @@ var EncryptInputsBuilder = class extends BaseBuilder {
|
|
|
1679
1693
|
this.fireStepEnd("verify" /* Verify */);
|
|
1680
1694
|
return encryptedInputs;
|
|
1681
1695
|
}
|
|
1696
|
+
structsToHashPlusProof(inItems) {
|
|
1697
|
+
let hashes = [];
|
|
1698
|
+
let proof = "";
|
|
1699
|
+
for (const item of inItems) {
|
|
1700
|
+
hashes.push("0x" + item.ctHash.toString(16).padStart(64, "0"));
|
|
1701
|
+
proof += item.signature;
|
|
1702
|
+
}
|
|
1703
|
+
return [...hashes, proof];
|
|
1704
|
+
}
|
|
1682
1705
|
/**
|
|
1683
1706
|
* Final step of the encryption process. MUST BE CALLED LAST IN THE CHAIN.
|
|
1684
1707
|
*
|
|
@@ -1699,9 +1722,14 @@ var EncryptInputsBuilder = class extends BaseBuilder {
|
|
|
1699
1722
|
* @returns The encrypted inputs.
|
|
1700
1723
|
*/
|
|
1701
1724
|
async execute() {
|
|
1725
|
+
let items;
|
|
1702
1726
|
if (this.chainId === chains.hardhat.id)
|
|
1703
|
-
|
|
1704
|
-
|
|
1727
|
+
items = await this.mocksExecute();
|
|
1728
|
+
else
|
|
1729
|
+
items = await this.productionExecute();
|
|
1730
|
+
if (this.hpp)
|
|
1731
|
+
return this.structsToHashPlusProof(items);
|
|
1732
|
+
return items;
|
|
1705
1733
|
}
|
|
1706
1734
|
};
|
|
1707
1735
|
|
|
@@ -3000,6 +3028,96 @@ function computeMinuteRampPollIntervalMs(elapsedMs, params) {
|
|
|
3000
3028
|
return Math.min(params.maxIntervalMs, Math.max(params.minIntervalMs, intervalMs));
|
|
3001
3029
|
}
|
|
3002
3030
|
|
|
3031
|
+
// core/decrypt/submitRetry.ts
|
|
3032
|
+
var DEFAULT_404_RETRY_TIMEOUT_MS = 1e4;
|
|
3033
|
+
function isRetryableSubmitStatus(status) {
|
|
3034
|
+
return status === 204 || status === 404;
|
|
3035
|
+
}
|
|
3036
|
+
function normalize404RetryTimeoutMs(params) {
|
|
3037
|
+
const { timeoutMs, operationLabel, errorCode } = params;
|
|
3038
|
+
if (timeoutMs === void 0)
|
|
3039
|
+
return DEFAULT_404_RETRY_TIMEOUT_MS;
|
|
3040
|
+
if (!Number.isFinite(timeoutMs) || timeoutMs < 0) {
|
|
3041
|
+
throw new CofheError({
|
|
3042
|
+
code: errorCode,
|
|
3043
|
+
message: `${operationLabel} submit 404 retry timeout must be a finite number greater than or equal to 0`,
|
|
3044
|
+
context: {
|
|
3045
|
+
timeoutMs
|
|
3046
|
+
}
|
|
3047
|
+
});
|
|
3048
|
+
}
|
|
3049
|
+
return timeoutMs;
|
|
3050
|
+
}
|
|
3051
|
+
async function classifySubmitResponse(params) {
|
|
3052
|
+
const { response, extractErrorMessage } = params;
|
|
3053
|
+
if (isRetryableSubmitStatus(response.status)) {
|
|
3054
|
+
return { kind: "retryable", status: response.status };
|
|
3055
|
+
}
|
|
3056
|
+
if (response.ok) {
|
|
3057
|
+
return { kind: "parse-json" };
|
|
3058
|
+
}
|
|
3059
|
+
let errorMessage = `HTTP ${response.status}`;
|
|
3060
|
+
try {
|
|
3061
|
+
const errorBody = await response.json();
|
|
3062
|
+
const maybeErrorMessage = extractErrorMessage?.(errorBody);
|
|
3063
|
+
if (typeof maybeErrorMessage === "string" && maybeErrorMessage.length > 0) {
|
|
3064
|
+
errorMessage = maybeErrorMessage;
|
|
3065
|
+
} else if (errorBody && typeof errorBody === "object") {
|
|
3066
|
+
const defaultMessage = errorBody.error_message;
|
|
3067
|
+
const fallbackMessage = errorBody.message;
|
|
3068
|
+
if (typeof defaultMessage === "string" && defaultMessage.length > 0) {
|
|
3069
|
+
errorMessage = defaultMessage;
|
|
3070
|
+
} else if (typeof fallbackMessage === "string" && fallbackMessage.length > 0) {
|
|
3071
|
+
errorMessage = fallbackMessage;
|
|
3072
|
+
}
|
|
3073
|
+
}
|
|
3074
|
+
} catch {
|
|
3075
|
+
errorMessage = response.statusText || errorMessage;
|
|
3076
|
+
}
|
|
3077
|
+
return { kind: "fatal-http", errorMessage };
|
|
3078
|
+
}
|
|
3079
|
+
function throwIfSubmitRetryTimedOut(params) {
|
|
3080
|
+
const {
|
|
3081
|
+
operationLabel,
|
|
3082
|
+
errorCode,
|
|
3083
|
+
status,
|
|
3084
|
+
elapsedMs,
|
|
3085
|
+
retry404TimeoutMs,
|
|
3086
|
+
overallTimeoutMs,
|
|
3087
|
+
thresholdNetworkUrl,
|
|
3088
|
+
body,
|
|
3089
|
+
attemptIndex
|
|
3090
|
+
} = params;
|
|
3091
|
+
if (status === 404 && elapsedMs > retry404TimeoutMs) {
|
|
3092
|
+
throw new CofheError({
|
|
3093
|
+
code: errorCode,
|
|
3094
|
+
message: `${operationLabel} submit retried 404 responses without receiving request_id for ${retry404TimeoutMs}ms`,
|
|
3095
|
+
hint: "The ciphertext may not be indexed yet. Increase set404RetryTimeout(...) if the backend is slow to index ciphertexts.",
|
|
3096
|
+
context: {
|
|
3097
|
+
thresholdNetworkUrl,
|
|
3098
|
+
body,
|
|
3099
|
+
attemptIndex,
|
|
3100
|
+
timeoutMs: retry404TimeoutMs,
|
|
3101
|
+
status
|
|
3102
|
+
}
|
|
3103
|
+
});
|
|
3104
|
+
}
|
|
3105
|
+
if (elapsedMs > overallTimeoutMs) {
|
|
3106
|
+
throw new CofheError({
|
|
3107
|
+
code: errorCode,
|
|
3108
|
+
message: `${operationLabel} submit retried without receiving request_id for ${overallTimeoutMs}ms`,
|
|
3109
|
+
hint: "The ciphertext may still be propagating. Try again later.",
|
|
3110
|
+
context: {
|
|
3111
|
+
thresholdNetworkUrl,
|
|
3112
|
+
body,
|
|
3113
|
+
attemptIndex,
|
|
3114
|
+
timeoutMs: overallTimeoutMs,
|
|
3115
|
+
status
|
|
3116
|
+
}
|
|
3117
|
+
});
|
|
3118
|
+
}
|
|
3119
|
+
}
|
|
3120
|
+
|
|
3003
3121
|
// core/decrypt/tnSealOutputV2.ts
|
|
3004
3122
|
var POLL_INTERVAL_MS = 1e3;
|
|
3005
3123
|
var POLL_MAX_INTERVAL_MS = 1e4;
|
|
@@ -3061,7 +3179,7 @@ function parseCompletedSealOutputResponse(params) {
|
|
|
3061
3179
|
}
|
|
3062
3180
|
return convertSealedData(sealed);
|
|
3063
3181
|
}
|
|
3064
|
-
async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, permission, overallStartTime, onPoll) {
|
|
3182
|
+
async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, permission, overallStartTime, retry404TimeoutMs, onPoll) {
|
|
3065
3183
|
const body = {
|
|
3066
3184
|
ct_tempkey: BigInt(ctHash).toString(16).padStart(64, "0"),
|
|
3067
3185
|
host_chain_id: chainId,
|
|
@@ -3091,17 +3209,11 @@ async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, per
|
|
|
3091
3209
|
}
|
|
3092
3210
|
});
|
|
3093
3211
|
}
|
|
3094
|
-
|
|
3095
|
-
|
|
3096
|
-
try {
|
|
3097
|
-
const errorBody = await response.json();
|
|
3098
|
-
errorMessage = errorBody.error_message || errorBody.message || errorMessage;
|
|
3099
|
-
} catch {
|
|
3100
|
-
errorMessage = response.statusText || errorMessage;
|
|
3101
|
-
}
|
|
3212
|
+
const responseClassification = await classifySubmitResponse({ response });
|
|
3213
|
+
if (responseClassification.kind === "fatal-http") {
|
|
3102
3214
|
throw new CofheError({
|
|
3103
3215
|
code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
|
|
3104
|
-
message: `sealOutput request failed: ${errorMessage}`,
|
|
3216
|
+
message: `sealOutput request failed: ${responseClassification.errorMessage}`,
|
|
3105
3217
|
hint: "Check the threshold network URL and request parameters.",
|
|
3106
3218
|
context: {
|
|
3107
3219
|
thresholdNetworkUrl,
|
|
@@ -3112,8 +3224,8 @@ async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, per
|
|
|
3112
3224
|
}
|
|
3113
3225
|
});
|
|
3114
3226
|
}
|
|
3115
|
-
|
|
3116
|
-
|
|
3227
|
+
if (responseClassification.kind === "parse-json") {
|
|
3228
|
+
let submitResponse;
|
|
3117
3229
|
try {
|
|
3118
3230
|
submitResponse = await response.json();
|
|
3119
3231
|
} catch (e) {
|
|
@@ -3141,46 +3253,39 @@ async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, per
|
|
|
3141
3253
|
if (submitResponse.request_id) {
|
|
3142
3254
|
return { kind: "request_id", requestId: submitResponse.request_id };
|
|
3143
3255
|
}
|
|
3144
|
-
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
|
|
3152
|
-
|
|
3153
|
-
thresholdNetworkUrl,
|
|
3154
|
-
body,
|
|
3155
|
-
attemptIndex,
|
|
3156
|
-
timeoutMs: SEAL_OUTPUT_TIMEOUT_MS,
|
|
3157
|
-
submitResponse,
|
|
3158
|
-
status: response.status
|
|
3159
|
-
}
|
|
3160
|
-
});
|
|
3161
|
-
}
|
|
3162
|
-
onPoll?.({
|
|
3163
|
-
operation: "sealoutput",
|
|
3164
|
-
requestId: "",
|
|
3165
|
-
attemptIndex,
|
|
3166
|
-
elapsedMs,
|
|
3167
|
-
intervalMs: SUBMIT_RETRY_INTERVAL_MS,
|
|
3168
|
-
timeoutMs: SEAL_OUTPUT_TIMEOUT_MS
|
|
3256
|
+
throw new CofheError({
|
|
3257
|
+
code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
|
|
3258
|
+
message: `sealOutput submit response missing request_id`,
|
|
3259
|
+
context: {
|
|
3260
|
+
thresholdNetworkUrl,
|
|
3261
|
+
body,
|
|
3262
|
+
submitResponse,
|
|
3263
|
+
attemptIndex
|
|
3264
|
+
}
|
|
3169
3265
|
});
|
|
3170
|
-
await new Promise((resolve) => setTimeout(resolve, SUBMIT_RETRY_INTERVAL_MS));
|
|
3171
|
-
attemptIndex += 1;
|
|
3172
|
-
continue;
|
|
3173
3266
|
}
|
|
3174
|
-
|
|
3175
|
-
|
|
3176
|
-
|
|
3177
|
-
|
|
3178
|
-
|
|
3179
|
-
|
|
3180
|
-
|
|
3181
|
-
|
|
3182
|
-
|
|
3267
|
+
const elapsedMs = Date.now() - overallStartTime;
|
|
3268
|
+
throwIfSubmitRetryTimedOut({
|
|
3269
|
+
operationLabel: "sealOutput",
|
|
3270
|
+
errorCode: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
|
|
3271
|
+
status: responseClassification.status,
|
|
3272
|
+
elapsedMs,
|
|
3273
|
+
retry404TimeoutMs,
|
|
3274
|
+
overallTimeoutMs: SEAL_OUTPUT_TIMEOUT_MS,
|
|
3275
|
+
thresholdNetworkUrl,
|
|
3276
|
+
body,
|
|
3277
|
+
attemptIndex
|
|
3183
3278
|
});
|
|
3279
|
+
onPoll?.({
|
|
3280
|
+
operation: "sealoutput",
|
|
3281
|
+
requestId: "",
|
|
3282
|
+
attemptIndex,
|
|
3283
|
+
elapsedMs,
|
|
3284
|
+
intervalMs: SUBMIT_RETRY_INTERVAL_MS,
|
|
3285
|
+
timeoutMs: SEAL_OUTPUT_TIMEOUT_MS
|
|
3286
|
+
});
|
|
3287
|
+
await new Promise((resolve) => setTimeout(resolve, SUBMIT_RETRY_INTERVAL_MS));
|
|
3288
|
+
attemptIndex += 1;
|
|
3184
3289
|
}
|
|
3185
3290
|
}
|
|
3186
3291
|
async function pollSealOutputStatus(thresholdNetworkUrl, requestId, overallStartTime, onPoll) {
|
|
@@ -3295,7 +3400,12 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId, overallStart
|
|
|
3295
3400
|
});
|
|
3296
3401
|
}
|
|
3297
3402
|
async function tnSealOutputV2(params) {
|
|
3298
|
-
const { thresholdNetworkUrl, ctHash, chainId, permission, onPoll } = params;
|
|
3403
|
+
const { thresholdNetworkUrl, ctHash, chainId, permission, retry404TimeoutMs, onPoll } = params;
|
|
3404
|
+
const normalized404RetryTimeoutMs = normalize404RetryTimeoutMs({
|
|
3405
|
+
timeoutMs: retry404TimeoutMs,
|
|
3406
|
+
operationLabel: "sealOutput",
|
|
3407
|
+
errorCode: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */
|
|
3408
|
+
});
|
|
3299
3409
|
const overallStartTime = Date.now();
|
|
3300
3410
|
const submitResult = await submitSealOutputRequest(
|
|
3301
3411
|
thresholdNetworkUrl,
|
|
@@ -3303,6 +3413,7 @@ async function tnSealOutputV2(params) {
|
|
|
3303
3413
|
chainId,
|
|
3304
3414
|
permission,
|
|
3305
3415
|
overallStartTime,
|
|
3416
|
+
normalized404RetryTimeoutMs,
|
|
3306
3417
|
onPoll
|
|
3307
3418
|
);
|
|
3308
3419
|
if (submitResult.kind === "completed") {
|
|
@@ -3312,12 +3423,14 @@ async function tnSealOutputV2(params) {
|
|
|
3312
3423
|
}
|
|
3313
3424
|
|
|
3314
3425
|
// core/decrypt/decryptForViewBuilder.ts
|
|
3426
|
+
var DEFAULT_404_RETRY_TIMEOUT_MS2 = 1e4;
|
|
3315
3427
|
var DecryptForViewBuilder = class extends BaseBuilder {
|
|
3316
3428
|
ctHash;
|
|
3317
3429
|
utype;
|
|
3318
3430
|
permitHash;
|
|
3319
3431
|
permit;
|
|
3320
3432
|
pollCallback;
|
|
3433
|
+
retry404TimeoutMs = DEFAULT_404_RETRY_TIMEOUT_MS2;
|
|
3321
3434
|
constructor(params) {
|
|
3322
3435
|
super({
|
|
3323
3436
|
config: params.config,
|
|
@@ -3378,6 +3491,19 @@ var DecryptForViewBuilder = class extends BaseBuilder {
|
|
|
3378
3491
|
this.pollCallback = callback;
|
|
3379
3492
|
return this;
|
|
3380
3493
|
}
|
|
3494
|
+
set404RetryTimeout(timeoutMs) {
|
|
3495
|
+
if (!Number.isFinite(timeoutMs) || timeoutMs < 0) {
|
|
3496
|
+
throw new CofheError({
|
|
3497
|
+
code: "INTERNAL_ERROR" /* InternalError */,
|
|
3498
|
+
message: "decryptForView: set404RetryTimeout(timeoutMs) expects a finite number greater than or equal to 0.",
|
|
3499
|
+
context: {
|
|
3500
|
+
timeoutMs
|
|
3501
|
+
}
|
|
3502
|
+
});
|
|
3503
|
+
}
|
|
3504
|
+
this.retry404TimeoutMs = timeoutMs;
|
|
3505
|
+
return this;
|
|
3506
|
+
}
|
|
3381
3507
|
withPermit(permitOrPermitHash) {
|
|
3382
3508
|
if (typeof permitOrPermitHash === "string") {
|
|
3383
3509
|
this.permitHash = permitOrPermitHash;
|
|
@@ -3506,6 +3632,7 @@ var DecryptForViewBuilder = class extends BaseBuilder {
|
|
|
3506
3632
|
chainId: this.chainId,
|
|
3507
3633
|
permission,
|
|
3508
3634
|
thresholdNetworkUrl,
|
|
3635
|
+
retry404TimeoutMs: this.retry404TimeoutMs,
|
|
3509
3636
|
onPoll: this.pollCallback
|
|
3510
3637
|
});
|
|
3511
3638
|
return PermitUtils.unseal(permit, sealed);
|
|
@@ -3781,7 +3908,7 @@ function assertDecryptStatusResponseV2(value) {
|
|
|
3781
3908
|
}
|
|
3782
3909
|
return value;
|
|
3783
3910
|
}
|
|
3784
|
-
async function submitDecryptRequestV2(thresholdNetworkUrl, ctHash, chainId, permission, overallStartTime, onPoll) {
|
|
3911
|
+
async function submitDecryptRequestV2(thresholdNetworkUrl, ctHash, chainId, permission, overallStartTime, retry404TimeoutMs, onPoll) {
|
|
3785
3912
|
const body = {
|
|
3786
3913
|
ct_tempkey: BigInt(ctHash).toString(16).padStart(64, "0"),
|
|
3787
3914
|
host_chain_id: chainId
|
|
@@ -3813,19 +3940,11 @@ async function submitDecryptRequestV2(thresholdNetworkUrl, ctHash, chainId, perm
|
|
|
3813
3940
|
}
|
|
3814
3941
|
});
|
|
3815
3942
|
}
|
|
3816
|
-
|
|
3817
|
-
|
|
3818
|
-
try {
|
|
3819
|
-
const errorBody = await response.json();
|
|
3820
|
-
const maybeMessage = errorBody.error_message || errorBody.message;
|
|
3821
|
-
if (typeof maybeMessage === "string" && maybeMessage.length > 0)
|
|
3822
|
-
errorMessage = maybeMessage;
|
|
3823
|
-
} catch {
|
|
3824
|
-
errorMessage = response.statusText || errorMessage;
|
|
3825
|
-
}
|
|
3943
|
+
const responseClassification = await classifySubmitResponse({ response });
|
|
3944
|
+
if (responseClassification.kind === "fatal-http") {
|
|
3826
3945
|
throw new CofheError({
|
|
3827
3946
|
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
3828
|
-
message: `decrypt request failed: ${errorMessage}`,
|
|
3947
|
+
message: `decrypt request failed: ${responseClassification.errorMessage}`,
|
|
3829
3948
|
hint: "Check the threshold network URL and request parameters.",
|
|
3830
3949
|
context: {
|
|
3831
3950
|
thresholdNetworkUrl,
|
|
@@ -3836,8 +3955,8 @@ async function submitDecryptRequestV2(thresholdNetworkUrl, ctHash, chainId, perm
|
|
|
3836
3955
|
}
|
|
3837
3956
|
});
|
|
3838
3957
|
}
|
|
3839
|
-
|
|
3840
|
-
|
|
3958
|
+
if (responseClassification.kind === "parse-json") {
|
|
3959
|
+
let submitResponse;
|
|
3841
3960
|
let rawJson;
|
|
3842
3961
|
try {
|
|
3843
3962
|
rawJson = await response.json();
|
|
@@ -3867,46 +3986,39 @@ async function submitDecryptRequestV2(thresholdNetworkUrl, ctHash, chainId, perm
|
|
|
3867
3986
|
if (submitResponse.request_id) {
|
|
3868
3987
|
return { kind: "request_id", requestId: submitResponse.request_id };
|
|
3869
3988
|
}
|
|
3870
|
-
|
|
3871
|
-
|
|
3872
|
-
|
|
3873
|
-
|
|
3874
|
-
|
|
3875
|
-
|
|
3876
|
-
|
|
3877
|
-
|
|
3878
|
-
|
|
3879
|
-
thresholdNetworkUrl,
|
|
3880
|
-
body,
|
|
3881
|
-
attemptIndex,
|
|
3882
|
-
timeoutMs: DECRYPT_TIMEOUT_MS,
|
|
3883
|
-
submitResponse,
|
|
3884
|
-
status: response.status
|
|
3885
|
-
}
|
|
3886
|
-
});
|
|
3887
|
-
}
|
|
3888
|
-
onPoll?.({
|
|
3889
|
-
operation: "decrypt",
|
|
3890
|
-
requestId: "",
|
|
3891
|
-
attemptIndex,
|
|
3892
|
-
elapsedMs,
|
|
3893
|
-
intervalMs: SUBMIT_RETRY_INTERVAL_MS2,
|
|
3894
|
-
timeoutMs: DECRYPT_TIMEOUT_MS
|
|
3989
|
+
throw new CofheError({
|
|
3990
|
+
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
3991
|
+
message: `decrypt submit response missing request_id`,
|
|
3992
|
+
context: {
|
|
3993
|
+
thresholdNetworkUrl,
|
|
3994
|
+
body,
|
|
3995
|
+
submitResponse,
|
|
3996
|
+
attemptIndex
|
|
3997
|
+
}
|
|
3895
3998
|
});
|
|
3896
|
-
await new Promise((resolve) => setTimeout(resolve, SUBMIT_RETRY_INTERVAL_MS2));
|
|
3897
|
-
attemptIndex += 1;
|
|
3898
|
-
continue;
|
|
3899
3999
|
}
|
|
3900
|
-
|
|
3901
|
-
|
|
3902
|
-
|
|
3903
|
-
|
|
3904
|
-
|
|
3905
|
-
|
|
3906
|
-
|
|
3907
|
-
|
|
3908
|
-
|
|
4000
|
+
const elapsedMs = Date.now() - overallStartTime;
|
|
4001
|
+
throwIfSubmitRetryTimedOut({
|
|
4002
|
+
operationLabel: "decrypt",
|
|
4003
|
+
errorCode: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
4004
|
+
status: responseClassification.status,
|
|
4005
|
+
elapsedMs,
|
|
4006
|
+
retry404TimeoutMs,
|
|
4007
|
+
overallTimeoutMs: DECRYPT_TIMEOUT_MS,
|
|
4008
|
+
thresholdNetworkUrl,
|
|
4009
|
+
body,
|
|
4010
|
+
attemptIndex
|
|
3909
4011
|
});
|
|
4012
|
+
onPoll?.({
|
|
4013
|
+
operation: "decrypt",
|
|
4014
|
+
requestId: "",
|
|
4015
|
+
attemptIndex,
|
|
4016
|
+
elapsedMs,
|
|
4017
|
+
intervalMs: SUBMIT_RETRY_INTERVAL_MS2,
|
|
4018
|
+
timeoutMs: DECRYPT_TIMEOUT_MS
|
|
4019
|
+
});
|
|
4020
|
+
await new Promise((resolve) => setTimeout(resolve, SUBMIT_RETRY_INTERVAL_MS2));
|
|
4021
|
+
attemptIndex += 1;
|
|
3910
4022
|
}
|
|
3911
4023
|
}
|
|
3912
4024
|
async function pollDecryptStatusV2(thresholdNetworkUrl, requestId, overallStartTime, onPoll) {
|
|
@@ -4024,7 +4136,12 @@ async function pollDecryptStatusV2(thresholdNetworkUrl, requestId, overallStartT
|
|
|
4024
4136
|
});
|
|
4025
4137
|
}
|
|
4026
4138
|
async function tnDecryptV2(params) {
|
|
4027
|
-
const { thresholdNetworkUrl, ctHash, chainId, permission, onPoll } = params;
|
|
4139
|
+
const { thresholdNetworkUrl, ctHash, chainId, permission, retry404TimeoutMs, onPoll } = params;
|
|
4140
|
+
const normalized404RetryTimeoutMs = normalize404RetryTimeoutMs({
|
|
4141
|
+
timeoutMs: retry404TimeoutMs,
|
|
4142
|
+
operationLabel: "decrypt",
|
|
4143
|
+
errorCode: "DECRYPT_FAILED" /* DecryptFailed */
|
|
4144
|
+
});
|
|
4028
4145
|
const overallStartTime = Date.now();
|
|
4029
4146
|
const submitResult = await submitDecryptRequestV2(
|
|
4030
4147
|
thresholdNetworkUrl,
|
|
@@ -4032,6 +4149,7 @@ async function tnDecryptV2(params) {
|
|
|
4032
4149
|
chainId,
|
|
4033
4150
|
permission,
|
|
4034
4151
|
overallStartTime,
|
|
4152
|
+
normalized404RetryTimeoutMs,
|
|
4035
4153
|
onPoll
|
|
4036
4154
|
);
|
|
4037
4155
|
if (submitResult.kind === "completed") {
|
|
@@ -4041,12 +4159,14 @@ async function tnDecryptV2(params) {
|
|
|
4041
4159
|
}
|
|
4042
4160
|
|
|
4043
4161
|
// core/decrypt/decryptForTxBuilder.ts
|
|
4162
|
+
var DEFAULT_404_RETRY_TIMEOUT_MS3 = 1e4;
|
|
4044
4163
|
var DecryptForTxBuilder = class extends BaseBuilder {
|
|
4045
4164
|
ctHash;
|
|
4046
4165
|
permitHash;
|
|
4047
4166
|
permit;
|
|
4048
4167
|
permitSelection = "unset";
|
|
4049
4168
|
pollCallback;
|
|
4169
|
+
retry404TimeoutMs = DEFAULT_404_RETRY_TIMEOUT_MS3;
|
|
4050
4170
|
constructor(params) {
|
|
4051
4171
|
super({
|
|
4052
4172
|
config: params.config,
|
|
@@ -4076,6 +4196,19 @@ var DecryptForTxBuilder = class extends BaseBuilder {
|
|
|
4076
4196
|
this.pollCallback = callback;
|
|
4077
4197
|
return this;
|
|
4078
4198
|
}
|
|
4199
|
+
set404RetryTimeout(timeoutMs) {
|
|
4200
|
+
if (!Number.isFinite(timeoutMs) || timeoutMs < 0) {
|
|
4201
|
+
throw new CofheError({
|
|
4202
|
+
code: "INTERNAL_ERROR" /* InternalError */,
|
|
4203
|
+
message: "decryptForTx: set404RetryTimeout(timeoutMs) expects a finite number greater than or equal to 0.",
|
|
4204
|
+
context: {
|
|
4205
|
+
timeoutMs
|
|
4206
|
+
}
|
|
4207
|
+
});
|
|
4208
|
+
}
|
|
4209
|
+
this.retry404TimeoutMs = timeoutMs;
|
|
4210
|
+
return this;
|
|
4211
|
+
}
|
|
4079
4212
|
withPermit(permitOrPermitHash) {
|
|
4080
4213
|
if (this.permitSelection === "with-permit") {
|
|
4081
4214
|
throw new CofheError({
|
|
@@ -4208,6 +4341,7 @@ var DecryptForTxBuilder = class extends BaseBuilder {
|
|
|
4208
4341
|
chainId: this.chainId,
|
|
4209
4342
|
permission,
|
|
4210
4343
|
thresholdNetworkUrl,
|
|
4344
|
+
retry404TimeoutMs: this.retry404TimeoutMs,
|
|
4211
4345
|
onPoll: this.pollCallback
|
|
4212
4346
|
});
|
|
4213
4347
|
return {
|
|
@@ -4538,7 +4672,6 @@ exports.MOCKS_ZK_VERIFIER_ADDRESS = MOCKS_ZK_VERIFIER_ADDRESS;
|
|
|
4538
4672
|
exports.MOCKS_ZK_VERIFIER_SIGNER_ADDRESS = MOCKS_ZK_VERIFIER_SIGNER_ADDRESS;
|
|
4539
4673
|
exports.MOCKS_ZK_VERIFIER_SIGNER_PRIVATE_KEY = MOCKS_ZK_VERIFIER_SIGNER_PRIVATE_KEY;
|
|
4540
4674
|
exports.TASK_MANAGER_ADDRESS = TASK_MANAGER_ADDRESS;
|
|
4541
|
-
exports.TEST_BED_ADDRESS = TEST_BED_ADDRESS;
|
|
4542
4675
|
exports.TFHE_RS_SAFE_SERIALIZATION_SIZE_LIMIT = TFHE_RS_SAFE_SERIALIZATION_SIZE_LIMIT;
|
|
4543
4676
|
exports.TFHE_RS_ZK_MAX_BITS = TFHE_RS_ZK_MAX_BITS;
|
|
4544
4677
|
exports.assertCorrectEncryptedItemInput = assertCorrectEncryptedItemInput;
|