@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/dist/node.cjs CHANGED
@@ -613,7 +613,7 @@ async function insertCtHashes(items, walletClient) {
613
613
  });
614
614
  }
615
615
  }
616
- async function createProofSignatures(items, securityZone) {
616
+ async function createProofSignatures(items, securityZone, account) {
617
617
  let signatures = [];
618
618
  let encInputSignerClient;
619
619
  try {
@@ -630,12 +630,15 @@ async function createProofSignatures(items, securityZone) {
630
630
  }
631
631
  try {
632
632
  for (const item of items) {
633
- const packedData = viem.encodePacked(["uint256", "int32", "uint8"], [BigInt(item.data), securityZone, item.utype]);
633
+ const packedData = viem.encodePacked(
634
+ ["uint256", "uint8", "uint8", "address", "uint256"],
635
+ [BigInt(item.ctHash), item.utype, securityZone, account, BigInt(chains.hardhat.id)]
636
+ );
634
637
  const messageHash = viem.keccak256(packedData);
635
- const ethSignedHash = viem.hashMessage({ raw: viem.toBytes(messageHash) });
636
- const signature = await encInputSignerClient.signMessage({
637
- message: { raw: viem.toBytes(ethSignedHash) },
638
- account: encInputSignerClient.account
638
+ const signature = await accounts.sign({
639
+ hash: messageHash,
640
+ privateKey: MOCKS_ZK_VERIFIER_SIGNER_PRIVATE_KEY,
641
+ to: "hex"
639
642
  });
640
643
  signatures.push(signature);
641
644
  }
@@ -666,7 +669,7 @@ async function cofheMocksZkVerifySign(items, account, securityZone, publicClient
666
669
  const _walletClient = zkvWalletClient ?? createMockZkVerifierSigner();
667
670
  const encryptableItems = await calcCtHashes(items, account, securityZone, publicClient);
668
671
  await insertCtHashes(encryptableItems, _walletClient);
669
- const signatures = await createProofSignatures(encryptableItems, securityZone);
672
+ const signatures = await createProofSignatures(encryptableItems, securityZone, account);
670
673
  return encryptableItems.map((item, index) => ({
671
674
  ct_hash: item.ctHash.toString(),
672
675
  signature: signatures[index]
@@ -2471,13 +2474,13 @@ var serialize = (permit) => {
2471
2474
  var deserialize = (serialized) => {
2472
2475
  return PermitUtils.deserialize(serialized);
2473
2476
  };
2474
- var getPermit2 = async (chainId, account, hash) => {
2477
+ var getPermit2 = (chainId, account, hash) => {
2475
2478
  return permitStore.getPermit(chainId, account, hash);
2476
2479
  };
2477
- var getPermits2 = async (chainId, account) => {
2480
+ var getPermits2 = (chainId, account) => {
2478
2481
  return permitStore.getPermits(chainId, account);
2479
2482
  };
2480
- var getActivePermit2 = async (chainId, account) => {
2483
+ var getActivePermit2 = (chainId, account) => {
2481
2484
  return permitStore.getActivePermit(chainId, account);
2482
2485
  };
2483
2486
  var getActivePermitHash2 = (chainId, account) => {
@@ -2726,9 +2729,7 @@ var MockThresholdNetworkAbi = [
2726
2729
  ];
2727
2730
 
2728
2731
  // core/decrypt/cofheMocksDecryptForView.ts
2729
- async function cofheMocksDecryptForView(ctHash, utype, permit, publicClient, mocksDecryptDelay) {
2730
- if (mocksDecryptDelay > 0)
2731
- await sleep(mocksDecryptDelay);
2732
+ async function cofheMocksDecryptForView(ctHash, utype, permit, publicClient) {
2732
2733
  const permission = PermitUtils.getPermission(permit, true);
2733
2734
  const permissionWithBigInts = {
2734
2735
  ...permission,
@@ -2739,7 +2740,7 @@ async function cofheMocksDecryptForView(ctHash, utype, permit, publicClient, moc
2739
2740
  address: MOCKS_THRESHOLD_NETWORK_ADDRESS,
2740
2741
  abi: MockThresholdNetworkAbi,
2741
2742
  functionName: "querySealOutput",
2742
- args: [ctHash, BigInt(utype), permissionWithBigInts]
2743
+ args: [BigInt(ctHash), BigInt(utype), permissionWithBigInts]
2743
2744
  });
2744
2745
  if (error != "") {
2745
2746
  throw new CofheError({
@@ -2780,7 +2781,7 @@ function convertSealedData(sealed) {
2780
2781
  }
2781
2782
  async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, permission) {
2782
2783
  const body = {
2783
- ct_tempkey: ctHash.toString(16).padStart(64, "0"),
2784
+ ct_tempkey: BigInt(ctHash).toString(16).padStart(64, "0"),
2784
2785
  host_chain_id: chainId,
2785
2786
  permit: permission
2786
2787
  };
@@ -2973,96 +2974,6 @@ async function tnSealOutputV2(ctHash, chainId, permission, thresholdNetworkUrl)
2973
2974
  const requestId = await submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, permission);
2974
2975
  return await pollSealOutputStatus(thresholdNetworkUrl, requestId);
2975
2976
  }
2976
- async function cofheMocksDecryptForTx(ctHash, utype, permit, publicClient, mocksDecryptForTxDelay) {
2977
- if (mocksDecryptForTxDelay > 0)
2978
- await sleep(mocksDecryptForTxDelay);
2979
- if (permit !== null) {
2980
- let permission = PermitUtils.getPermission(permit, true);
2981
- const permissionWithBigInts = {
2982
- ...permission,
2983
- expiration: BigInt(permission.expiration),
2984
- validatorId: BigInt(permission.validatorId)
2985
- };
2986
- const [allowed2, error2, result2] = await publicClient.readContract({
2987
- address: MOCKS_THRESHOLD_NETWORK_ADDRESS,
2988
- abi: MockThresholdNetworkAbi,
2989
- functionName: "decryptForTxWithPermit",
2990
- args: [ctHash, permissionWithBigInts]
2991
- });
2992
- if (error2 != "") {
2993
- throw new CofheError({
2994
- code: "DECRYPT_FAILED" /* DecryptFailed */,
2995
- message: `mocks decryptForTx call failed: ${error2}`
2996
- });
2997
- }
2998
- if (allowed2 == false) {
2999
- throw new CofheError({
3000
- code: "DECRYPT_FAILED" /* DecryptFailed */,
3001
- message: `mocks decryptForTx call failed: ACL Access Denied (NotAllowed)`
3002
- });
3003
- }
3004
- const chainId2 = await publicClient.getChainId();
3005
- const ctHashBigInt2 = BigInt(ctHash);
3006
- const resultBigInt2 = BigInt(result2);
3007
- const encryptionType2 = Number((ctHashBigInt2 & 0x7fn << 8n) >> 8n);
3008
- const ctHashBytes322 = viem.pad(viem.toHex(ctHashBigInt2), { size: 32 });
3009
- const packed2 = viem.encodePacked(
3010
- ["uint256", "uint32", "uint64", "bytes32"],
3011
- [resultBigInt2, encryptionType2, BigInt(chainId2), ctHashBytes322]
3012
- );
3013
- const messageHash2 = viem.keccak256(packed2);
3014
- const signatureHex2 = await accounts.sign({
3015
- hash: messageHash2,
3016
- privateKey: MOCKS_DECRYPT_RESULT_SIGNER_PRIVATE_KEY,
3017
- to: "hex"
3018
- });
3019
- const signature2 = signatureHex2.slice(2);
3020
- return {
3021
- ctHash,
3022
- decryptedValue: BigInt(result2),
3023
- signature: signature2
3024
- };
3025
- }
3026
- const [allowed, error, result] = await publicClient.readContract({
3027
- address: MOCKS_THRESHOLD_NETWORK_ADDRESS,
3028
- abi: MockThresholdNetworkAbi,
3029
- functionName: "decryptForTxWithoutPermit",
3030
- args: [ctHash]
3031
- });
3032
- if (error != "") {
3033
- throw new CofheError({
3034
- code: "DECRYPT_FAILED" /* DecryptFailed */,
3035
- message: `mocks decryptForTx call failed: ${error}`
3036
- });
3037
- }
3038
- if (allowed == false) {
3039
- throw new CofheError({
3040
- code: "DECRYPT_FAILED" /* DecryptFailed */,
3041
- message: `mocks decryptForTx call failed: ACL Access Denied (NotAllowed)`
3042
- });
3043
- }
3044
- const chainId = await publicClient.getChainId();
3045
- const ctHashBigInt = BigInt(ctHash);
3046
- const resultBigInt = BigInt(result);
3047
- const encryptionType = Number((ctHashBigInt & 0x7fn << 8n) >> 8n);
3048
- const ctHashBytes32 = viem.pad(viem.toHex(ctHashBigInt), { size: 32 });
3049
- const packed = viem.encodePacked(
3050
- ["uint256", "uint32", "uint64", "bytes32"],
3051
- [resultBigInt, encryptionType, BigInt(chainId), ctHashBytes32]
3052
- );
3053
- const messageHash = viem.keccak256(packed);
3054
- const signatureHex = await accounts.sign({
3055
- hash: messageHash,
3056
- privateKey: MOCKS_DECRYPT_RESULT_SIGNER_PRIVATE_KEY,
3057
- to: "hex"
3058
- });
3059
- const signature = signatureHex.slice(2);
3060
- return {
3061
- ctHash,
3062
- decryptedValue: BigInt(result),
3063
- signature
3064
- };
3065
- }
3066
2977
 
3067
2978
  // core/decrypt/decryptForViewBuilder.ts
3068
2979
  var DecryptForViewBuilder = class extends BaseBuilder {
@@ -3237,7 +3148,9 @@ var DecryptForViewBuilder = class extends BaseBuilder {
3237
3148
  async mocksSealOutput(permit) {
3238
3149
  this.assertPublicClient();
3239
3150
  const mocksDecryptDelay = this.config.mocks.decryptDelay;
3240
- return cofheMocksDecryptForView(this.ctHash, this.utype, permit, this.publicClient, mocksDecryptDelay);
3151
+ if (mocksDecryptDelay > 0)
3152
+ await sleep(mocksDecryptDelay);
3153
+ return cofheMocksDecryptForView(this.ctHash, this.utype, permit, this.publicClient);
3241
3154
  }
3242
3155
  /**
3243
3156
  * In the production context, perform a true decryption with the CoFHE coprocessor.
@@ -3286,9 +3199,57 @@ var DecryptForViewBuilder = class extends BaseBuilder {
3286
3199
  return convertViaUtype(this.utype, unsealed);
3287
3200
  }
3288
3201
  };
3289
-
3290
- // core/decrypt/tnDecrypt.ts
3291
- function normalizeSignature(signature) {
3202
+ async function cofheMocksDecryptForTx(ctHash, utype, permit, publicClient) {
3203
+ let allowed;
3204
+ let error;
3205
+ let decryptedValue;
3206
+ if (permit !== null) {
3207
+ let permission = PermitUtils.getPermission(permit, true);
3208
+ const permissionWithBigInts = {
3209
+ ...permission,
3210
+ expiration: BigInt(permission.expiration),
3211
+ validatorId: BigInt(permission.validatorId)
3212
+ };
3213
+ [allowed, error, decryptedValue] = await publicClient.readContract({
3214
+ address: MOCKS_THRESHOLD_NETWORK_ADDRESS,
3215
+ abi: MockThresholdNetworkAbi,
3216
+ functionName: "decryptForTxWithPermit",
3217
+ args: [BigInt(ctHash), permissionWithBigInts]
3218
+ });
3219
+ } else {
3220
+ [allowed, error, decryptedValue] = await publicClient.readContract({
3221
+ address: MOCKS_THRESHOLD_NETWORK_ADDRESS,
3222
+ abi: MockThresholdNetworkAbi,
3223
+ functionName: "decryptForTxWithoutPermit",
3224
+ args: [BigInt(ctHash)]
3225
+ });
3226
+ }
3227
+ if (error != "") {
3228
+ throw new CofheError({
3229
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
3230
+ message: `mocks decryptForTx call failed: ${error}`
3231
+ });
3232
+ }
3233
+ if (allowed == false) {
3234
+ throw new CofheError({
3235
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
3236
+ message: `mocks decryptForTx call failed: ACL Access Denied (NotAllowed)`
3237
+ });
3238
+ }
3239
+ const packed = viem.encodePacked(["uint256", "uint256"], [BigInt(ctHash), decryptedValue]);
3240
+ const messageHash = viem.keccak256(packed);
3241
+ const signature = await accounts.sign({
3242
+ hash: messageHash,
3243
+ privateKey: MOCKS_DECRYPT_RESULT_SIGNER_PRIVATE_KEY,
3244
+ to: "hex"
3245
+ });
3246
+ return {
3247
+ ctHash,
3248
+ decryptedValue,
3249
+ signature
3250
+ };
3251
+ }
3252
+ function normalizeTnSignature(signature) {
3292
3253
  if (typeof signature !== "string") {
3293
3254
  throw new CofheError({
3294
3255
  code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
@@ -3305,7 +3266,9 @@ function normalizeSignature(signature) {
3305
3266
  message: "decrypt response returned empty signature"
3306
3267
  });
3307
3268
  }
3308
- return trimmed.startsWith("0x") ? trimmed.slice(2) : trimmed;
3269
+ const prefixed = trimmed.startsWith("0x") ? trimmed : `0x${trimmed}`;
3270
+ const parsed = viem.parseSignature(prefixed);
3271
+ return viem.serializeSignature(parsed);
3309
3272
  }
3310
3273
  function parseDecryptedBytesToBigInt(decrypted) {
3311
3274
  if (!Array.isArray(decrypted)) {
@@ -3342,59 +3305,79 @@ function parseDecryptedBytesToBigInt(decrypted) {
3342
3305
  }
3343
3306
  return BigInt(`0x${hex}`);
3344
3307
  }
3345
- function assertTnDecryptResponse(value) {
3308
+
3309
+ // core/decrypt/tnDecryptV2.ts
3310
+ var POLL_INTERVAL_MS2 = 1e3;
3311
+ var POLL_TIMEOUT_MS2 = 5 * 60 * 1e3;
3312
+ function assertDecryptSubmitResponseV2(value) {
3346
3313
  if (value == null || typeof value !== "object") {
3347
3314
  throw new CofheError({
3348
3315
  code: "DECRYPT_FAILED" /* DecryptFailed */,
3349
- message: "decrypt response must be a JSON object",
3316
+ message: "decrypt submit response must be a JSON object",
3350
3317
  context: {
3351
3318
  value
3352
3319
  }
3353
3320
  });
3354
3321
  }
3355
3322
  const v = value;
3356
- const decrypted = v.decrypted;
3357
- const signature = v.signature;
3358
- const encryptionType = v.encryption_type;
3359
- const errorMessage = v.error_message;
3360
- if (!Array.isArray(decrypted)) {
3323
+ if (typeof v.request_id !== "string" || v.request_id.trim().length === 0) {
3361
3324
  throw new CofheError({
3362
- code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
3363
- message: "decrypt response missing <decrypted> byte array",
3364
- context: { decryptResponse: value }
3325
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
3326
+ message: "decrypt submit response missing request_id",
3327
+ context: {
3328
+ value
3329
+ }
3365
3330
  });
3366
3331
  }
3367
- if (typeof signature !== "string") {
3332
+ return { request_id: v.request_id };
3333
+ }
3334
+ function assertDecryptStatusResponseV2(value) {
3335
+ if (value == null || typeof value !== "object") {
3368
3336
  throw new CofheError({
3369
- code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
3370
- message: "decrypt response missing <signature> string",
3371
- context: { decryptResponse: value }
3337
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
3338
+ message: "decrypt status response must be a JSON object",
3339
+ context: {
3340
+ value
3341
+ }
3372
3342
  });
3373
3343
  }
3374
- if (typeof encryptionType !== "number") {
3344
+ const v = value;
3345
+ const requestId = v.request_id;
3346
+ const status = v.status;
3347
+ const submittedAt = v.submitted_at;
3348
+ if (typeof requestId !== "string" || requestId.trim().length === 0) {
3375
3349
  throw new CofheError({
3376
3350
  code: "DECRYPT_FAILED" /* DecryptFailed */,
3377
- message: "decrypt response missing <encryption_type> number",
3378
- context: { decryptResponse: value }
3351
+ message: "decrypt status response missing request_id",
3352
+ context: {
3353
+ value
3354
+ }
3379
3355
  });
3380
3356
  }
3381
- if (!(typeof errorMessage === "string" || errorMessage === null)) {
3357
+ if (status !== "PROCESSING" && status !== "COMPLETED") {
3382
3358
  throw new CofheError({
3383
3359
  code: "DECRYPT_FAILED" /* DecryptFailed */,
3384
- message: "decrypt response field <error_message> must be string or null",
3385
- context: { decryptResponse: value }
3360
+ message: "decrypt status response has invalid status",
3361
+ context: {
3362
+ value,
3363
+ status
3364
+ }
3386
3365
  });
3387
3366
  }
3388
- return {
3389
- decrypted,
3390
- signature,
3391
- encryption_type: encryptionType,
3392
- error_message: errorMessage
3393
- };
3367
+ if (typeof submittedAt !== "string" || submittedAt.trim().length === 0) {
3368
+ throw new CofheError({
3369
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
3370
+ message: "decrypt status response missing submitted_at",
3371
+ context: {
3372
+ value
3373
+ }
3374
+ });
3375
+ }
3376
+ return value;
3394
3377
  }
3395
- async function tnDecrypt(ctHash, chainId, permission, thresholdNetworkUrl) {
3378
+ async function submitDecryptRequestV2(thresholdNetworkUrl, ctHash, chainId, permission) {
3396
3379
  const body = {
3397
- ct_tempkey: ctHash.toString(16).padStart(64, "0"),
3380
+ ct_tempkey: BigInt(ctHash).toString(16).padStart(64, "0"),
3398
3381
  host_chain_id: chainId
3399
3382
  };
3400
3383
  if (permission) {
@@ -3402,7 +3385,7 @@ async function tnDecrypt(ctHash, chainId, permission, thresholdNetworkUrl) {
3402
3385
  }
3403
3386
  let response;
3404
3387
  try {
3405
- response = await fetch(`${thresholdNetworkUrl}/decrypt`, {
3388
+ response = await fetch(`${thresholdNetworkUrl}/v2/decrypt`, {
3406
3389
  method: "POST",
3407
3390
  headers: {
3408
3391
  "Content-Type": "application/json"
@@ -3421,18 +3404,15 @@ async function tnDecrypt(ctHash, chainId, permission, thresholdNetworkUrl) {
3421
3404
  }
3422
3405
  });
3423
3406
  }
3424
- const responseText = await response.text();
3425
3407
  if (!response.ok) {
3426
- let errorMessage = response.statusText || `HTTP ${response.status}`;
3408
+ let errorMessage = `HTTP ${response.status}`;
3427
3409
  try {
3428
- const errorBody = JSON.parse(responseText);
3410
+ const errorBody = await response.json();
3429
3411
  const maybeMessage = errorBody.error_message || errorBody.message;
3430
3412
  if (typeof maybeMessage === "string" && maybeMessage.length > 0)
3431
3413
  errorMessage = maybeMessage;
3432
3414
  } catch {
3433
- const trimmed = responseText.trim();
3434
- if (trimmed.length > 0)
3435
- errorMessage = trimmed;
3415
+ errorMessage = response.statusText || errorMessage;
3436
3416
  }
3437
3417
  throw new CofheError({
3438
3418
  code: "DECRYPT_FAILED" /* DecryptFailed */,
@@ -3442,41 +3422,163 @@ async function tnDecrypt(ctHash, chainId, permission, thresholdNetworkUrl) {
3442
3422
  thresholdNetworkUrl,
3443
3423
  status: response.status,
3444
3424
  statusText: response.statusText,
3445
- body,
3446
- responseText
3425
+ body
3447
3426
  }
3448
3427
  });
3449
3428
  }
3450
3429
  let rawJson;
3451
3430
  try {
3452
- rawJson = JSON.parse(responseText);
3431
+ rawJson = await response.json();
3453
3432
  } catch (e) {
3454
3433
  throw new CofheError({
3455
3434
  code: "DECRYPT_FAILED" /* DecryptFailed */,
3456
- message: `Failed to parse decrypt response`,
3435
+ message: `Failed to parse decrypt submit response`,
3457
3436
  cause: e instanceof Error ? e : void 0,
3458
3437
  context: {
3459
3438
  thresholdNetworkUrl,
3460
- body,
3461
- responseText
3439
+ body
3462
3440
  }
3463
3441
  });
3464
3442
  }
3465
- const decryptResponse = assertTnDecryptResponse(rawJson);
3466
- if (decryptResponse.error_message) {
3467
- throw new CofheError({
3468
- code: "DECRYPT_FAILED" /* DecryptFailed */,
3469
- message: `decrypt request failed: ${decryptResponse.error_message}`,
3470
- context: {
3471
- thresholdNetworkUrl,
3472
- body,
3473
- decryptResponse
3443
+ const submitResponse = assertDecryptSubmitResponseV2(rawJson);
3444
+ return submitResponse.request_id;
3445
+ }
3446
+ async function pollDecryptStatusV2(thresholdNetworkUrl, requestId) {
3447
+ const startTime = Date.now();
3448
+ let completed = false;
3449
+ while (!completed) {
3450
+ if (Date.now() - startTime > POLL_TIMEOUT_MS2) {
3451
+ throw new CofheError({
3452
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
3453
+ message: `decrypt polling timed out after ${POLL_TIMEOUT_MS2}ms`,
3454
+ hint: "The request may still be processing. Try again later.",
3455
+ context: {
3456
+ thresholdNetworkUrl,
3457
+ requestId,
3458
+ timeoutMs: POLL_TIMEOUT_MS2
3459
+ }
3460
+ });
3461
+ }
3462
+ let response;
3463
+ try {
3464
+ response = await fetch(`${thresholdNetworkUrl}/v2/decrypt/${requestId}`, {
3465
+ method: "GET",
3466
+ headers: {
3467
+ "Content-Type": "application/json"
3468
+ }
3469
+ });
3470
+ } catch (e) {
3471
+ throw new CofheError({
3472
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
3473
+ message: `decrypt status poll failed`,
3474
+ hint: "Ensure the threshold network URL is valid and reachable.",
3475
+ cause: e instanceof Error ? e : void 0,
3476
+ context: {
3477
+ thresholdNetworkUrl,
3478
+ requestId
3479
+ }
3480
+ });
3481
+ }
3482
+ if (response.status === 404) {
3483
+ throw new CofheError({
3484
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
3485
+ message: `decrypt request not found: ${requestId}`,
3486
+ hint: "The request may have expired or been invalid.",
3487
+ context: {
3488
+ thresholdNetworkUrl,
3489
+ requestId
3490
+ }
3491
+ });
3492
+ }
3493
+ if (!response.ok) {
3494
+ let errorMessage = `HTTP ${response.status}`;
3495
+ try {
3496
+ const errorBody = await response.json();
3497
+ const maybeMessage = errorBody.error_message || errorBody.message;
3498
+ if (typeof maybeMessage === "string" && maybeMessage.length > 0)
3499
+ errorMessage = maybeMessage;
3500
+ } catch {
3501
+ errorMessage = response.statusText || errorMessage;
3474
3502
  }
3475
- });
3503
+ throw new CofheError({
3504
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
3505
+ message: `decrypt status poll failed: ${errorMessage}`,
3506
+ context: {
3507
+ thresholdNetworkUrl,
3508
+ requestId,
3509
+ status: response.status,
3510
+ statusText: response.statusText
3511
+ }
3512
+ });
3513
+ }
3514
+ let rawJson;
3515
+ try {
3516
+ rawJson = await response.json();
3517
+ } catch (e) {
3518
+ throw new CofheError({
3519
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
3520
+ message: `Failed to parse decrypt status response`,
3521
+ cause: e instanceof Error ? e : void 0,
3522
+ context: {
3523
+ thresholdNetworkUrl,
3524
+ requestId
3525
+ }
3526
+ });
3527
+ }
3528
+ const statusResponse = assertDecryptStatusResponseV2(rawJson);
3529
+ if (statusResponse.status === "COMPLETED") {
3530
+ if (statusResponse.is_succeed === false) {
3531
+ const errorMessage = statusResponse.error_message || "Unknown error";
3532
+ throw new CofheError({
3533
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
3534
+ message: `decrypt request failed: ${errorMessage}`,
3535
+ context: {
3536
+ thresholdNetworkUrl,
3537
+ requestId,
3538
+ statusResponse
3539
+ }
3540
+ });
3541
+ }
3542
+ if (statusResponse.error_message) {
3543
+ throw new CofheError({
3544
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
3545
+ message: `decrypt request failed: ${statusResponse.error_message}`,
3546
+ context: {
3547
+ thresholdNetworkUrl,
3548
+ requestId,
3549
+ statusResponse
3550
+ }
3551
+ });
3552
+ }
3553
+ if (!Array.isArray(statusResponse.decrypted)) {
3554
+ throw new CofheError({
3555
+ code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
3556
+ message: "decrypt completed but response missing <decrypted> byte array",
3557
+ context: {
3558
+ thresholdNetworkUrl,
3559
+ requestId,
3560
+ statusResponse
3561
+ }
3562
+ });
3563
+ }
3564
+ const decryptedValue = parseDecryptedBytesToBigInt(statusResponse.decrypted);
3565
+ const signature = normalizeTnSignature(statusResponse.signature);
3566
+ return { decryptedValue, signature };
3567
+ }
3568
+ await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS2));
3476
3569
  }
3477
- const decryptedValue = parseDecryptedBytesToBigInt(decryptResponse.decrypted);
3478
- const signature = normalizeSignature(decryptResponse.signature);
3479
- return { decryptedValue, signature };
3570
+ throw new CofheError({
3571
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
3572
+ message: "Polling loop exited unexpectedly",
3573
+ context: {
3574
+ thresholdNetworkUrl,
3575
+ requestId
3576
+ }
3577
+ });
3578
+ }
3579
+ async function tnDecryptV2(ctHash, chainId, permission, thresholdNetworkUrl) {
3580
+ const requestId = await submitDecryptRequestV2(thresholdNetworkUrl, ctHash, chainId, permission);
3581
+ return await pollDecryptStatusV2(thresholdNetworkUrl, requestId);
3480
3582
  }
3481
3583
 
3482
3584
  // core/decrypt/decryptForTxBuilder.ts
@@ -3624,7 +3726,9 @@ var DecryptForTxBuilder = class extends BaseBuilder {
3624
3726
  async mocksDecryptForTx(permit) {
3625
3727
  this.assertPublicClient();
3626
3728
  const delay = this.config.mocks.decryptDelay;
3627
- const result = await cofheMocksDecryptForTx(this.ctHash, 0, permit, this.publicClient, delay);
3729
+ if (delay > 0)
3730
+ await sleep(delay);
3731
+ const result = await cofheMocksDecryptForTx(this.ctHash, 0, permit, this.publicClient);
3628
3732
  return result;
3629
3733
  }
3630
3734
  /**
@@ -3635,7 +3739,7 @@ var DecryptForTxBuilder = class extends BaseBuilder {
3635
3739
  this.assertPublicClient();
3636
3740
  const thresholdNetworkUrl = await this.getThresholdNetworkUrl();
3637
3741
  const permission = permit ? PermitUtils.getPermission(permit, true) : null;
3638
- const { decryptedValue, signature } = await tnDecrypt(this.ctHash, this.chainId, permission, thresholdNetworkUrl);
3742
+ const { decryptedValue, signature } = await tnDecryptV2(this.ctHash, this.chainId, permission, thresholdNetworkUrl);
3639
3743
  return {
3640
3744
  ctHash: this.ctHash,
3641
3745
  decryptedValue,
@@ -3843,19 +3947,19 @@ function createCofheClientBase(opts) {
3843
3947
  return permits.getOrCreateSharingPermit(publicClient, walletClient, options, _chainId, _account);
3844
3948
  },
3845
3949
  // Retrieval methods (auto-fill chainId/account)
3846
- getPermit: async (hash, chainId, account) => {
3950
+ getPermit: (hash, chainId, account) => {
3847
3951
  const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
3848
3952
  return permits.getPermit(_chainId, _account, hash);
3849
3953
  },
3850
- getPermits: async (chainId, account) => {
3954
+ getPermits: (chainId, account) => {
3851
3955
  const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
3852
3956
  return permits.getPermits(_chainId, _account);
3853
3957
  },
3854
- getActivePermit: async (chainId, account) => {
3958
+ getActivePermit: (chainId, account) => {
3855
3959
  const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
3856
3960
  return permits.getActivePermit(_chainId, _account);
3857
3961
  },
3858
- getActivePermitHash: async (chainId, account) => {
3962
+ getActivePermitHash: (chainId, account) => {
3859
3963
  const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
3860
3964
  return permits.getActivePermitHash(_chainId, _account);
3861
3965
  },
package/dist/node.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { C as CofheInputConfig, a as CofheConfig, b as CofheClient } from './clientTypes-Bhq7pCSA.cjs';
1
+ import { C as CofheInputConfig, a as CofheConfig, b as CofheClient } from './clientTypes-ACVWbrXL.cjs';
2
2
  import 'viem';
3
3
  import './types-YiAC4gig.cjs';
4
4
  import 'zod';
package/dist/node.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { C as CofheInputConfig, a as CofheConfig, b as CofheClient } from './clientTypes-6aTZPQ_4.js';
1
+ import { C as CofheInputConfig, a as CofheConfig, b as CofheClient } from './clientTypes-kkrRdawm.js';
2
2
  import 'viem';
3
3
  import './types-YiAC4gig.js';
4
4
  import 'zod';
package/dist/node.js CHANGED
@@ -1,4 +1,4 @@
1
- import { createCofheConfigBase, createCofheClientBase } from './chunk-2TPSCOW3.js';
1
+ import { createCofheConfigBase, createCofheClientBase } from './chunk-MXND5SVN.js';
2
2
  import './chunk-TBLR7NNE.js';
3
3
  import './chunk-NWDKXBIP.js';
4
4
  import { promises } from 'fs';