@cofhe/sdk 0.5.0 → 0.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/web.cjs CHANGED
@@ -9,13 +9,11 @@ var middleware = require('zustand/middleware');
9
9
  var immer = require('immer');
10
10
  var nacl = require('tweetnacl');
11
11
  var iframeSharedStorage = require('iframe-shared-storage');
12
- var init = require('tfhe');
13
12
 
14
13
  var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
15
14
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
16
15
 
17
16
  var nacl__default = /*#__PURE__*/_interopDefault(nacl);
18
- var init__default = /*#__PURE__*/_interopDefault(init);
19
17
 
20
18
  // core/client.ts
21
19
 
@@ -2846,6 +2844,96 @@ function computeMinuteRampPollIntervalMs(elapsedMs, params) {
2846
2844
  return Math.min(params.maxIntervalMs, Math.max(params.minIntervalMs, intervalMs));
2847
2845
  }
2848
2846
 
2847
+ // core/decrypt/submitRetry.ts
2848
+ var DEFAULT_404_RETRY_TIMEOUT_MS = 1e4;
2849
+ function isRetryableSubmitStatus(status) {
2850
+ return status === 204 || status === 404;
2851
+ }
2852
+ function normalize404RetryTimeoutMs(params) {
2853
+ const { timeoutMs, operationLabel, errorCode } = params;
2854
+ if (timeoutMs === void 0)
2855
+ return DEFAULT_404_RETRY_TIMEOUT_MS;
2856
+ if (!Number.isFinite(timeoutMs) || timeoutMs < 0) {
2857
+ throw new CofheError({
2858
+ code: errorCode,
2859
+ message: `${operationLabel} submit 404 retry timeout must be a finite number greater than or equal to 0`,
2860
+ context: {
2861
+ timeoutMs
2862
+ }
2863
+ });
2864
+ }
2865
+ return timeoutMs;
2866
+ }
2867
+ async function classifySubmitResponse(params) {
2868
+ const { response, extractErrorMessage } = params;
2869
+ if (isRetryableSubmitStatus(response.status)) {
2870
+ return { kind: "retryable", status: response.status };
2871
+ }
2872
+ if (response.ok) {
2873
+ return { kind: "parse-json" };
2874
+ }
2875
+ let errorMessage = `HTTP ${response.status}`;
2876
+ try {
2877
+ const errorBody = await response.json();
2878
+ const maybeErrorMessage = extractErrorMessage?.(errorBody);
2879
+ if (typeof maybeErrorMessage === "string" && maybeErrorMessage.length > 0) {
2880
+ errorMessage = maybeErrorMessage;
2881
+ } else if (errorBody && typeof errorBody === "object") {
2882
+ const defaultMessage = errorBody.error_message;
2883
+ const fallbackMessage = errorBody.message;
2884
+ if (typeof defaultMessage === "string" && defaultMessage.length > 0) {
2885
+ errorMessage = defaultMessage;
2886
+ } else if (typeof fallbackMessage === "string" && fallbackMessage.length > 0) {
2887
+ errorMessage = fallbackMessage;
2888
+ }
2889
+ }
2890
+ } catch {
2891
+ errorMessage = response.statusText || errorMessage;
2892
+ }
2893
+ return { kind: "fatal-http", errorMessage };
2894
+ }
2895
+ function throwIfSubmitRetryTimedOut(params) {
2896
+ const {
2897
+ operationLabel,
2898
+ errorCode,
2899
+ status,
2900
+ elapsedMs,
2901
+ retry404TimeoutMs,
2902
+ overallTimeoutMs,
2903
+ thresholdNetworkUrl,
2904
+ body,
2905
+ attemptIndex
2906
+ } = params;
2907
+ if (status === 404 && elapsedMs > retry404TimeoutMs) {
2908
+ throw new CofheError({
2909
+ code: errorCode,
2910
+ message: `${operationLabel} submit retried 404 responses without receiving request_id for ${retry404TimeoutMs}ms`,
2911
+ hint: "The ciphertext may not be indexed yet. Increase set404RetryTimeout(...) if the backend is slow to index ciphertexts.",
2912
+ context: {
2913
+ thresholdNetworkUrl,
2914
+ body,
2915
+ attemptIndex,
2916
+ timeoutMs: retry404TimeoutMs,
2917
+ status
2918
+ }
2919
+ });
2920
+ }
2921
+ if (elapsedMs > overallTimeoutMs) {
2922
+ throw new CofheError({
2923
+ code: errorCode,
2924
+ message: `${operationLabel} submit retried without receiving request_id for ${overallTimeoutMs}ms`,
2925
+ hint: "The ciphertext may still be propagating. Try again later.",
2926
+ context: {
2927
+ thresholdNetworkUrl,
2928
+ body,
2929
+ attemptIndex,
2930
+ timeoutMs: overallTimeoutMs,
2931
+ status
2932
+ }
2933
+ });
2934
+ }
2935
+ }
2936
+
2849
2937
  // core/decrypt/tnSealOutputV2.ts
