@cofhe/sdk 0.3.1 → 0.4.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 +19 -0
- package/adapters/ethers6.test.ts +1 -1
- package/core/client.ts +6 -6
- package/core/clientTypes.ts +7 -7
- package/core/decrypt/cofheMocksDecryptForTx.ts +21 -79
- package/core/decrypt/cofheMocksDecryptForView.ts +3 -10
- package/core/decrypt/decryptForTxBuilder.ts +19 -14
- package/core/decrypt/decryptForViewBuilder.ts +9 -4
- package/core/decrypt/tnDecryptUtils.ts +65 -0
- package/core/decrypt/{tnDecrypt.ts → tnDecryptV1.ts} +10 -71
- package/core/decrypt/tnDecryptV2.ts +343 -0
- package/core/decrypt/tnSealOutputV2.ts +3 -3
- package/core/encrypt/cofheMocksZkVerifySign.ts +15 -11
- package/core/permits.ts +3 -3
- package/core/types.ts +8 -0
- package/dist/{chunk-2TPSCOW3.js → chunk-MXND5SVN.js} +275 -171
- package/dist/{clientTypes-Bhq7pCSA.d.cts → clientTypes-ACVWbrXL.d.cts} +22 -14
- package/dist/{clientTypes-6aTZPQ_4.d.ts → clientTypes-kkrRdawm.d.ts} +22 -14
- package/dist/core.cjs +274 -170
- package/dist/core.d.cts +2 -2
- package/dist/core.d.ts +2 -2
- package/dist/core.js +1 -1
- package/dist/node.cjs +274 -170
- package/dist/node.d.cts +1 -1
- package/dist/node.d.ts +1 -1
- package/dist/node.js +1 -1
- package/dist/web.cjs +274 -170
- package/dist/web.d.cts +1 -1
- package/dist/web.d.ts +1 -1
- package/dist/web.js +1 -1
- package/node/client.test.ts +1 -1
- package/package.json +1 -1
- package/web/client.web.test.ts +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { hardhat as hardhat$1 } from './chunk-TBLR7NNE.js';
|
|
2
2
|
import { permitStore, PermitUtils, MOCKS_THRESHOLD_NETWORK_ADDRESS, MOCKS_DECRYPT_RESULT_SIGNER_PRIVATE_KEY, MOCKS_ZK_VERIFIER_SIGNER_PRIVATE_KEY, MOCKS_ZK_VERIFIER_ADDRESS } from './chunk-NWDKXBIP.js';
|
|
3
3
|
import { createStore } from 'zustand/vanilla';
|
|
4
|
-
import {
|
|
4
|
+
import { encodePacked, keccak256, createWalletClient, http, getAddress, parseSignature, serializeSignature } from 'viem';
|
|
5
5
|
import { hardhat } from 'viem/chains';
|
|
6
6
|
import { sign, privateKeyToAccount } from 'viem/accounts';
|
|
7
7
|
import { z } from 'zod';
|
|
@@ -767,7 +767,7 @@ async function insertCtHashes(items, walletClient) {
|
|
|
767
767
|
});
|
|
768
768
|
}
|
|
769
769
|
}
|
|
770
|
-
async function createProofSignatures(items, securityZone) {
|
|
770
|
+
async function createProofSignatures(items, securityZone, account) {
|
|
771
771
|
let signatures = [];
|
|
772
772
|
let encInputSignerClient;
|
|
773
773
|
try {
|
|
@@ -784,12 +784,15 @@ async function createProofSignatures(items, securityZone) {
|
|
|
784
784
|
}
|
|
785
785
|
try {
|
|
786
786
|
for (const item of items) {
|
|
787
|
-
const packedData = encodePacked(
|
|
787
|
+
const packedData = encodePacked(
|
|
788
|
+
["uint256", "uint8", "uint8", "address", "uint256"],
|
|
789
|
+
[BigInt(item.ctHash), item.utype, securityZone, account, BigInt(hardhat.id)]
|
|
790
|
+
);
|
|
788
791
|
const messageHash = keccak256(packedData);
|
|
789
|
-
const
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
792
|
+
const signature = await sign({
|
|
793
|
+
hash: messageHash,
|
|
794
|
+
privateKey: MOCKS_ZK_VERIFIER_SIGNER_PRIVATE_KEY,
|
|
795
|
+
to: "hex"
|
|
793
796
|
});
|
|
794
797
|
signatures.push(signature);
|
|
795
798
|
}
|
|
@@ -820,7 +823,7 @@ async function cofheMocksZkVerifySign(items, account, securityZone, publicClient
|
|
|
820
823
|
const _walletClient = zkvWalletClient ?? createMockZkVerifierSigner();
|
|
821
824
|
const encryptableItems = await calcCtHashes(items, account, securityZone, publicClient);
|
|
822
825
|
await insertCtHashes(encryptableItems, _walletClient);
|
|
823
|
-
const signatures = await createProofSignatures(encryptableItems, securityZone);
|
|
826
|
+
const signatures = await createProofSignatures(encryptableItems, securityZone, account);
|
|
824
827
|
return encryptableItems.map((item, index) => ({
|
|
825
828
|
ct_hash: item.ctHash.toString(),
|
|
826
829
|
signature: signatures[index]
|
|
@@ -1675,13 +1678,13 @@ var serialize = (permit) => {
|
|
|
1675
1678
|
var deserialize = (serialized) => {
|
|
1676
1679
|
return PermitUtils.deserialize(serialized);
|
|
1677
1680
|
};
|
|
1678
|
-
var getPermit =
|
|
1681
|
+
var getPermit = (chainId, account, hash) => {
|
|
1679
1682
|
return permitStore.getPermit(chainId, account, hash);
|
|
1680
1683
|
};
|
|
1681
|
-
var getPermits =
|
|
1684
|
+
var getPermits = (chainId, account) => {
|
|
1682
1685
|
return permitStore.getPermits(chainId, account);
|
|
1683
1686
|
};
|
|
1684
|
-
var getActivePermit =
|
|
1687
|
+
var getActivePermit = (chainId, account) => {
|
|
1685
1688
|
return permitStore.getActivePermit(chainId, account);
|
|
1686
1689
|
};
|
|
1687
1690
|
var getActivePermitHash = (chainId, account) => {
|
|
@@ -1930,9 +1933,7 @@ var MockThresholdNetworkAbi = [
|
|
|
1930
1933
|
];
|
|
1931
1934
|
|
|
1932
1935
|
// core/decrypt/cofheMocksDecryptForView.ts
|
|
1933
|
-
async function cofheMocksDecryptForView(ctHash, utype, permit, publicClient
|
|
1934
|
-
if (mocksDecryptDelay > 0)
|
|
1935
|
-
await sleep(mocksDecryptDelay);
|
|
1936
|
+
async function cofheMocksDecryptForView(ctHash, utype, permit, publicClient) {
|
|
1936
1937
|
const permission = PermitUtils.getPermission(permit, true);
|
|
1937
1938
|
const permissionWithBigInts = {
|
|
1938
1939
|
...permission,
|
|
@@ -1943,7 +1944,7 @@ async function cofheMocksDecryptForView(ctHash, utype, permit, publicClient, moc
|
|
|
1943
1944
|
address: MOCKS_THRESHOLD_NETWORK_ADDRESS,
|
|
1944
1945
|
abi: MockThresholdNetworkAbi,
|
|
1945
1946
|
functionName: "querySealOutput",
|
|
1946
|
-
args: [ctHash, BigInt(utype), permissionWithBigInts]
|
|
1947
|
+
args: [BigInt(ctHash), BigInt(utype), permissionWithBigInts]
|
|
1947
1948
|
});
|
|
1948
1949
|
if (error != "") {
|
|
1949
1950
|
throw new CofheError({
|
|
@@ -1984,7 +1985,7 @@ function convertSealedData(sealed) {
|
|
|
1984
1985
|
}
|
|
1985
1986
|
async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, permission) {
|
|
1986
1987
|
const body = {
|
|
1987
|
-
ct_tempkey: ctHash.toString(16).padStart(64, "0"),
|
|
1988
|
+
ct_tempkey: BigInt(ctHash).toString(16).padStart(64, "0"),
|
|
1988
1989
|
host_chain_id: chainId,
|
|
1989
1990
|
permit: permission
|
|
1990
1991
|
};
|
|
@@ -2177,96 +2178,6 @@ async function tnSealOutputV2(ctHash, chainId, permission, thresholdNetworkUrl)
|
|
|
2177
2178
|
const requestId = await submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, permission);
|
|
2178
2179
|
return await pollSealOutputStatus(thresholdNetworkUrl, requestId);
|
|
2179
2180
|
}
|
|
2180
|
-
async function cofheMocksDecryptForTx(ctHash, utype, permit, publicClient, mocksDecryptForTxDelay) {
|
|
2181
|
-
if (mocksDecryptForTxDelay > 0)
|
|
2182
|
-
await sleep(mocksDecryptForTxDelay);
|
|
2183
|
-
if (permit !== null) {
|
|
2184
|
-
let permission = PermitUtils.getPermission(permit, true);
|
|
2185
|
-
const permissionWithBigInts = {
|
|
2186
|
-
...permission,
|
|
2187
|
-
expiration: BigInt(permission.expiration),
|
|
2188
|
-
validatorId: BigInt(permission.validatorId)
|
|
2189
|
-
};
|
|
2190
|
-
const [allowed2, error2, result2] = await publicClient.readContract({
|
|
2191
|
-
address: MOCKS_THRESHOLD_NETWORK_ADDRESS,
|
|
2192
|
-
abi: MockThresholdNetworkAbi,
|
|
2193
|
-
functionName: "decryptForTxWithPermit",
|
|
2194
|
-
args: [ctHash, permissionWithBigInts]
|
|
2195
|
-
});
|
|
2196
|
-
if (error2 != "") {
|
|
2197
|
-
throw new CofheError({
|
|
2198
|
-
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
2199
|
-
message: `mocks decryptForTx call failed: ${error2}`
|
|
2200
|
-
});
|
|
2201
|
-
}
|
|
2202
|
-
if (allowed2 == false) {
|
|
2203
|
-
throw new CofheError({
|
|
2204
|
-
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
2205
|
-
message: `mocks decryptForTx call failed: ACL Access Denied (NotAllowed)`
|
|
2206
|
-
});
|
|
2207
|
-
}
|
|
2208
|
-
const chainId2 = await publicClient.getChainId();
|
|
2209
|
-
const ctHashBigInt2 = BigInt(ctHash);
|
|
2210
|
-
const resultBigInt2 = BigInt(result2);
|
|
2211
|
-
const encryptionType2 = Number((ctHashBigInt2 & 0x7fn << 8n) >> 8n);
|
|
2212
|
-
const ctHashBytes322 = pad(toHex(ctHashBigInt2), { size: 32 });
|
|
2213
|
-
const packed2 = encodePacked(
|
|
2214
|
-
["uint256", "uint32", "uint64", "bytes32"],
|
|
2215
|
-
[resultBigInt2, encryptionType2, BigInt(chainId2), ctHashBytes322]
|
|
2216
|
-
);
|
|
2217
|
-
const messageHash2 = keccak256(packed2);
|
|
2218
|
-
const signatureHex2 = await sign({
|
|
2219
|
-
hash: messageHash2,
|
|
2220
|
-
privateKey: MOCKS_DECRYPT_RESULT_SIGNER_PRIVATE_KEY,
|
|
2221
|
-
to: "hex"
|
|
2222
|
-
});
|
|
2223
|
-
const signature2 = signatureHex2.slice(2);
|
|
2224
|
-
return {
|
|
2225
|
-
ctHash,
|
|
2226
|
-
decryptedValue: BigInt(result2),
|
|
2227
|
-
signature: signature2
|
|
2228
|
-
};
|
|
2229
|
-
}
|
|
2230
|
-
const [allowed, error, result] = await publicClient.readContract({
|
|
2231
|
-
address: MOCKS_THRESHOLD_NETWORK_ADDRESS,
|
|
2232
|
-
abi: MockThresholdNetworkAbi,
|
|
2233
|
-
functionName: "decryptForTxWithoutPermit",
|
|
2234
|
-
args: [ctHash]
|
|
2235
|
-
});
|
|
2236
|
-
if (error != "") {
|
|
2237
|
-
throw new CofheError({
|
|
2238
|
-
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
2239
|
-
message: `mocks decryptForTx call failed: ${error}`
|
|
2240
|
-
});
|
|
2241
|
-
}
|
|
2242
|
-
if (allowed == false) {
|
|
2243
|
-
throw new CofheError({
|
|
2244
|
-
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
2245
|
-
message: `mocks decryptForTx call failed: ACL Access Denied (NotAllowed)`
|
|
2246
|
-
});
|
|
2247
|
-
}
|
|
2248
|
-
const chainId = await publicClient.getChainId();
|
|
2249
|
-
const ctHashBigInt = BigInt(ctHash);
|
|
2250
|
-
const resultBigInt = BigInt(result);
|
|
2251
|
-
const encryptionType = Number((ctHashBigInt & 0x7fn << 8n) >> 8n);
|
|
2252
|
-
const ctHashBytes32 = pad(toHex(ctHashBigInt), { size: 32 });
|
|
2253
|
-
const packed = encodePacked(
|
|
2254
|
-
["uint256", "uint32", "uint64", "bytes32"],
|
|
2255
|
-
[resultBigInt, encryptionType, BigInt(chainId), ctHashBytes32]
|
|
2256
|
-
);
|
|
2257
|
-
const messageHash = keccak256(packed);
|
|
2258
|
-
const signatureHex = await sign({
|
|
2259
|
-
hash: messageHash,
|
|
2260
|
-
privateKey: MOCKS_DECRYPT_RESULT_SIGNER_PRIVATE_KEY,
|
|
2261
|
-
to: "hex"
|
|
2262
|
-
});
|
|
2263
|
-
const signature = signatureHex.slice(2);
|
|
2264
|
-
return {
|
|
2265
|
-
ctHash,
|
|
2266
|
-
decryptedValue: BigInt(result),
|
|
2267
|
-
signature
|
|
2268
|
-
};
|
|
2269
|
-
}
|
|
2270
2181
|
|
|
2271
2182
|
// core/decrypt/decryptForViewBuilder.ts
|
|
2272
2183
|
var DecryptForViewBuilder = class extends BaseBuilder {
|
|
@@ -2441,7 +2352,9 @@ var DecryptForViewBuilder = class extends BaseBuilder {
|
|
|
2441
2352
|
async mocksSealOutput(permit) {
|
|
2442
2353
|
this.assertPublicClient();
|
|
2443
2354
|
const mocksDecryptDelay = this.config.mocks.decryptDelay;
|
|
2444
|
-
|
|
2355
|
+
if (mocksDecryptDelay > 0)
|
|
2356
|
+
await sleep(mocksDecryptDelay);
|
|
2357
|
+
return cofheMocksDecryptForView(this.ctHash, this.utype, permit, this.publicClient);
|
|
2445
2358
|
}
|
|
2446
2359
|
/**
|
|
2447
2360
|
* In the production context, perform a true decryption with the CoFHE coprocessor.
|
|
@@ -2490,9 +2403,57 @@ var DecryptForViewBuilder = class extends BaseBuilder {
|
|
|
2490
2403
|
return convertViaUtype(this.utype, unsealed);
|
|
2491
2404
|
}
|
|
2492
2405
|
};
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2406
|
+
async function cofheMocksDecryptForTx(ctHash, utype, permit, publicClient) {
|
|
2407
|
+
let allowed;
|
|
2408
|
+
let error;
|
|
2409
|
+
let decryptedValue;
|
|
2410
|
+
if (permit !== null) {
|
|
2411
|
+
let permission = PermitUtils.getPermission(permit, true);
|
|
2412
|
+
const permissionWithBigInts = {
|
|
2413
|
+
...permission,
|
|
2414
|
+
expiration: BigInt(permission.expiration),
|
|
2415
|
+
validatorId: BigInt(permission.validatorId)
|
|
2416
|
+
};
|
|
2417
|
+
[allowed, error, decryptedValue] = await publicClient.readContract({
|
|
2418
|
+
address: MOCKS_THRESHOLD_NETWORK_ADDRESS,
|
|
2419
|
+
abi: MockThresholdNetworkAbi,
|
|
2420
|
+
functionName: "decryptForTxWithPermit",
|
|
2421
|
+
args: [BigInt(ctHash), permissionWithBigInts]
|
|
2422
|
+
});
|
|
2423
|
+
} else {
|
|
2424
|
+
[allowed, error, decryptedValue] = await publicClient.readContract({
|
|
2425
|
+
address: MOCKS_THRESHOLD_NETWORK_ADDRESS,
|
|
2426
|
+
abi: MockThresholdNetworkAbi,
|
|
2427
|
+
functionName: "decryptForTxWithoutPermit",
|
|
2428
|
+
args: [BigInt(ctHash)]
|
|
2429
|
+
});
|
|
2430
|
+
}
|
|
2431
|
+
if (error != "") {
|
|
2432
|
+
throw new CofheError({
|
|
2433
|
+
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
2434
|
+
message: `mocks decryptForTx call failed: ${error}`
|
|
2435
|
+
});
|
|
2436
|
+
}
|
|
2437
|
+
if (allowed == false) {
|
|
2438
|
+
throw new CofheError({
|
|
2439
|
+
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
2440
|
+
message: `mocks decryptForTx call failed: ACL Access Denied (NotAllowed)`
|
|
2441
|
+
});
|
|
2442
|
+
}
|
|
2443
|
+
const packed = encodePacked(["uint256", "uint256"], [BigInt(ctHash), decryptedValue]);
|
|
2444
|
+
const messageHash = keccak256(packed);
|
|
2445
|
+
const signature = await sign({
|
|
2446
|
+
hash: messageHash,
|
|
2447
|
+
privateKey: MOCKS_DECRYPT_RESULT_SIGNER_PRIVATE_KEY,
|
|
2448
|
+
to: "hex"
|
|
2449
|
+
});
|
|
2450
|
+
return {
|
|
2451
|
+
ctHash,
|
|
2452
|
+
decryptedValue,
|
|
2453
|
+
signature
|
|
2454
|
+
};
|
|
2455
|
+
}
|
|
2456
|
+
function normalizeTnSignature(signature) {
|
|
2496
2457
|
if (typeof signature !== "string") {
|
|
2497
2458
|
throw new CofheError({
|
|
2498
2459
|
code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
|
|
@@ -2509,7 +2470,9 @@ function normalizeSignature(signature) {
|
|
|
2509
2470
|
message: "decrypt response returned empty signature"
|
|
2510
2471
|
});
|
|
2511
2472
|
}
|
|
2512
|
-
|
|
2473
|
+
const prefixed = trimmed.startsWith("0x") ? trimmed : `0x${trimmed}`;
|
|
2474
|
+
const parsed = parseSignature(prefixed);
|
|
2475
|
+
return serializeSignature(parsed);
|
|
2513
2476
|
}
|
|
2514
2477
|
function parseDecryptedBytesToBigInt(decrypted) {
|
|
2515
2478
|
if (!Array.isArray(decrypted)) {
|
|
@@ -2546,59 +2509,79 @@ function parseDecryptedBytesToBigInt(decrypted) {
|
|
|
2546
2509
|
}
|
|
2547
2510
|
return BigInt(`0x${hex}`);
|
|
2548
2511
|
}
|
|
2549
|
-
|
|
2512
|
+
|
|
2513
|
+
// core/decrypt/tnDecryptV2.ts
|
|
2514
|
+
var POLL_INTERVAL_MS2 = 1e3;
|
|
2515
|
+
var POLL_TIMEOUT_MS2 = 5 * 60 * 1e3;
|
|
2516
|
+
function assertDecryptSubmitResponseV2(value) {
|
|
2550
2517
|
if (value == null || typeof value !== "object") {
|
|
2551
2518
|
throw new CofheError({
|
|
2552
2519
|
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
2553
|
-
message: "decrypt response must be a JSON object",
|
|
2520
|
+
message: "decrypt submit response must be a JSON object",
|
|
2554
2521
|
context: {
|
|
2555
2522
|
value
|
|
2556
2523
|
}
|
|
2557
2524
|
});
|
|
2558
2525
|
}
|
|
2559
2526
|
const v = value;
|
|
2560
|
-
|
|
2561
|
-
const signature = v.signature;
|
|
2562
|
-
const encryptionType = v.encryption_type;
|
|
2563
|
-
const errorMessage = v.error_message;
|
|
2564
|
-
if (!Array.isArray(decrypted)) {
|
|
2527
|
+
if (typeof v.request_id !== "string" || v.request_id.trim().length === 0) {
|
|
2565
2528
|
throw new CofheError({
|
|
2566
|
-
code: "
|
|
2567
|
-
message: "decrypt response missing
|
|
2568
|
-
context: {
|
|
2529
|
+
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
2530
|
+
message: "decrypt submit response missing request_id",
|
|
2531
|
+
context: {
|
|
2532
|
+
value
|
|
2533
|
+
}
|
|
2569
2534
|
});
|
|
2570
2535
|
}
|
|
2571
|
-
|
|
2536
|
+
return { request_id: v.request_id };
|
|
2537
|
+
}
|
|
2538
|
+
function assertDecryptStatusResponseV2(value) {
|
|
2539
|
+
if (value == null || typeof value !== "object") {
|
|
2572
2540
|
throw new CofheError({
|
|
2573
|
-
code: "
|
|
2574
|
-
message: "decrypt response
|
|
2575
|
-
context: {
|
|
2541
|
+
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
2542
|
+
message: "decrypt status response must be a JSON object",
|
|
2543
|
+
context: {
|
|
2544
|
+
value
|
|
2545
|
+
}
|
|
2576
2546
|
});
|
|
2577
2547
|
}
|
|
2578
|
-
|
|
2548
|
+
const v = value;
|
|
2549
|
+
const requestId = v.request_id;
|
|
2550
|
+
const status = v.status;
|
|
2551
|
+
const submittedAt = v.submitted_at;
|
|
2552
|
+
if (typeof requestId !== "string" || requestId.trim().length === 0) {
|
|
2579
2553
|
throw new CofheError({
|
|
2580
2554
|
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
2581
|
-
message: "decrypt response missing
|
|
2582
|
-
context: {
|
|
2555
|
+
message: "decrypt status response missing request_id",
|
|
2556
|
+
context: {
|
|
2557
|
+
value
|
|
2558
|
+
}
|
|
2583
2559
|
});
|
|
2584
2560
|
}
|
|
2585
|
-
if (
|
|
2561
|
+
if (status !== "PROCESSING" && status !== "COMPLETED") {
|
|
2586
2562
|
throw new CofheError({
|
|
2587
2563
|
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
2588
|
-
message: "decrypt response
|
|
2589
|
-
context: {
|
|
2564
|
+
message: "decrypt status response has invalid status",
|
|
2565
|
+
context: {
|
|
2566
|
+
value,
|
|
2567
|
+
status
|
|
2568
|
+
}
|
|
2590
2569
|
});
|
|
2591
2570
|
}
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2571
|
+
if (typeof submittedAt !== "string" || submittedAt.trim().length === 0) {
|
|
2572
|
+
throw new CofheError({
|
|
2573
|
+
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
2574
|
+
message: "decrypt status response missing submitted_at",
|
|
2575
|
+
context: {
|
|
2576
|
+
value
|
|
2577
|
+
}
|
|
2578
|
+
});
|
|
2579
|
+
}
|
|
2580
|
+
return value;
|
|
2598
2581
|
}
|
|
2599
|
-
async function
|
|
2582
|
+
async function submitDecryptRequestV2(thresholdNetworkUrl, ctHash, chainId, permission) {
|
|
2600
2583
|
const body = {
|
|
2601
|
-
ct_tempkey: ctHash.toString(16).padStart(64, "0"),
|
|
2584
|
+
ct_tempkey: BigInt(ctHash).toString(16).padStart(64, "0"),
|
|
2602
2585
|
host_chain_id: chainId
|
|
2603
2586
|
};
|
|
2604
2587
|
if (permission) {
|
|
@@ -2606,7 +2589,7 @@ async function tnDecrypt(ctHash, chainId, permission, thresholdNetworkUrl) {
|
|
|
2606
2589
|
}
|
|
2607
2590
|
let response;
|
|
2608
2591
|
try {
|
|
2609
|
-
response = await fetch(`${thresholdNetworkUrl}/decrypt`, {
|
|
2592
|
+
response = await fetch(`${thresholdNetworkUrl}/v2/decrypt`, {
|
|
2610
2593
|
method: "POST",
|
|
2611
2594
|
headers: {
|
|
2612
2595
|
"Content-Type": "application/json"
|
|
@@ -2625,18 +2608,15 @@ async function tnDecrypt(ctHash, chainId, permission, thresholdNetworkUrl) {
|
|
|
2625
2608
|
}
|
|
2626
2609
|
});
|
|
2627
2610
|
}
|
|
2628
|
-
const responseText = await response.text();
|
|
2629
2611
|
if (!response.ok) {
|
|
2630
|
-
let errorMessage =
|
|
2612
|
+
let errorMessage = `HTTP ${response.status}`;
|
|
2631
2613
|
try {
|
|
2632
|
-
const errorBody =
|
|
2614
|
+
const errorBody = await response.json();
|
|
2633
2615
|
const maybeMessage = errorBody.error_message || errorBody.message;
|
|
2634
2616
|
if (typeof maybeMessage === "string" && maybeMessage.length > 0)
|
|
2635
2617
|
errorMessage = maybeMessage;
|
|
2636
2618
|
} catch {
|
|
2637
|
-
|
|
2638
|
-
if (trimmed.length > 0)
|
|
2639
|
-
errorMessage = trimmed;
|
|
2619
|
+
errorMessage = response.statusText || errorMessage;
|
|
2640
2620
|
}
|
|
2641
2621
|
throw new CofheError({
|
|
2642
2622
|
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
@@ -2646,41 +2626,163 @@ async function tnDecrypt(ctHash, chainId, permission, thresholdNetworkUrl) {
|
|
|
2646
2626
|
thresholdNetworkUrl,
|
|
2647
2627
|
status: response.status,
|
|
2648
2628
|
statusText: response.statusText,
|
|
2649
|
-
body
|
|
2650
|
-
responseText
|
|
2629
|
+
body
|
|
2651
2630
|
}
|
|
2652
2631
|
});
|
|
2653
2632
|
}
|
|
2654
2633
|
let rawJson;
|
|
2655
2634
|
try {
|
|
2656
|
-
rawJson =
|
|
2635
|
+
rawJson = await response.json();
|
|
2657
2636
|
} catch (e) {
|
|
2658
2637
|
throw new CofheError({
|
|
2659
2638
|
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
2660
|
-
message: `Failed to parse decrypt response`,
|
|
2639
|
+
message: `Failed to parse decrypt submit response`,
|
|
2661
2640
|
cause: e instanceof Error ? e : void 0,
|
|
2662
2641
|
context: {
|
|
2663
2642
|
thresholdNetworkUrl,
|
|
2664
|
-
body
|
|
2665
|
-
responseText
|
|
2643
|
+
body
|
|
2666
2644
|
}
|
|
2667
2645
|
});
|
|
2668
2646
|
}
|
|
2669
|
-
const
|
|
2670
|
-
|
|
2671
|
-
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2647
|
+
const submitResponse = assertDecryptSubmitResponseV2(rawJson);
|
|
2648
|
+
return submitResponse.request_id;
|
|
2649
|
+
}
|
|
2650
|
+
async function pollDecryptStatusV2(thresholdNetworkUrl, requestId) {
|
|
2651
|
+
const startTime = Date.now();
|
|
2652
|
+
let completed = false;
|
|
2653
|
+
while (!completed) {
|
|
2654
|
+
if (Date.now() - startTime > POLL_TIMEOUT_MS2) {
|
|
2655
|
+
throw new CofheError({
|
|
2656
|
+
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
2657
|
+
message: `decrypt polling timed out after ${POLL_TIMEOUT_MS2}ms`,
|
|
2658
|
+
hint: "The request may still be processing. Try again later.",
|
|
2659
|
+
context: {
|
|
2660
|
+
thresholdNetworkUrl,
|
|
2661
|
+
requestId,
|
|
2662
|
+
timeoutMs: POLL_TIMEOUT_MS2
|
|
2663
|
+
}
|
|
2664
|
+
});
|
|
2665
|
+
}
|
|
2666
|
+
let response;
|
|
2667
|
+
try {
|
|
2668
|
+
response = await fetch(`${thresholdNetworkUrl}/v2/decrypt/${requestId}`, {
|
|
2669
|
+
method: "GET",
|
|
2670
|
+
headers: {
|
|
2671
|
+
"Content-Type": "application/json"
|
|
2672
|
+
}
|
|
2673
|
+
});
|
|
2674
|
+
} catch (e) {
|
|
2675
|
+
throw new CofheError({
|
|
2676
|
+
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
2677
|
+
message: `decrypt status poll failed`,
|
|
2678
|
+
hint: "Ensure the threshold network URL is valid and reachable.",
|
|
2679
|
+
cause: e instanceof Error ? e : void 0,
|
|
2680
|
+
context: {
|
|
2681
|
+
thresholdNetworkUrl,
|
|
2682
|
+
requestId
|
|
2683
|
+
}
|
|
2684
|
+
});
|
|
2685
|
+
}
|
|
2686
|
+
if (response.status === 404) {
|
|
2687
|
+
throw new CofheError({
|
|
2688
|
+
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
2689
|
+
message: `decrypt request not found: ${requestId}`,
|
|
2690
|
+
hint: "The request may have expired or been invalid.",
|
|
2691
|
+
context: {
|
|
2692
|
+
thresholdNetworkUrl,
|
|
2693
|
+
requestId
|
|
2694
|
+
}
|
|
2695
|
+
});
|
|
2696
|
+
}
|
|
2697
|
+
if (!response.ok) {
|
|
2698
|
+
let errorMessage = `HTTP ${response.status}`;
|
|
2699
|
+
try {
|
|
2700
|
+
const errorBody = await response.json();
|
|
2701
|
+
const maybeMessage = errorBody.error_message || errorBody.message;
|
|
2702
|
+
if (typeof maybeMessage === "string" && maybeMessage.length > 0)
|
|
2703
|
+
errorMessage = maybeMessage;
|
|
2704
|
+
} catch {
|
|
2705
|
+
errorMessage = response.statusText || errorMessage;
|
|
2678
2706
|
}
|
|
2679
|
-
|
|
2707
|
+
throw new CofheError({
|
|
2708
|
+
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
2709
|
+
message: `decrypt status poll failed: ${errorMessage}`,
|
|
2710
|
+
context: {
|
|
2711
|
+
thresholdNetworkUrl,
|
|
2712
|
+
requestId,
|
|
2713
|
+
status: response.status,
|
|
2714
|
+
statusText: response.statusText
|
|
2715
|
+
}
|
|
2716
|
+
});
|
|
2717
|
+
}
|
|
2718
|
+
let rawJson;
|
|
2719
|
+
try {
|
|
2720
|
+
rawJson = await response.json();
|
|
2721
|
+
} catch (e) {
|
|
2722
|
+
throw new CofheError({
|
|
2723
|
+
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
2724
|
+
message: `Failed to parse decrypt status response`,
|
|
2725
|
+
cause: e instanceof Error ? e : void 0,
|
|
2726
|
+
context: {
|
|
2727
|
+
thresholdNetworkUrl,
|
|
2728
|
+
requestId
|
|
2729
|
+
}
|
|
2730
|
+
});
|
|
2731
|
+
}
|
|
2732
|
+
const statusResponse = assertDecryptStatusResponseV2(rawJson);
|
|
2733
|
+
if (statusResponse.status === "COMPLETED") {
|
|
2734
|
+
if (statusResponse.is_succeed === false) {
|
|
2735
|
+
const errorMessage = statusResponse.error_message || "Unknown error";
|
|
2736
|
+
throw new CofheError({
|
|
2737
|
+
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
2738
|
+
message: `decrypt request failed: ${errorMessage}`,
|
|
2739
|
+
context: {
|
|
2740
|
+
thresholdNetworkUrl,
|
|
2741
|
+
requestId,
|
|
2742
|
+
statusResponse
|
|
2743
|
+
}
|
|
2744
|
+
});
|
|
2745
|
+
}
|
|
2746
|
+
if (statusResponse.error_message) {
|
|
2747
|
+
throw new CofheError({
|
|
2748
|
+
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
2749
|
+
message: `decrypt request failed: ${statusResponse.error_message}`,
|
|
2750
|
+
context: {
|
|
2751
|
+
thresholdNetworkUrl,
|
|
2752
|
+
requestId,
|
|
2753
|
+
statusResponse
|
|
2754
|
+
}
|
|
2755
|
+
});
|
|
2756
|
+
}
|
|
2757
|
+
if (!Array.isArray(statusResponse.decrypted)) {
|
|
2758
|
+
throw new CofheError({
|
|
2759
|
+
code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
|
|
2760
|
+
message: "decrypt completed but response missing <decrypted> byte array",
|
|
2761
|
+
context: {
|
|
2762
|
+
thresholdNetworkUrl,
|
|
2763
|
+
requestId,
|
|
2764
|
+
statusResponse
|
|
2765
|
+
}
|
|
2766
|
+
});
|
|
2767
|
+
}
|
|
2768
|
+
const decryptedValue = parseDecryptedBytesToBigInt(statusResponse.decrypted);
|
|
2769
|
+
const signature = normalizeTnSignature(statusResponse.signature);
|
|
2770
|
+
return { decryptedValue, signature };
|
|
2771
|
+
}
|
|
2772
|
+
await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS2));
|
|
2680
2773
|
}
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
|
|
2774
|
+
throw new CofheError({
|
|
2775
|
+
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
2776
|
+
message: "Polling loop exited unexpectedly",
|
|
2777
|
+
context: {
|
|
2778
|
+
thresholdNetworkUrl,
|
|
2779
|
+
requestId
|
|
2780
|
+
}
|
|
2781
|
+
});
|
|
2782
|
+
}
|
|
2783
|
+
async function tnDecryptV2(ctHash, chainId, permission, thresholdNetworkUrl) {
|
|
2784
|
+
const requestId = await submitDecryptRequestV2(thresholdNetworkUrl, ctHash, chainId, permission);
|
|
2785
|
+
return await pollDecryptStatusV2(thresholdNetworkUrl, requestId);
|
|
2684
2786
|
}
|
|
2685
2787
|
|
|
2686
2788
|
// core/decrypt/decryptForTxBuilder.ts
|
|
@@ -2828,7 +2930,9 @@ var DecryptForTxBuilder = class extends BaseBuilder {
|
|
|
2828
2930
|
async mocksDecryptForTx(permit) {
|
|
2829
2931
|
this.assertPublicClient();
|
|
2830
2932
|
const delay = this.config.mocks.decryptDelay;
|
|
2831
|
-
|
|
2933
|
+
if (delay > 0)
|
|
2934
|
+
await sleep(delay);
|
|
2935
|
+
const result = await cofheMocksDecryptForTx(this.ctHash, 0, permit, this.publicClient);
|
|
2832
2936
|
return result;
|
|
2833
2937
|
}
|
|
2834
2938
|
/**
|
|
@@ -2839,7 +2943,7 @@ var DecryptForTxBuilder = class extends BaseBuilder {
|
|
|
2839
2943
|
this.assertPublicClient();
|
|
2840
2944
|
const thresholdNetworkUrl = await this.getThresholdNetworkUrl();
|
|
2841
2945
|
const permission = permit ? PermitUtils.getPermission(permit, true) : null;
|
|
2842
|
-
const { decryptedValue, signature } = await
|
|
2946
|
+
const { decryptedValue, signature } = await tnDecryptV2(this.ctHash, this.chainId, permission, thresholdNetworkUrl);
|
|
2843
2947
|
return {
|
|
2844
2948
|
ctHash: this.ctHash,
|
|
2845
2949
|
decryptedValue,
|
|
@@ -3047,19 +3151,19 @@ function createCofheClientBase(opts) {
|
|
|
3047
3151
|
return permits.getOrCreateSharingPermit(publicClient, walletClient, options, _chainId, _account);
|
|
3048
3152
|
},
|
|
3049
3153
|
// Retrieval methods (auto-fill chainId/account)
|
|
3050
|
-
getPermit:
|
|
3154
|
+
getPermit: (hash, chainId, account) => {
|
|
3051
3155
|
const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
|
|
3052
3156
|
return permits.getPermit(_chainId, _account, hash);
|
|
3053
3157
|
},
|
|
3054
|
-
getPermits:
|
|
3158
|
+
getPermits: (chainId, account) => {
|
|
3055
3159
|
const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
|
|
3056
3160
|
return permits.getPermits(_chainId, _account);
|
|
3057
3161
|
},
|
|
3058
|
-
getActivePermit:
|
|
3162
|
+
getActivePermit: (chainId, account) => {
|
|
3059
3163
|
const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
|
|
3060
3164
|
return permits.getActivePermit(_chainId, _account);
|
|
3061
3165
|
},
|
|
3062
|
-
getActivePermitHash:
|
|
3166
|
+
getActivePermitHash: (chainId, account) => {
|
|
3063
3167
|
const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
|
|
3064
3168
|
return permits.getActivePermitHash(_chainId, _account);
|
|
3065
3169
|
},
|