@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
package/dist/web.cjs
CHANGED
|
@@ -652,7 +652,7 @@ async function insertCtHashes(items, walletClient) {
|
|
|
652
652
|
});
|
|
653
653
|
}
|
|
654
654
|
}
|
|
655
|
-
async function createProofSignatures(items, securityZone) {
|
|
655
|
+
async function createProofSignatures(items, securityZone, account) {
|
|
656
656
|
let signatures = [];
|
|
657
657
|
let encInputSignerClient;
|
|
658
658
|
try {
|
|
@@ -669,12 +669,15 @@ async function createProofSignatures(items, securityZone) {
|
|
|
669
669
|
}
|
|
670
670
|
try {
|
|
671
671
|
for (const item of items) {
|
|
672
|
-
const packedData = viem.encodePacked(
|
|
672
|
+
const packedData = viem.encodePacked(
|
|
673
|
+
["uint256", "uint8", "uint8", "address", "uint256"],
|
|
674
|
+
[BigInt(item.ctHash), item.utype, securityZone, account, BigInt(chains.hardhat.id)]
|
|
675
|
+
);
|
|
673
676
|
const messageHash = viem.keccak256(packedData);
|
|
674
|
-
const
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
677
|
+
const signature = await accounts.sign({
|
|
678
|
+
hash: messageHash,
|
|
679
|
+
privateKey: MOCKS_ZK_VERIFIER_SIGNER_PRIVATE_KEY,
|
|
680
|
+
to: "hex"
|
|
678
681
|
});
|
|
679
682
|
signatures.push(signature);
|
|
680
683
|
}
|
|
@@ -705,7 +708,7 @@ async function cofheMocksZkVerifySign(items, account, securityZone, publicClient
|
|
|
705
708
|
const _walletClient = zkvWalletClient ?? createMockZkVerifierSigner();
|
|
706
709
|
const encryptableItems = await calcCtHashes(items, account, securityZone, publicClient);
|
|
707
710
|
await insertCtHashes(encryptableItems, _walletClient);
|
|
708
|
-
const signatures = await createProofSignatures(encryptableItems, securityZone);
|
|
711
|
+
const signatures = await createProofSignatures(encryptableItems, securityZone, account);
|
|
709
712
|
return encryptableItems.map((item, index) => ({
|
|
710
713
|
ct_hash: item.ctHash.toString(),
|
|
711
714
|
signature: signatures[index]
|
|
@@ -2510,13 +2513,13 @@ var serialize = (permit) => {
|
|
|
2510
2513
|
var deserialize = (serialized) => {
|
|
2511
2514
|
return PermitUtils.deserialize(serialized);
|
|
2512
2515
|
};
|
|
2513
|
-
var getPermit2 =
|
|
2516
|
+
var getPermit2 = (chainId, account, hash) => {
|
|
2514
2517
|
return permitStore.getPermit(chainId, account, hash);
|
|
2515
2518
|
};
|
|
2516
|
-
var getPermits2 =
|
|
2519
|
+
var getPermits2 = (chainId, account) => {
|
|
2517
2520
|
return permitStore.getPermits(chainId, account);
|
|
2518
2521
|
};
|
|
2519
|
-
var getActivePermit2 =
|
|
2522
|
+
var getActivePermit2 = (chainId, account) => {
|
|
2520
2523
|
return permitStore.getActivePermit(chainId, account);
|
|
2521
2524
|
};
|
|
2522
2525
|
var getActivePermitHash2 = (chainId, account) => {
|
|
@@ -2765,9 +2768,7 @@ var MockThresholdNetworkAbi = [
|
|
|
2765
2768
|
];
|
|
2766
2769
|
|
|
2767
2770
|
// core/decrypt/cofheMocksDecryptForView.ts
|
|
2768
|
-
async function cofheMocksDecryptForView(ctHash, utype, permit, publicClient
|
|
2769
|
-
if (mocksDecryptDelay > 0)
|
|
2770
|
-
await sleep(mocksDecryptDelay);
|
|
2771
|
+
async function cofheMocksDecryptForView(ctHash, utype, permit, publicClient) {
|
|
2771
2772
|
const permission = PermitUtils.getPermission(permit, true);
|
|
2772
2773
|
const permissionWithBigInts = {
|
|
2773
2774
|
...permission,
|
|
@@ -2778,7 +2779,7 @@ async function cofheMocksDecryptForView(ctHash, utype, permit, publicClient, moc
|
|
|
2778
2779
|
address: MOCKS_THRESHOLD_NETWORK_ADDRESS,
|
|
2779
2780
|
abi: MockThresholdNetworkAbi,
|
|
2780
2781
|
functionName: "querySealOutput",
|
|
2781
|
-
args: [ctHash, BigInt(utype), permissionWithBigInts]
|
|
2782
|
+
args: [BigInt(ctHash), BigInt(utype), permissionWithBigInts]
|
|
2782
2783
|
});
|
|
2783
2784
|
if (error != "") {
|
|
2784
2785
|
throw new CofheError({
|
|
@@ -2819,7 +2820,7 @@ function convertSealedData(sealed) {
|
|
|
2819
2820
|
}
|
|
2820
2821
|
async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, permission) {
|
|
2821
2822
|
const body = {
|
|
2822
|
-
ct_tempkey: ctHash.toString(16).padStart(64, "0"),
|
|
2823
|
+
ct_tempkey: BigInt(ctHash).toString(16).padStart(64, "0"),
|
|
2823
2824
|
host_chain_id: chainId,
|
|
2824
2825
|
permit: permission
|
|
2825
2826
|
};
|
|
@@ -3012,96 +3013,6 @@ async function tnSealOutputV2(ctHash, chainId, permission, thresholdNetworkUrl)
|
|
|
3012
3013
|
const requestId = await submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, permission);
|
|
3013
3014
|
return await pollSealOutputStatus(thresholdNetworkUrl, requestId);
|
|
3014
3015
|
}
|
|
3015
|
-
async function cofheMocksDecryptForTx(ctHash, utype, permit, publicClient, mocksDecryptForTxDelay) {
|
|
3016
|
-
if (mocksDecryptForTxDelay > 0)
|
|
3017
|
-
await sleep(mocksDecryptForTxDelay);
|
|
3018
|
-
if (permit !== null) {
|
|
3019
|
-
let permission = PermitUtils.getPermission(permit, true);
|
|
3020
|
-
const permissionWithBigInts = {
|
|
3021
|
-
...permission,
|
|
3022
|
-
expiration: BigInt(permission.expiration),
|
|
3023
|
-
validatorId: BigInt(permission.validatorId)
|
|
3024
|
-
};
|
|
3025
|
-
const [allowed2, error2, result2] = await publicClient.readContract({
|
|
3026
|
-
address: MOCKS_THRESHOLD_NETWORK_ADDRESS,
|
|
3027
|
-
abi: MockThresholdNetworkAbi,
|
|
3028
|
-
functionName: "decryptForTxWithPermit",
|
|
3029
|
-
args: [ctHash, permissionWithBigInts]
|
|
3030
|
-
});
|
|
3031
|
-
if (error2 != "") {
|
|
3032
|
-
throw new CofheError({
|
|
3033
|
-
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
3034
|
-
message: `mocks decryptForTx call failed: ${error2}`
|
|
3035
|
-
});
|
|
3036
|
-
}
|
|
3037
|
-
if (allowed2 == false) {
|
|
3038
|
-
throw new CofheError({
|
|
3039
|
-
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
3040
|
-
message: `mocks decryptForTx call failed: ACL Access Denied (NotAllowed)`
|
|
3041
|
-
});
|
|
3042
|
-
}
|
|
3043
|
-
const chainId2 = await publicClient.getChainId();
|
|
3044
|
-
const ctHashBigInt2 = BigInt(ctHash);
|
|
3045
|
-
const resultBigInt2 = BigInt(result2);
|
|
3046
|
-
const encryptionType2 = Number((ctHashBigInt2 & 0x7fn << 8n) >> 8n);
|
|
3047
|
-
const ctHashBytes322 = viem.pad(viem.toHex(ctHashBigInt2), { size: 32 });
|
|
3048
|
-
const packed2 = viem.encodePacked(
|
|
3049
|
-
["uint256", "uint32", "uint64", "bytes32"],
|
|
3050
|
-
[resultBigInt2, encryptionType2, BigInt(chainId2), ctHashBytes322]
|
|
3051
|
-
);
|
|
3052
|
-
const messageHash2 = viem.keccak256(packed2);
|
|
3053
|
-
const signatureHex2 = await accounts.sign({
|
|
3054
|
-
hash: messageHash2,
|
|
3055
|
-
privateKey: MOCKS_DECRYPT_RESULT_SIGNER_PRIVATE_KEY,
|
|
3056
|
-
to: "hex"
|
|
3057
|
-
});
|
|
3058
|
-
const signature2 = signatureHex2.slice(2);
|
|
3059
|
-
return {
|
|
3060
|
-
ctHash,
|
|
3061
|
-
decryptedValue: BigInt(result2),
|
|
3062
|
-
signature: signature2
|
|
3063
|
-
};
|
|
3064
|
-
}
|
|
3065
|
-
const [allowed, error, result] = await publicClient.readContract({
|
|
3066
|
-
address: MOCKS_THRESHOLD_NETWORK_ADDRESS,
|
|
3067
|
-
abi: MockThresholdNetworkAbi,
|
|
3068
|
-
functionName: "decryptForTxWithoutPermit",
|
|
3069
|
-
args: [ctHash]
|
|
3070
|
-
});
|
|
3071
|
-
if (error != "") {
|
|
3072
|
-
throw new CofheError({
|
|
3073
|
-
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
3074
|
-
message: `mocks decryptForTx call failed: ${error}`
|
|
3075
|
-
});
|
|
3076
|
-
}
|
|
3077
|
-
if (allowed == false) {
|
|
3078
|
-
throw new CofheError({
|
|
3079
|
-
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
3080
|
-
message: `mocks decryptForTx call failed: ACL Access Denied (NotAllowed)`
|
|
3081
|
-
});
|
|
3082
|
-
}
|
|
3083
|
-
const chainId = await publicClient.getChainId();
|
|
3084
|
-
const ctHashBigInt = BigInt(ctHash);
|
|
3085
|
-
const resultBigInt = BigInt(result);
|
|
3086
|
-
const encryptionType = Number((ctHashBigInt & 0x7fn << 8n) >> 8n);
|
|
3087
|
-
const ctHashBytes32 = viem.pad(viem.toHex(ctHashBigInt), { size: 32 });
|
|
3088
|
-
const packed = viem.encodePacked(
|
|
3089
|
-
["uint256", "uint32", "uint64", "bytes32"],
|
|
3090
|
-
[resultBigInt, encryptionType, BigInt(chainId), ctHashBytes32]
|
|
3091
|
-
);
|
|
3092
|
-
const messageHash = viem.keccak256(packed);
|
|
3093
|
-
const signatureHex = await accounts.sign({
|
|
3094
|
-
hash: messageHash,
|
|
3095
|
-
privateKey: MOCKS_DECRYPT_RESULT_SIGNER_PRIVATE_KEY,
|
|
3096
|
-
to: "hex"
|
|
3097
|
-
});
|
|
3098
|
-
const signature = signatureHex.slice(2);
|
|
3099
|
-
return {
|
|
3100
|
-
ctHash,
|
|
3101
|
-
decryptedValue: BigInt(result),
|
|
3102
|
-
signature
|
|
3103
|
-
};
|
|
3104
|
-
}
|
|
3105
3016
|
|
|
3106
3017
|
// core/decrypt/decryptForViewBuilder.ts
|
|
3107
3018
|
var DecryptForViewBuilder = class extends BaseBuilder {
|
|
@@ -3276,7 +3187,9 @@ var DecryptForViewBuilder = class extends BaseBuilder {
|
|
|
3276
3187
|
async mocksSealOutput(permit) {
|
|
3277
3188
|
this.assertPublicClient();
|
|
3278
3189
|
const mocksDecryptDelay = this.config.mocks.decryptDelay;
|
|
3279
|
-
|
|
3190
|
+
if (mocksDecryptDelay > 0)
|
|
3191
|
+
await sleep(mocksDecryptDelay);
|
|
3192
|
+
return cofheMocksDecryptForView(this.ctHash, this.utype, permit, this.publicClient);
|
|
3280
3193
|
}
|
|
3281
3194
|
/**
|
|
3282
3195
|
* In the production context, perform a true decryption with the CoFHE coprocessor.
|
|
@@ -3325,9 +3238,57 @@ var DecryptForViewBuilder = class extends BaseBuilder {
|
|
|
3325
3238
|
return convertViaUtype(this.utype, unsealed);
|
|
3326
3239
|
}
|
|
3327
3240
|
};
|
|
3328
|
-
|
|
3329
|
-
|
|
3330
|
-
|
|
3241
|
+
async function cofheMocksDecryptForTx(ctHash, utype, permit, publicClient) {
|
|
3242
|
+
let allowed;
|
|
3243
|
+
let error;
|
|
3244
|
+
let decryptedValue;
|
|
3245
|
+
if (permit !== null) {
|
|
3246
|
+
let permission = PermitUtils.getPermission(permit, true);
|
|
3247
|
+
const permissionWithBigInts = {
|
|
3248
|
+
...permission,
|
|
3249
|
+
expiration: BigInt(permission.expiration),
|
|
3250
|
+
validatorId: BigInt(permission.validatorId)
|
|
3251
|
+
};
|
|
3252
|
+
[allowed, error, decryptedValue] = await publicClient.readContract({
|
|
3253
|
+
address: MOCKS_THRESHOLD_NETWORK_ADDRESS,
|
|
3254
|
+
abi: MockThresholdNetworkAbi,
|
|
3255
|
+
functionName: "decryptForTxWithPermit",
|
|
3256
|
+
args: [BigInt(ctHash), permissionWithBigInts]
|
|
3257
|
+
});
|
|
3258
|
+
} else {
|
|
3259
|
+
[allowed, error, decryptedValue] = await publicClient.readContract({
|
|
3260
|
+
address: MOCKS_THRESHOLD_NETWORK_ADDRESS,
|
|
3261
|
+
abi: MockThresholdNetworkAbi,
|
|
3262
|
+
functionName: "decryptForTxWithoutPermit",
|
|
3263
|
+
args: [BigInt(ctHash)]
|
|
3264
|
+
});
|
|
3265
|
+
}
|
|
3266
|
+
if (error != "") {
|
|
3267
|
+
throw new CofheError({
|
|
3268
|
+
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
3269
|
+
message: `mocks decryptForTx call failed: ${error}`
|
|
3270
|
+
});
|
|
3271
|
+
}
|
|
3272
|
+
if (allowed == false) {
|
|
3273
|
+
throw new CofheError({
|
|
3274
|
+
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
3275
|
+
message: `mocks decryptForTx call failed: ACL Access Denied (NotAllowed)`
|
|
3276
|
+
});
|
|
3277
|
+
}
|
|
3278
|
+
const packed = viem.encodePacked(["uint256", "uint256"], [BigInt(ctHash), decryptedValue]);
|
|
3279
|
+
const messageHash = viem.keccak256(packed);
|
|
3280
|
+
const signature = await accounts.sign({
|
|
3281
|
+
hash: messageHash,
|
|
3282
|
+
privateKey: MOCKS_DECRYPT_RESULT_SIGNER_PRIVATE_KEY,
|
|
3283
|
+
to: "hex"
|
|
3284
|
+
});
|
|
3285
|
+
return {
|
|
3286
|
+
ctHash,
|
|
3287
|
+
decryptedValue,
|
|
3288
|
+
signature
|
|
3289
|
+
};
|
|
3290
|
+
}
|
|
3291
|
+
function normalizeTnSignature(signature) {
|
|
3331
3292
|
if (typeof signature !== "string") {
|
|
3332
3293
|
throw new CofheError({
|
|
3333
3294
|
code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
|
|
@@ -3344,7 +3305,9 @@ function normalizeSignature(signature) {
|
|
|
3344
3305
|
message: "decrypt response returned empty signature"
|
|
3345
3306
|
});
|
|
3346
3307
|
}
|
|
3347
|
-
|
|
3308
|
+
const prefixed = trimmed.startsWith("0x") ? trimmed : `0x${trimmed}`;
|
|
3309
|
+
const parsed = viem.parseSignature(prefixed);
|
|
3310
|
+
return viem.serializeSignature(parsed);
|
|
3348
3311
|
}
|
|
3349
3312
|
function parseDecryptedBytesToBigInt(decrypted) {
|
|
3350
3313
|
if (!Array.isArray(decrypted)) {
|
|
@@ -3381,59 +3344,79 @@ function parseDecryptedBytesToBigInt(decrypted) {
|
|
|
3381
3344
|
}
|
|
3382
3345
|
return BigInt(`0x${hex}`);
|
|
3383
3346
|
}
|
|
3384
|
-
|
|
3347
|
+
|
|
3348
|
+
// core/decrypt/tnDecryptV2.ts
|
|
3349
|
+
var POLL_INTERVAL_MS2 = 1e3;
|
|
3350
|
+
var POLL_TIMEOUT_MS2 = 5 * 60 * 1e3;
|
|
3351
|
+
function assertDecryptSubmitResponseV2(value) {
|
|
3385
3352
|
if (value == null || typeof value !== "object") {
|
|
3386
3353
|
throw new CofheError({
|
|
3387
3354
|
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
3388
|
-
message: "decrypt response must be a JSON object",
|
|
3355
|
+
message: "decrypt submit response must be a JSON object",
|
|
3389
3356
|
context: {
|
|
3390
3357
|
value
|
|
3391
3358
|
}
|
|
3392
3359
|
});
|
|
3393
3360
|
}
|
|
3394
3361
|
const v = value;
|
|
3395
|
-
|
|
3396
|
-
const signature = v.signature;
|
|
3397
|
-
const encryptionType = v.encryption_type;
|
|
3398
|
-
const errorMessage = v.error_message;
|
|
3399
|
-
if (!Array.isArray(decrypted)) {
|
|
3362
|
+
if (typeof v.request_id !== "string" || v.request_id.trim().length === 0) {
|
|
3400
3363
|
throw new CofheError({
|
|
3401
|
-
code: "
|
|
3402
|
-
message: "decrypt response missing
|
|
3403
|
-
context: {
|
|
3364
|
+
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
3365
|
+
message: "decrypt submit response missing request_id",
|
|
3366
|
+
context: {
|
|
3367
|
+
value
|
|
3368
|
+
}
|
|
3404
3369
|
});
|
|
3405
3370
|
}
|
|
3406
|
-
|
|
3371
|
+
return { request_id: v.request_id };
|
|
3372
|
+
}
|
|
3373
|
+
function assertDecryptStatusResponseV2(value) {
|
|
3374
|
+
if (value == null || typeof value !== "object") {
|
|
3407
3375
|
throw new CofheError({
|
|
3408
|
-
code: "
|
|
3409
|
-
message: "decrypt response
|
|
3410
|
-
context: {
|
|
3376
|
+
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
3377
|
+
message: "decrypt status response must be a JSON object",
|
|
3378
|
+
context: {
|
|
3379
|
+
value
|
|
3380
|
+
}
|
|
3411
3381
|
});
|
|
3412
3382
|
}
|
|
3413
|
-
|
|
3383
|
+
const v = value;
|
|
3384
|
+
const requestId = v.request_id;
|
|
3385
|
+
const status = v.status;
|
|
3386
|
+
const submittedAt = v.submitted_at;
|
|
3387
|
+
if (typeof requestId !== "string" || requestId.trim().length === 0) {
|
|
3414
3388
|
throw new CofheError({
|
|
3415
3389
|
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
3416
|
-
message: "decrypt response missing
|
|
3417
|
-
context: {
|
|
3390
|
+
message: "decrypt status response missing request_id",
|
|
3391
|
+
context: {
|
|
3392
|
+
value
|
|
3393
|
+
}
|
|
3418
3394
|
});
|
|
3419
3395
|
}
|
|
3420
|
-
if (
|
|
3396
|
+
if (status !== "PROCESSING" && status !== "COMPLETED") {
|
|
3421
3397
|
throw new CofheError({
|
|
3422
3398
|
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
3423
|
-
message: "decrypt response
|
|
3424
|
-
context: {
|
|
3399
|
+
message: "decrypt status response has invalid status",
|
|
3400
|
+
context: {
|
|
3401
|
+
value,
|
|
3402
|
+
status
|
|
3403
|
+
}
|
|
3425
3404
|
});
|
|
3426
3405
|
}
|
|
3427
|
-
|
|
3428
|
-
|
|
3429
|
-
|
|
3430
|
-
|
|
3431
|
-
|
|
3432
|
-
|
|
3406
|
+
if (typeof submittedAt !== "string" || submittedAt.trim().length === 0) {
|
|
3407
|
+
throw new CofheError({
|
|
3408
|
+
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
3409
|
+
message: "decrypt status response missing submitted_at",
|
|
3410
|
+
context: {
|
|
3411
|
+
value
|
|
3412
|
+
}
|
|
3413
|
+
});
|
|
3414
|
+
}
|
|
3415
|
+
return value;
|
|
3433
3416
|
}
|
|
3434
|
-
async function
|
|
3417
|
+
async function submitDecryptRequestV2(thresholdNetworkUrl, ctHash, chainId, permission) {
|
|
3435
3418
|
const body = {
|
|
3436
|
-
ct_tempkey: ctHash.toString(16).padStart(64, "0"),
|
|
3419
|
+
ct_tempkey: BigInt(ctHash).toString(16).padStart(64, "0"),
|
|
3437
3420
|
host_chain_id: chainId
|
|
3438
3421
|
};
|
|
3439
3422
|
if (permission) {
|
|
@@ -3441,7 +3424,7 @@ async function tnDecrypt(ctHash, chainId, permission, thresholdNetworkUrl) {
|
|
|
3441
3424
|
}
|
|
3442
3425
|
let response;
|
|
3443
3426
|
try {
|
|
3444
|
-
response = await fetch(`${thresholdNetworkUrl}/decrypt`, {
|
|
3427
|
+
response = await fetch(`${thresholdNetworkUrl}/v2/decrypt`, {
|
|
3445
3428
|
method: "POST",
|
|
3446
3429
|
headers: {
|
|
3447
3430
|
"Content-Type": "application/json"
|
|
@@ -3460,18 +3443,15 @@ async function tnDecrypt(ctHash, chainId, permission, thresholdNetworkUrl) {
|
|
|
3460
3443
|
}
|
|
3461
3444
|
});
|
|
3462
3445
|
}
|
|
3463
|
-
const responseText = await response.text();
|
|
3464
3446
|
if (!response.ok) {
|
|
3465
|
-
let errorMessage =
|
|
3447
|
+
let errorMessage = `HTTP ${response.status}`;
|
|
3466
3448
|
try {
|
|
3467
|
-
const errorBody =
|
|
3449
|
+
const errorBody = await response.json();
|
|
3468
3450
|
const maybeMessage = errorBody.error_message || errorBody.message;
|
|
3469
3451
|
if (typeof maybeMessage === "string" && maybeMessage.length > 0)
|
|
3470
3452
|
errorMessage = maybeMessage;
|
|
3471
3453
|
} catch {
|
|
3472
|
-
|
|
3473
|
-
if (trimmed.length > 0)
|
|
3474
|
-
errorMessage = trimmed;
|
|
3454
|
+
errorMessage = response.statusText || errorMessage;
|
|
3475
3455
|
}
|
|
3476
3456
|
throw new CofheError({
|
|
3477
3457
|
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
@@ -3481,41 +3461,163 @@ async function tnDecrypt(ctHash, chainId, permission, thresholdNetworkUrl) {
|
|
|
3481
3461
|
thresholdNetworkUrl,
|
|
3482
3462
|
status: response.status,
|
|
3483
3463
|
statusText: response.statusText,
|
|
3484
|
-
body
|
|
3485
|
-
responseText
|
|
3464
|
+
body
|
|
3486
3465
|
}
|
|
3487
3466
|
});
|
|
3488
3467
|
}
|
|
3489
3468
|
let rawJson;
|
|
3490
3469
|
try {
|
|
3491
|
-
rawJson =
|
|
3470
|
+
rawJson = await response.json();
|
|
3492
3471
|
} catch (e) {
|
|
3493
3472
|
throw new CofheError({
|
|
3494
3473
|
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
3495
|
-
message: `Failed to parse decrypt response`,
|
|
3474
|
+
message: `Failed to parse decrypt submit response`,
|
|
3496
3475
|
cause: e instanceof Error ? e : void 0,
|
|
3497
3476
|
context: {
|
|
3498
3477
|
thresholdNetworkUrl,
|
|
3499
|
-
body
|
|
3500
|
-
responseText
|
|
3478
|
+
body
|
|
3501
3479
|
}
|
|
3502
3480
|
});
|
|
3503
3481
|
}
|
|
3504
|
-
const
|
|
3505
|
-
|
|
3506
|
-
|
|
3507
|
-
|
|
3508
|
-
|
|
3509
|
-
|
|
3510
|
-
|
|
3511
|
-
|
|
3512
|
-
|
|
3482
|
+
const submitResponse = assertDecryptSubmitResponseV2(rawJson);
|
|
3483
|
+
return submitResponse.request_id;
|
|
3484
|
+
}
|
|
3485
|
+
async function pollDecryptStatusV2(thresholdNetworkUrl, requestId) {
|
|
3486
|
+
const startTime = Date.now();
|
|
3487
|
+
let completed = false;
|
|
3488
|
+
while (!completed) {
|
|
3489
|
+
if (Date.now() - startTime > POLL_TIMEOUT_MS2) {
|
|
3490
|
+
throw new CofheError({
|
|
3491
|
+
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
3492
|
+
message: `decrypt polling timed out after ${POLL_TIMEOUT_MS2}ms`,
|
|
3493
|
+
hint: "The request may still be processing. Try again later.",
|
|
3494
|
+
context: {
|
|
3495
|
+
thresholdNetworkUrl,
|
|
3496
|
+
requestId,
|
|
3497
|
+
timeoutMs: POLL_TIMEOUT_MS2
|
|
3498
|
+
}
|
|
3499
|
+
});
|
|
3500
|
+
}
|
|
3501
|
+
let response;
|
|
3502
|
+
try {
|
|
3503
|
+
response = await fetch(`${thresholdNetworkUrl}/v2/decrypt/${requestId}`, {
|
|
3504
|
+
method: "GET",
|
|
3505
|
+
headers: {
|
|
3506
|
+
"Content-Type": "application/json"
|
|
3507
|
+
}
|
|
3508
|
+
});
|
|
3509
|
+
} catch (e) {
|
|
3510
|
+
throw new CofheError({
|
|
3511
|
+
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
3512
|
+
message: `decrypt status poll failed`,
|
|
3513
|
+
hint: "Ensure the threshold network URL is valid and reachable.",
|
|
3514
|
+
cause: e instanceof Error ? e : void 0,
|
|
3515
|
+
context: {
|
|
3516
|
+
thresholdNetworkUrl,
|
|
3517
|
+
requestId
|
|
3518
|
+
}
|
|
3519
|
+
});
|
|
3520
|
+
}
|
|
3521
|
+
if (response.status === 404) {
|
|
3522
|
+
throw new CofheError({
|
|
3523
|
+
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
3524
|
+
message: `decrypt request not found: ${requestId}`,
|
|
3525
|
+
hint: "The request may have expired or been invalid.",
|
|
3526
|
+
context: {
|
|
3527
|
+
thresholdNetworkUrl,
|
|
3528
|
+
requestId
|
|
3529
|
+
}
|
|
3530
|
+
});
|
|
3531
|
+
}
|
|
3532
|
+
if (!response.ok) {
|
|
3533
|
+
let errorMessage = `HTTP ${response.status}`;
|
|
3534
|
+
try {
|
|
3535
|
+
const errorBody = await response.json();
|
|
3536
|
+
const maybeMessage = errorBody.error_message || errorBody.message;
|
|
3537
|
+
if (typeof maybeMessage === "string" && maybeMessage.length > 0)
|
|
3538
|
+
errorMessage = maybeMessage;
|
|
3539
|
+
} catch {
|
|
3540
|
+
errorMessage = response.statusText || errorMessage;
|
|
3513
3541
|
}
|
|
3514
|
-
|
|
3542
|
+
throw new CofheError({
|
|
3543
|
+
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
3544
|
+
message: `decrypt status poll failed: ${errorMessage}`,
|
|
3545
|
+
context: {
|
|
3546
|
+
thresholdNetworkUrl,
|
|
3547
|
+
requestId,
|
|
3548
|
+
status: response.status,
|
|
3549
|
+
statusText: response.statusText
|
|
3550
|
+
}
|
|
3551
|
+
});
|
|
3552
|
+
}
|
|
3553
|
+
let rawJson;
|
|
3554
|
+
try {
|
|
3555
|
+
rawJson = await response.json();
|
|
3556
|
+
} catch (e) {
|
|
3557
|
+
throw new CofheError({
|
|
3558
|
+
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
3559
|
+
message: `Failed to parse decrypt status response`,
|
|
3560
|
+
cause: e instanceof Error ? e : void 0,
|
|
3561
|
+
context: {
|
|
3562
|
+
thresholdNetworkUrl,
|
|
3563
|
+
requestId
|
|
3564
|
+
}
|
|
3565
|
+
});
|
|
3566
|
+
}
|
|
3567
|
+
const statusResponse = assertDecryptStatusResponseV2(rawJson);
|
|
3568
|
+
if (statusResponse.status === "COMPLETED") {
|
|
3569
|
+
if (statusResponse.is_succeed === false) {
|
|
3570
|
+
const errorMessage = statusResponse.error_message || "Unknown error";
|
|
3571
|
+
throw new CofheError({
|
|
3572
|
+
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
3573
|
+
message: `decrypt request failed: ${errorMessage}`,
|
|
3574
|
+
context: {
|
|
3575
|
+
thresholdNetworkUrl,
|
|
3576
|
+
requestId,
|
|
3577
|
+
statusResponse
|
|
3578
|
+
}
|
|
3579
|
+
});
|
|
3580
|
+
}
|
|
3581
|
+
if (statusResponse.error_message) {
|
|
3582
|
+
throw new CofheError({
|
|
3583
|
+
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
3584
|
+
message: `decrypt request failed: ${statusResponse.error_message}`,
|
|
3585
|
+
context: {
|
|
3586
|
+
thresholdNetworkUrl,
|
|
3587
|
+
requestId,
|
|
3588
|
+
statusResponse
|
|
3589
|
+
}
|
|
3590
|
+
});
|
|
3591
|
+
}
|
|
3592
|
+
if (!Array.isArray(statusResponse.decrypted)) {
|
|
3593
|
+
throw new CofheError({
|
|
3594
|
+
code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
|
|
3595
|
+
message: "decrypt completed but response missing <decrypted> byte array",
|
|
3596
|
+
context: {
|
|
3597
|
+
thresholdNetworkUrl,
|
|
3598
|
+
requestId,
|
|
3599
|
+
statusResponse
|
|
3600
|
+
}
|
|
3601
|
+
});
|
|
3602
|
+
}
|
|
3603
|
+
const decryptedValue = parseDecryptedBytesToBigInt(statusResponse.decrypted);
|
|
3604
|
+
const signature = normalizeTnSignature(statusResponse.signature);
|
|
3605
|
+
return { decryptedValue, signature };
|
|
3606
|
+
}
|
|
3607
|
+
await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS2));
|
|
3515
3608
|
}
|
|
3516
|
-
|
|
3517
|
-
|
|
3518
|
-
|
|
3609
|
+
throw new CofheError({
|
|
3610
|
+
code: "DECRYPT_FAILED" /* DecryptFailed */,
|
|
3611
|
+
message: "Polling loop exited unexpectedly",
|
|
3612
|
+
context: {
|
|
3613
|
+
thresholdNetworkUrl,
|
|
3614
|
+
requestId
|
|
3615
|
+
}
|
|
3616
|
+
});
|
|
3617
|
+
}
|
|
3618
|
+
async function tnDecryptV2(ctHash, chainId, permission, thresholdNetworkUrl) {
|
|
3619
|
+
const requestId = await submitDecryptRequestV2(thresholdNetworkUrl, ctHash, chainId, permission);
|
|
3620
|
+
return await pollDecryptStatusV2(thresholdNetworkUrl, requestId);
|
|
3519
3621
|
}
|
|
3520
3622
|
|
|
3521
3623
|
// core/decrypt/decryptForTxBuilder.ts
|
|
@@ -3663,7 +3765,9 @@ var DecryptForTxBuilder = class extends BaseBuilder {
|
|
|
3663
3765
|
async mocksDecryptForTx(permit) {
|
|
3664
3766
|
this.assertPublicClient();
|
|
3665
3767
|
const delay = this.config.mocks.decryptDelay;
|
|
3666
|
-
|
|
3768
|
+
if (delay > 0)
|
|
3769
|
+
await sleep(delay);
|
|
3770
|
+
const result = await cofheMocksDecryptForTx(this.ctHash, 0, permit, this.publicClient);
|
|
3667
3771
|
return result;
|
|
3668
3772
|
}
|
|
3669
3773
|
/**
|
|
@@ -3674,7 +3778,7 @@ var DecryptForTxBuilder = class extends BaseBuilder {
|
|
|
3674
3778
|
this.assertPublicClient();
|
|
3675
3779
|
const thresholdNetworkUrl = await this.getThresholdNetworkUrl();
|
|
3676
3780
|
const permission = permit ? PermitUtils.getPermission(permit, true) : null;
|
|
3677
|
-
const { decryptedValue, signature } = await
|
|
3781
|
+
const { decryptedValue, signature } = await tnDecryptV2(this.ctHash, this.chainId, permission, thresholdNetworkUrl);
|
|
3678
3782
|
return {
|
|
3679
3783
|
ctHash: this.ctHash,
|
|
3680
3784
|
decryptedValue,
|
|
@@ -3882,19 +3986,19 @@ function createCofheClientBase(opts) {
|
|
|
3882
3986
|
return permits.getOrCreateSharingPermit(publicClient, walletClient, options, _chainId, _account);
|
|
3883
3987
|
},
|
|
3884
3988
|
// Retrieval methods (auto-fill chainId/account)
|
|
3885
|
-
getPermit:
|
|
3989
|
+
getPermit: (hash, chainId, account) => {
|
|
3886
3990
|
const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
|
|
3887
3991
|
return permits.getPermit(_chainId, _account, hash);
|
|
3888
3992
|
},
|
|
3889
|
-
getPermits:
|
|
3993
|
+
getPermits: (chainId, account) => {
|
|
3890
3994
|
const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
|
|
3891
3995
|
return permits.getPermits(_chainId, _account);
|
|
3892
3996
|
},
|
|
3893
|
-
getActivePermit:
|
|
3997
|
+
getActivePermit: (chainId, account) => {
|
|
3894
3998
|
const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
|
|
3895
3999
|
return permits.getActivePermit(_chainId, _account);
|
|
3896
4000
|
},
|
|
3897
|
-
getActivePermitHash:
|
|
4001
|
+
getActivePermitHash: (chainId, account) => {
|
|
3898
4002
|
const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
|
|
3899
4003
|
return permits.getActivePermitHash(_chainId, _account);
|
|
3900
4004
|
},
|
package/dist/web.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { C as CofheInputConfig, a as CofheConfig, b as CofheClient, E as EncryptableItem } from './clientTypes-
|
|
1
|
+
import { C as CofheInputConfig, a as CofheConfig, b as CofheClient, E as EncryptableItem } from './clientTypes-ACVWbrXL.cjs';
|
|
2
2
|
import 'viem';
|
|
3
3
|
import './types-YiAC4gig.cjs';
|
|
4
4
|
import 'zod';
|
package/dist/web.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { C as CofheInputConfig, a as CofheConfig, b as CofheClient, E as EncryptableItem } from './clientTypes-
|
|
1
|
+
import { C as CofheInputConfig, a as CofheConfig, b as CofheClient, E as EncryptableItem } from './clientTypes-kkrRdawm.js';
|
|
2
2
|
import 'viem';
|
|
3
3
|
import './types-YiAC4gig.js';
|
|
4
4
|
import 'zod';
|
package/dist/web.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createCofheConfigBase, createCofheClientBase, fheTypeToString } from './chunk-
|
|
1
|
+
import { createCofheConfigBase, createCofheClientBase, fheTypeToString } from './chunk-MXND5SVN.js';
|
|
2
2
|
import './chunk-TBLR7NNE.js';
|
|
3
3
|
import './chunk-NWDKXBIP.js';
|
|
4
4
|
import { constructClient } from 'iframe-shared-storage';
|
package/node/client.test.ts
CHANGED
|
@@ -136,7 +136,7 @@ describe('@cofhe/node - Client Integration Tests', () => {
|
|
|
136
136
|
it('should create decrypt builder after connection', async () => {
|
|
137
137
|
await cofheClient.connect(publicClient, walletClient);
|
|
138
138
|
|
|
139
|
-
const builder = cofheClient.decryptForView(
|
|
139
|
+
const builder = cofheClient.decryptForView('0x123', 2);
|
|
140
140
|
|
|
141
141
|
expect(builder).toBeDefined();
|
|
142
142
|
expect(typeof builder.setChainId).toBe('function');
|
package/package.json
CHANGED
package/web/client.web.test.ts
CHANGED
|
@@ -136,7 +136,7 @@ describe('@cofhe/web - Client', () => {
|
|
|
136
136
|
it('should create decrypt builder after connection', async () => {
|
|
137
137
|
await cofheClient.connect(publicClient, walletClient);
|
|
138
138
|
|
|
139
|
-
const builder = cofheClient.decryptForView(
|
|
139
|
+
const builder = cofheClient.decryptForView('0x123', 2);
|
|
140
140
|
|
|
141
141
|
expect(builder).toBeDefined();
|
|
142
142
|
expect(typeof builder.setChainId).toBe('function');
|