2850
2938
  var POLL_INTERVAL_MS = 1e3;
2851
2939
  var POLL_MAX_INTERVAL_MS = 1e4;
@@ -2907,7 +2995,7 @@ function parseCompletedSealOutputResponse(params) {
2907
2995
  }
2908
2996
  return convertSealedData(sealed);
2909
2997
  }
2910
- async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, permission, overallStartTime, onPoll) {
2998
+ async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, permission, overallStartTime, retry404TimeoutMs, onPoll) {
2911
2999
  const body = {
2912
3000
  ct_tempkey: BigInt(ctHash).toString(16).padStart(64, "0"),
2913
3001
  host_chain_id: chainId,
@@ -2937,17 +3025,11 @@ async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, per
2937
3025
  }
2938
3026
  });
2939
3027
  }
2940
- if (!response.ok) {
2941
- let errorMessage = `HTTP ${response.status}`;
2942
- try {
2943
- const errorBody = await response.json();
2944
- errorMessage = errorBody.error_message || errorBody.message || errorMessage;
2945
- } catch {
2946
- errorMessage = response.statusText || errorMessage;
2947
- }
3028
+ const responseClassification = await classifySubmitResponse({ response });
3029
+ if (responseClassification.kind === "fatal-http") {
2948
3030
  throw new CofheError({
2949
3031
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
2950
- message: `sealOutput request failed: ${errorMessage}`,
3032
+ message: `sealOutput request failed: ${responseClassification.errorMessage}`,
2951
3033
  hint: "Check the threshold network URL and request parameters.",
2952
3034
  context: {
2953
3035
  thresholdNetworkUrl,
@@ -2958,8 +3040,8 @@ async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, per
2958
3040
  }
2959
3041
  });
2960
3042
  }
2961
- let submitResponse;
2962
- if (response.status !== 204) {
3043
+ if (responseClassification.kind === "parse-json") {
3044
+ let submitResponse;
2963
3045
  try {
2964
3046
  submitResponse = await response.json();
2965
3047
  } catch (e) {
@@ -2987,46 +3069,39 @@ async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, per
2987
3069
  if (submitResponse.request_id) {
2988
3070
  return { kind: "request_id", requestId: submitResponse.request_id };
2989
3071
  }
2990
- }
2991
- if (response.status === 204) {
2992
- const elapsedMs = Date.now() - overallStartTime;
2993
- if (elapsedMs > SEAL_OUTPUT_TIMEOUT_MS) {
2994
- throw new CofheError({
2995
- code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
2996
- message: `sealOutput submit retried without receiving request_id for ${SEAL_OUTPUT_TIMEOUT_MS}ms`,
2997
- hint: "The ciphertext may still be propagating. Try again later.",
2998
- context: {
2999
- thresholdNetworkUrl,
3000
- body,
3001
- attemptIndex,
3002
- timeoutMs: SEAL_OUTPUT_TIMEOUT_MS,
3003
- submitResponse,
3004
- status: response.status
3005
- }
3006
- });
3007
- }
3008
- onPoll?.({
3009
- operation: "sealoutput",
3010
- requestId: "",
3011
- attemptIndex,
3012
- elapsedMs,
3013
- intervalMs: SUBMIT_RETRY_INTERVAL_MS,
3014
- timeoutMs: SEAL_OUTPUT_TIMEOUT_MS
3072
+ throw new CofheError({
3073
+ code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
3074
+ message: `sealOutput submit response missing request_id`,
3075
+ context: {
3076
+ thresholdNetworkUrl,
3077
+ body,
3078
+ submitResponse,
3079
+ attemptIndex
3080
+ }
3015
3081
  });
3016
- await new Promise((resolve) => setTimeout(resolve, SUBMIT_RETRY_INTERVAL_MS));
3017
- attemptIndex += 1;
3018
- continue;
3019
3082
  }
3020
- throw new CofheError({
3021
- code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
3022
- message: `sealOutput submit response missing request_id`,
3023
- context: {
3024
- thresholdNetworkUrl,
3025
- body,
3026
- submitResponse,
3027
- attemptIndex
3028
- }
3083
+ const elapsedMs = Date.now() - overallStartTime;
3084
+ throwIfSubmitRetryTimedOut({
3085
+ operationLabel: "sealOutput",
3086
+ errorCode: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
3087
+ status: responseClassification.status,
3088
+ elapsedMs,
3089
+ retry404TimeoutMs,
3090
+ overallTimeoutMs: SEAL_OUTPUT_TIMEOUT_MS,
3091
+ thresholdNetworkUrl,
3092
+ body,
3093
+ attemptIndex
3094
+ });
3095
+ onPoll?.({
3096
+ operation: "sealoutput",
3097
+ requestId: "",
3098
+ attemptIndex,
3099
+ elapsedMs,
3100
+ intervalMs: SUBMIT_RETRY_INTERVAL_MS,
3101
+ timeoutMs: SEAL_OUTPUT_TIMEOUT_MS
3029
3102
  });
3103
+ await new Promise((resolve) => setTimeout(resolve, SUBMIT_RETRY_INTERVAL_MS));
3104
+ attemptIndex += 1;
3030
3105
  }
3031
3106
  }
3032
3107
  async function pollSealOutputStatus(thresholdNetworkUrl, requestId, overallStartTime, onPoll) {
@@ -3141,7 +3216,12 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId, overallStart
3141
3216
  });
3142
3217
  }
3143
3218
  async function tnSealOutputV2(params) {
3144
- const { thresholdNetworkUrl, ctHash, chainId, permission, onPoll } = params;
3219
+ const { thresholdNetworkUrl, ctHash, chainId, permission, retry404TimeoutMs, onPoll } = params;
3220
+ const normalized404RetryTimeoutMs = normalize404RetryTimeoutMs({
3221
+ timeoutMs: retry404TimeoutMs,
3222
+ operationLabel: "sealOutput",
3223
+ errorCode: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */
3224
+ });
3145
3225
  const overallStartTime = Date.now();
3146
3226
  const submitResult = await submitSealOutputRequest(
3147
3227
  thresholdNetworkUrl,
@@ -3149,6 +3229,7 @@ async function tnSealOutputV2(params) {
3149
3229
  chainId,
3150
3230
  permission,
3151
3231
  overallStartTime,
3232
+ normalized404RetryTimeoutMs,
3152
3233
  onPoll
3153
3234
  );
3154
3235
  if (submitResult.kind === "completed") {
@@ -3158,12 +3239,14 @@ async function tnSealOutputV2(params) {
3158
3239
  }
3159
3240
 
3160
3241
  // core/decrypt/decryptForViewBuilder.ts
3242
+ var DEFAULT_404_RETRY_TIMEOUT_MS2 = 1e4;
3161
3243
  var DecryptForViewBuilder = class extends BaseBuilder {
3162
3244
  ctHash;
3163
3245
  utype;
3164
3246
  permitHash;
3165
3247
  permit;
3166
3248
  pollCallback;
3249
+ retry404TimeoutMs = DEFAULT_404_RETRY_TIMEOUT_MS2;
3167
3250
  constructor(params) {
3168
3251
  super({
3169
3252
  config: params.config,
@@ -3224,6 +3307,19 @@ var DecryptForViewBuilder = class extends BaseBuilder {
3224
3307
  this.pollCallback = callback;
3225
3308
  return this;
3226
3309
  }
3310
+ set404RetryTimeout(timeoutMs) {
3311
+ if (!Number.isFinite(timeoutMs) || timeoutMs < 0) {
3312
+ throw new CofheError({
3313
+ code: "INTERNAL_ERROR" /* InternalError */,
3314
+ message: "decryptForView: set404RetryTimeout(timeoutMs) expects a finite number greater than or equal to 0.",
3315
+ context: {
3316
+ timeoutMs
3317
+ }
3318
+ });
3319
+ }
3320
+ this.retry404TimeoutMs = timeoutMs;
3321
+ return this;
3322
+ }
3227
3323
  withPermit(permitOrPermitHash) {
3228
3324
  if (typeof permitOrPermitHash === "string") {
3229
3325
  this.permitHash = permitOrPermitHash;
@@ -3352,6 +3448,7 @@ var DecryptForViewBuilder = class extends BaseBuilder {
3352
3448
  chainId: this.chainId,
3353
3449
  permission,
3354
3450
  thresholdNetworkUrl,
3451
+ retry404TimeoutMs: this.retry404TimeoutMs,
3355
3452
  onPoll: this.pollCallback
3356
3453
  });
3357
3454
  return PermitUtils.unseal(permit, sealed);
@@ -3627,7 +3724,7 @@ function assertDecryptStatusResponseV2(value) {
3627
3724
  }
3628
3725
  return value;
3629
3726
  }
3630
- async function submitDecryptRequestV2(thresholdNetworkUrl, ctHash, chainId, permission, overallStartTime, onPoll) {
3727
+ async function submitDecryptRequestV2(thresholdNetworkUrl, ctHash, chainId, permission, overallStartTime, retry404TimeoutMs, onPoll) {
3631
3728
  const body = {
3632
3729
  ct_tempkey: BigInt(ctHash).toString(16).padStart(64, "0"),
3633
3730
  host_chain_id: chainId
@@ -3659,19 +3756,11 @@ async function submitDecryptRequestV2(thresholdNetworkUrl, ctHash, chainId, perm
3659
3756
  }
3660
3757
  });
3661
3758
  }
3662
- if (!response.ok) {
3663
- let errorMessage = `HTTP ${response.status}`;
3664
- try {
3665
- const errorBody = await response.json();
3666
- const maybeMessage = errorBody.error_message || errorBody.message;
3667
- if (typeof maybeMessage === "string" && maybeMessage.length > 0)
3668
- errorMessage = maybeMessage;
3669
- } catch {
3670
- errorMessage = response.statusText || errorMessage;
3671
- }
3759
+ const responseClassification = await classifySubmitResponse({ response });
3760
+ if (responseClassification.kind === "fatal-http") {
3672
3761
  throw new CofheError({
3673
3762
  code: "DECRYPT_FAILED" /* DecryptFailed */,
3674
- message: `decrypt request failed: ${errorMessage}`,
3763
+ message: `decrypt request failed: ${responseClassification.errorMessage}`,
3675
3764
  hint: "Check the threshold network URL and request parameters.",
3676
3765
  context: {
3677
3766
  thresholdNetworkUrl,
@@ -3682,8 +3771,8 @@ async function submitDecryptRequestV2(thresholdNetworkUrl, ctHash, chainId, perm
3682
3771
  }
3683
3772
  });
3684
3773
  }
3685
- let submitResponse;
3686
- if (response.status !== 204) {
3774
+ if (responseClassification.kind === "parse-json") {
3775
+ let submitResponse;
3687
3776
  let rawJson;
3688
3777
  try {
3689
3778
  rawJson = await response.json();
@@ -3713,46 +3802,39 @@ async function submitDecryptRequestV2(thresholdNetworkUrl, ctHash, chainId, perm
3713
3802
  if (submitResponse.request_id) {
3714
3803
  return { kind: "request_id", requestId: submitResponse.request_id };
3715
3804
  }
3716
- }
3717
- if (response.status === 204) {
3718
- const elapsedMs = Date.now() - overallStartTime;
3719
- if (elapsedMs > DECRYPT_TIMEOUT_MS) {
3720
- throw new CofheError({
3721
- code: "DECRYPT_FAILED" /* DecryptFailed */,
3722
- message: `decrypt submit retried without receiving request_id for ${DECRYPT_TIMEOUT_MS}ms`,
3723
- hint: "The ciphertext may still be propagating. Try again later.",
3724
- context: {
3725
- thresholdNetworkUrl,
3726
- body,
3727
- attemptIndex,
3728
- timeoutMs: DECRYPT_TIMEOUT_MS,
3729
- submitResponse,
3730
- status: response.status
3731
- }
3732
- });
3733
- }
3734
- onPoll?.({
3735
- operation: "decrypt",
3736
- requestId: "",
3737
- attemptIndex,
3738
- elapsedMs,
3739
- intervalMs: SUBMIT_RETRY_INTERVAL_MS2,
3740
- timeoutMs: DECRYPT_TIMEOUT_MS
3805
+ throw new CofheError({
3806
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
3807
+ message: `decrypt submit response missing request_id`,
3808
+ context: {
3809
+ thresholdNetworkUrl,
3810
+ body,
3811
+ submitResponse,
3812
+ attemptIndex
3813
+ }
3741
3814
  });
3742
- await new Promise((resolve) => setTimeout(resolve, SUBMIT_RETRY_INTERVAL_MS2));
3743
- attemptIndex += 1;
3744
- continue;
3745
3815
  }
3746
- throw new CofheError({
3747
- code: "DECRYPT_FAILED" /* DecryptFailed */,
3748
- message: `decrypt submit response missing request_id`,
3749
- context: {
3750
- thresholdNetworkUrl,
3751
- body,
3752
- submitResponse,
3753
- attemptIndex
3754
- }
3816
+ const elapsedMs = Date.now() - overallStartTime;
3817
+ throwIfSubmitRetryTimedOut({
3818
+ operationLabel: "decrypt",
3819
+ errorCode: "DECRYPT_FAILED" /* DecryptFailed */,
3820
+ status: responseClassification.status,
3821
+ elapsedMs,
3822
+ retry404TimeoutMs,
3823
+ overallTimeoutMs: DECRYPT_TIMEOUT_MS,
3824
+ thresholdNetworkUrl,
3825
+ body,
3826
+ attemptIndex
3755
3827
  });
3828
+ onPoll?.({
3829
+ operation: "decrypt",
3830
+ requestId: "",
3831
+ attemptIndex,
3832
+ elapsedMs,
3833
+ intervalMs: SUBMIT_RETRY_INTERVAL_MS2,
3834
+ timeoutMs: DECRYPT_TIMEOUT_MS
3835
+ });
3836
+ await new Promise((resolve) => setTimeout(resolve, SUBMIT_RETRY_INTERVAL_MS2));
3837
+ attemptIndex += 1;
3756
3838
  }
3757
3839
  }
3758
3840
  async function pollDecryptStatusV2(thresholdNetworkUrl, requestId, overallStartTime, onPoll) {
@@ -3870,7 +3952,12 @@ async function pollDecryptStatusV2(thresholdNetworkUrl, requestId, overallStartT
3870
3952
  });
3871
3953
  }
3872
3954
  async function tnDecryptV2(params) {
3873
- const { thresholdNetworkUrl, ctHash, chainId, permission, onPoll } = params;
3955
+ const { thresholdNetworkUrl, ctHash, chainId, permission, retry404TimeoutMs, onPoll } = params;
3956
+ const normalized404RetryTimeoutMs = normalize404RetryTimeoutMs({
3957
+ timeoutMs: retry404TimeoutMs,
3958
+ operationLabel: "decrypt",
3959
+ errorCode: "DECRYPT_FAILED" /* DecryptFailed */
3960
+ });
3874
3961
  const overallStartTime = Date.now();
3875
3962
  const submitResult = await submitDecryptRequestV2(
3876
3963
  thresholdNetworkUrl,
@@ -3878,6 +3965,7 @@ async function tnDecryptV2(params) {
3878
3965
  chainId,
3879
3966
  permission,
3880
3967
  overallStartTime,
3968
+ normalized404RetryTimeoutMs,
3881
3969
  onPoll
3882
3970
  );
3883
3971
  if (submitResult.kind === "completed") {
@@ -3887,12 +3975,14 @@ async function tnDecryptV2(params) {
3887
3975
  }
3888
3976
 
3889
3977
  // core/decrypt/decryptForTxBuilder.ts
3978
+ var DEFAULT_404_RETRY_TIMEOUT_MS3 = 1e4;
3890
3979
  var DecryptForTxBuilder = class extends BaseBuilder {
3891
3980
  ctHash;
3892
3981
  permitHash;
3893
3982
  permit;
3894
3983
  permitSelection = "unset";
3895
3984
  pollCallback;
3985
+ retry404TimeoutMs = DEFAULT_404_RETRY_TIMEOUT_MS3;
3896
3986
  constructor(params) {
3897
3987
  super({
3898
3988
  config: params.config,
@@ -3922,6 +4012,19 @@ var DecryptForTxBuilder = class extends BaseBuilder {
3922
4012
  this.pollCallback = callback;
3923
4013
  return this;
3924
4014
  }
4015
+ set404RetryTimeout(timeoutMs) {
4016
+ if (!Number.isFinite(timeoutMs) || timeoutMs < 0) {
4017
+ throw new CofheError({
4018
+ code: "INTERNAL_ERROR" /* InternalError */,
4019
+ message: "decryptForTx: set404RetryTimeout(timeoutMs) expects a finite number greater than or equal to 0.",
4020
+ context: {
4021
+ timeoutMs
4022
+ }
4023
+ });
4024
+ }
4025
+ this.retry404TimeoutMs = timeoutMs;
4026
+ return this;
4027
+ }
3925
4028
  withPermit(permitOrPermitHash) {
3926
4029
  if (this.permitSelection === "with-permit") {
3927
4030
  throw new CofheError({
@@ -4054,6 +4157,7 @@ var DecryptForTxBuilder = class extends BaseBuilder {
4054
4157
  chainId: this.chainId,
4055
4158
  permission,
4056
4159
  thresholdNetworkUrl,
4160
+ retry404TimeoutMs: this.retry404TimeoutMs,
4057
4161
  onPoll: this.pollCallback
4058
4162
  });
4059
4163
  return {
@@ -4550,15 +4654,25 @@ function terminateWorker() {
4550
4654
  function areWorkersAvailable() {
4551
4655
  return typeof Worker !== "undefined";
4552
4656
  }
4657
+
4658
+ // web/index.ts
4659
+ var tfheModule = null;
4553
4660
  var tfheInitialized = false;
4554
4661
  async function initTfhe() {
4555
4662
  if (tfheInitialized)
4556
4663
  return false;
4557
- await init__default.default();
4558
- await init.init_panic_hook();
4664
+ tfheModule = await import('tfhe');
4665
+ await tfheModule.default();
4666
+ await tfheModule.init_panic_hook();
4559
4667
  tfheInitialized = true;
4560
4668
  return true;
4561
4669
  }
4670
+ function requireTfhe() {
4671
+ if (!tfheModule) {
4672
+ throw new Error("TFHE not initialized \u2014 call initTfhe() (or any client method that triggers it) first");
4673
+ }
4674
+ return tfheModule;
4675
+ }
4562
4676
  var fromHexString2 = (hexString) => {
4563
4677
  const cleanString = hexString.length % 2 === 1 ? `0${hexString}` : hexString;
4564
4678
  const arr = cleanString.replace(/^0x/, "").match(/.{1,2}/g);
@@ -4567,10 +4681,13 @@ var fromHexString2 = (hexString) => {
4567
4681
  return new Uint8Array(arr.map((byte) => parseInt(byte, 16)));
4568
4682
  };
4569
4683
  var _deserializeTfhePublicKey = (buff) => {
4570
- return init.TfheCompactPublicKey.safe_deserialize(fromHexString2(buff), TFHE_RS_SAFE_SERIALIZATION_SIZE_LIMIT);
4684
+ return requireTfhe().TfheCompactPublicKey.safe_deserialize(
4685
+ fromHexString2(buff),
4686
+ TFHE_RS_SAFE_SERIALIZATION_SIZE_LIMIT
4687
+ );
4571
4688
  };
4572
4689
  var _deserializeCompactPkeCrs = (buff) => {
4573
- return init.CompactPkeCrs.safe_deserialize(fromHexString2(buff), TFHE_RS_SAFE_SERIALIZATION_SIZE_LIMIT);
4690
+ return requireTfhe().CompactPkeCrs.safe_deserialize(fromHexString2(buff), TFHE_RS_SAFE_SERIALIZATION_SIZE_LIMIT);
4574
4691
  };
4575
4692
  var tfhePublicKeyDeserializer = (buff) => {
4576
4693
  _deserializeTfhePublicKey(buff);
@@ -4580,7 +4697,7 @@ var compactPkeCrsDeserializer = (buff) => {
4580
4697
  };
4581
4698
  var zkBuilderAndCrsGenerator = (fhe, crs) => {
4582
4699
  const fhePublicKey = _deserializeTfhePublicKey(fhe);
4583
- const zkBuilder = init.ProvenCompactCiphertextList.builder(fhePublicKey);
4700
+ const zkBuilder = requireTfhe().ProvenCompactCiphertextList.builder(fhePublicKey);
4584
4701
  const zkCrs = _deserializeCompactPkeCrs(crs);
4585
4702
  return { zkBuilder, zkCrs };
4586
4703
  };
package/dist/web.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { I as IStorage, C as CofheInputConfig, a as CofheConfig, b as CofheClient, E as EncryptableItem } from './clientTypes-BSbwairE.cjs';
1
+ import { I as IStorage, C as CofheInputConfig, a as CofheConfig, b as CofheClient, E as EncryptableItem } from './clientTypes-BJbFeeno.cjs';
2
2
  import 'viem';
3
3
  import './types-C07FK-cL.cjs';
4
4
  import 'zod';
package/dist/web.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { I as IStorage, C as CofheInputConfig, a as CofheConfig, b as CofheClient, E as EncryptableItem } from './clientTypes-DDmcgZ0a.js';
1
+ import { I as IStorage, C as CofheInputConfig, a as CofheConfig, b as CofheClient, E as EncryptableItem } from './clientTypes-CEno_BEf.js';
2
2
  import 'viem';
3
3
  import './types-C07FK-cL.js';
4
4
  import 'zod';
package/dist/web.js CHANGED
@@ -1,9 +1,8 @@
1
- import { createCofheConfigBase, createCofheClientBase, fheTypeToString } from './chunk-S7OKGLFD.js';
1
+ import { createCofheConfigBase, createCofheClientBase, fheTypeToString } from './chunk-YDOK4BDL.js';
2
2
  import './chunk-TBLR7NNE.js';
3
3
  import './chunk-MRCKUMOS.js';
4
4
  import { TFHE_RS_SAFE_SERIALIZATION_SIZE_LIMIT } from './chunk-4FP4V35O.js';
5
5
  import { constructClient } from 'iframe-shared-storage';
6
- import init, { init_panic_hook, ProvenCompactCiphertextList, CompactPkeCrs, TfheCompactPublicKey } from 'tfhe';
7
6
 
8
7
  // web/const.ts
9
8
  var hasDOM = typeof globalThis?.document !== "undefined" && typeof globalThis?.window !== "undefined";
@@ -188,15 +187,25 @@ function terminateWorker() {
188
187
  function areWorkersAvailable() {
189
188
  return typeof Worker !== "undefined";
190
189
  }
190
+
191
+ // web/index.ts
192
+ var tfheModule = null;
191
193
  var tfheInitialized = false;
192
194
  async function initTfhe() {
193
195
  if (tfheInitialized)
194
196
  return false;
195
- await init();
196
- await init_panic_hook();
197
+ tfheModule = await import('tfhe');
198
+ await tfheModule.default();
199
+ await tfheModule.init_panic_hook();
197
200
  tfheInitialized = true;
198
201
  return true;
199
202
  }
203
+ function requireTfhe() {
204
+ if (!tfheModule) {
205
+ throw new Error("TFHE not initialized \u2014 call initTfhe() (or any client method that triggers it) first");
206
+ }
207
+ return tfheModule;
208
+ }
200
209
  var fromHexString = (hexString) => {
201
210
  const cleanString = hexString.length % 2 === 1 ? `0${hexString}` : hexString;
202
211
  const arr = cleanString.replace(/^0x/, "").match(/.{1,2}/g);
@@ -205,10 +214,13 @@ var fromHexString = (hexString) => {
205
214
  return new Uint8Array(arr.map((byte) => parseInt(byte, 16)));
206
215
  };
207
216
  var _deserializeTfhePublicKey = (buff) => {
208
- return TfheCompactPublicKey.safe_deserialize(fromHexString(buff), TFHE_RS_SAFE_SERIALIZATION_SIZE_LIMIT);
217
+ return requireTfhe().TfheCompactPublicKey.safe_deserialize(
218
+ fromHexString(buff),
219
+ TFHE_RS_SAFE_SERIALIZATION_SIZE_LIMIT
220
+ );
209
221
  };
210
222
  var _deserializeCompactPkeCrs = (buff) => {
211
- return CompactPkeCrs.safe_deserialize(fromHexString(buff), TFHE_RS_SAFE_SERIALIZATION_SIZE_LIMIT);
223
+ return requireTfhe().CompactPkeCrs.safe_deserialize(fromHexString(buff), TFHE_RS_SAFE_SERIALIZATION_SIZE_LIMIT);
212
224
  };
213
225
  var tfhePublicKeyDeserializer = (buff) => {
214
226
  _deserializeTfhePublicKey(buff);
@@ -218,7 +230,7 @@ var compactPkeCrsDeserializer = (buff) => {
218
230
  };
219
231
  var zkBuilderAndCrsGenerator = (fhe, crs) => {
220
232
  const fhePublicKey = _deserializeTfhePublicKey(fhe);
221
- const zkBuilder = ProvenCompactCiphertextList.builder(fhePublicKey);
233
+ const zkBuilder = requireTfhe().ProvenCompactCiphertextList.builder(fhePublicKey);
222
234
  const zkCrs = _deserializeCompactPkeCrs(crs);
223
235
  return { zkBuilder, zkCrs };
224
236
  };