@cofhe/sdk 1.1.0-alpha.3 → 1.1.0-alpha.4

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
@@ -2367,6 +2367,8 @@ var CofheConfigSchema = zod.z.object({
2367
2367
  supportedChains: zod.z.array(zod.z.custom()),
2368
2368
  /** Default acp expiration in seconds, default is 30 days */
2369
2369
  defaultACPExpiration: zod.z.number().optional().default(60 * 60 * 24 * 30),
2370
+ /** Decrypts sent to the threshold network at a time per client; `Infinity` disables the cap (default 8) */
2371
+ decryptConcurrency: zod.z.union([zod.z.number().min(1), zod.z.literal(Infinity)]).optional().default(8),
2370
2372
  /** Storage method for fhe keys (defaults to indexedDB on web, filesystem on node) */
2371
2373
  fheKeyStorage: zod.z.object({
2372
2374
  getItem: zod.z.custom((val) => typeof val === "function", {
@@ -3909,6 +3911,32 @@ function throwIfSubmitRetryTimedOut(params) {
3909
3911
  });
3910
3912
  }
3911
3913
  }
3914
+ function decryptAbortedError(operationLabel, signal) {
3915
+ return new CofheError({
3916
+ code: "ABORTED" /* Aborted */,
3917
+ message: `${operationLabel} aborted by the caller`,
3918
+ cause: signal.reason instanceof Error ? signal.reason : void 0
3919
+ });
3920
+ }
3921
+ function throwIfAborted(signal, operationLabel) {
3922
+ if (signal?.aborted)
3923
+ throw decryptAbortedError(operationLabel, signal);
3924
+ }
3925
+ function sleepUnlessAborted(ms, signal, operationLabel) {
3926
+ return new Promise((resolve, reject) => {
3927
+ if (signal?.aborted)
3928
+ return reject(decryptAbortedError(operationLabel, signal));
3929
+ const onAbort = () => {
3930
+ clearTimeout(timer);
3931
+ reject(decryptAbortedError(operationLabel, signal));
3932
+ };
3933
+ const timer = setTimeout(() => {
3934
+ signal?.removeEventListener("abort", onAbort);
3935
+ resolve();
3936
+ }, ms);
3937
+ signal?.addEventListener("abort", onAbort, { once: true });
3938
+ });
3939
+ }
3912
3940
  function normalizeTnSignature(signature) {
3913
3941
  if (typeof signature !== "string") {
3914
3942
  throw new CofheError({
@@ -4026,7 +4054,7 @@ function parseCompletedSealOutputResponse(params) {
4026
4054
  }
4027
4055
  return convertSealedData(sealed);
4028
4056
  }
4029
- async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, acp, overallStartTime, retry404TimeoutMs, timeoutMs, onPoll) {
4057
+ async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, acp, overallStartTime, retry404TimeoutMs, timeoutMs, onPoll, signal) {
4030
4058
  const body = {
4031
4059
  ct_tempkey: BigInt(ctHash).toString(16).padStart(64, "0"),
4032
4060
  host_chain_id: chainId,
@@ -4035,6 +4063,7 @@ async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, acp
4035
4063
  let attemptIndex = 0;
4036
4064
  let last404ApiErrorMessage;
4037
4065
  for (; ; ) {
4066
+ throwIfAborted(signal, "sealOutput");
4038
4067
  let response;
4039
4068
  try {
4040
4069
  response = await cofheFetch(
@@ -4045,10 +4074,12 @@ async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, acp
4045
4074
  headers: {
4046
4075
  "Content-Type": "application/json"
4047
4076
  },
4048
- body: JSON.stringify(body)
4077
+ body: JSON.stringify(body),
4078
+ signal
4049
4079
  }
4050
4080
  );
4051
4081
  } catch (e) {
4082
+ throwIfAborted(signal, "sealOutput");
4052
4083
  throw new CofheError({
4053
4084
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
4054
4085
  message: `sealOutput request failed`,
@@ -4143,13 +4174,14 @@ async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, acp
4143
4174
  intervalMs: SUBMIT_RETRY_INTERVAL_MS,
4144
4175
  timeoutMs
4145
4176
  });
4146
- await new Promise((resolve) => setTimeout(resolve, SUBMIT_RETRY_INTERVAL_MS));
4177
+ await sleepUnlessAborted(SUBMIT_RETRY_INTERVAL_MS, signal, "sealOutput");
4147
4178
  attemptIndex += 1;
4148
4179
  }
4149
4180
  }
4150
- async function pollSealOutputStatus(thresholdNetworkUrl, requestId, overallStartTime, timeoutMs, onPoll) {
4181
+ async function pollSealOutputStatus(thresholdNetworkUrl, requestId, overallStartTime, timeoutMs, onPoll, signal) {
4151
4182
  let attemptIndex = 0;
4152
4183
  while (true) {
4184
+ throwIfAborted(signal, "sealOutput");
4153
4185
  const elapsedMs = Date.now() - overallStartTime;
4154
4186
  const intervalMs = computeMinuteRampPollIntervalMs(elapsedMs, {
4155
4187
  minIntervalMs: POLL_INTERVAL_MS,
@@ -4184,7 +4216,8 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId, overallStart
4184
4216
  method: "GET",
4185
4217
  headers: {
4186
4218
  "Content-Type": "application/json"
4187
- }
4219
+ },
4220
+ signal
4188
4221
  }
4189
4222
  );
4190
4223
  } catch (e) {
@@ -4245,7 +4278,7 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId, overallStart
4245
4278
  requestId
4246
4279
  });
4247
4280
  }
4248
- await new Promise((resolve) => setTimeout(resolve, intervalMs));
4281
+ await sleepUnlessAborted(intervalMs, signal, "sealOutput");
4249
4282
  attemptIndex += 1;
4250
4283
  }
4251
4284
  throw new CofheError({
@@ -4258,7 +4291,7 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId, overallStart
4258
4291
  });
4259
4292
  }
4260
4293
  async function tnSealOutputV2(params) {
4261
- const { thresholdNetworkUrl, ctHash, chainId, acp, retry404TimeoutMs, onPoll } = params;
4294
+ const { thresholdNetworkUrl, ctHash, chainId, acp, retry404TimeoutMs, onPoll, signal } = params;
4262
4295
  const timeoutMs = params.timeoutMs ?? DEFAULT_DECRYPT_TIMEOUT_MS;
4263
4296
  const normalized404RetryTimeoutMs = normalize404RetryTimeoutMs({
4264
4297
  timeoutMs: retry404TimeoutMs,
@@ -4274,12 +4307,20 @@ async function tnSealOutputV2(params) {
4274
4307
  overallStartTime,
4275
4308
  normalized404RetryTimeoutMs,
4276
4309
  timeoutMs,
4277
- onPoll
4310
+ onPoll,
4311
+ signal
4278
4312
  );
4279
4313
  if (submitResult.kind === "completed") {
4280
4314
  return submitResult.sealed;
4281
4315
  }
4282
- return await pollSealOutputStatus(thresholdNetworkUrl, submitResult.requestId, overallStartTime, timeoutMs, onPoll);
4316
+ return await pollSealOutputStatus(
4317
+ thresholdNetworkUrl,
4318
+ submitResult.requestId,
4319
+ overallStartTime,
4320
+ timeoutMs,
4321
+ onPoll,
4322
+ signal
4323
+ );
4283
4324
  }
4284
4325
 
4285
4326
  // core/decrypt/decryptForViewBuilder.ts
@@ -4292,6 +4333,8 @@ var DecryptForViewBuilder = class extends BaseBuilder {
4292
4333
  pollCallback;
4293
4334
  retry404TimeoutMs = DEFAULT_404_RETRY_TIMEOUT_MS2;
4294
4335
  timeoutMs;
4336
+ signal;
4337
+ limit;
4295
4338
  constructor(params) {
4296
4339
  super({
4297
4340
  config: params.config,
@@ -4305,6 +4348,7 @@ var DecryptForViewBuilder = class extends BaseBuilder {
4305
4348
  this.utype = params.utype;
4306
4349
  this.acpHash = params.acpHash;
4307
4350
  this.acp = params.acp;
4351
+ this.limit = params.limit ?? ((task) => task());
4308
4352
  }
4309
4353
  /**
4310
4354
  * @param chainId - Chain to decrypt values from. Used to fetch the threshold network URL and use the correct acp.
@@ -4375,6 +4419,15 @@ var DecryptForViewBuilder = class extends BaseBuilder {
4375
4419
  this.timeoutMs = timeoutMs;
4376
4420
  return this;
4377
4421
  }
4422
+ /**
4423
+ * Stops the decrypt when `signal` fires: the pending request is aborted, no further attempt is
4424
+ * sent, and `execute()` rejects with `Aborted`. A request already processing on the threshold
4425
+ * network is not cancelled.
4426
+ */
4427
+ setSignal(signal) {
4428
+ this.signal = signal;
4429
+ return this;
4430
+ }
4378
4431
  withACP(acpOrACPHash) {
4379
4432
  if (typeof acpOrACPHash === "string") {
4380
4433
  this.acpHash = acpOrACPHash;
@@ -4498,15 +4551,20 @@ var DecryptForViewBuilder = class extends BaseBuilder {
4498
4551
  this.assertPublicClient();
4499
4552
  const thresholdNetworkUrl = await this.getThresholdNetworkUrl();
4500
4553
  const wireAcp = ACPUtils.getPublic(acp, true);
4501
- const sealed = await tnSealOutputV2({
4502
- ctHash: this.ctHash,
4503
- chainId: this.chainId,
4504
- acp: wireAcp,
4505
- thresholdNetworkUrl,
4506
- retry404TimeoutMs: this.retry404TimeoutMs,
4507
- timeoutMs: this.timeoutMs,
4508
- onPoll: this.pollCallback
4509
- });
4554
+ const sealed = await this.limit(
4555
+ () => tnSealOutputV2({
4556
+ ctHash: this.ctHash,
4557
+ chainId: this.chainId,
4558
+ acp: wireAcp,
4559
+ thresholdNetworkUrl,
4560
+ retry404TimeoutMs: this.retry404TimeoutMs,
4561
+ timeoutMs: this.timeoutMs,
4562
+ onPoll: this.pollCallback,
4563
+ signal: this.signal
4564
+ }),
4565
+ "sealOutput",
4566
+ this.signal
4567
+ );
4510
4568
  return ACPUtils.unseal(acp, sealed);
4511
4569
  }
4512
4570
  /**
@@ -4723,7 +4781,7 @@ function assertDecryptStatusResponseV2(value) {
4723
4781
  }
4724
4782
  return value;
4725
4783
  }
4726
- async function submitDecryptRequestV2(thresholdNetworkUrl, ctHash, chainId, acp, overallStartTime, retry404TimeoutMs, timeoutMs, onPoll) {
4784
+ async function submitDecryptRequestV2(thresholdNetworkUrl, ctHash, chainId, acp, overallStartTime, retry404TimeoutMs, timeoutMs, onPoll, signal) {
4727
4785
  const body = {
4728
4786
  ct_tempkey: BigInt(ctHash).toString(16).padStart(64, "0"),
4729
4787
  host_chain_id: chainId
@@ -4734,6 +4792,7 @@ async function submitDecryptRequestV2(thresholdNetworkUrl, ctHash, chainId, acp,
4734
4792
  let attemptIndex = 0;
4735
4793
  let last404ApiErrorMessage;
4736
4794
  for (; ; ) {
4795
+ throwIfAborted(signal, "decrypt");
4737
4796
  let response;
4738
4797
  try {
4739
4798
  response = await cofheFetch(
@@ -4744,10 +4803,12 @@ async function submitDecryptRequestV2(thresholdNetworkUrl, ctHash, chainId, acp,
4744
4803
  headers: {
4745
4804
  "Content-Type": "application/json"
4746
4805
  },
4747
- body: JSON.stringify(body)
4806
+ body: JSON.stringify(body),
4807
+ signal
4748
4808
  }
4749
4809
  );
4750
4810
  } catch (e) {
4811
+ throwIfAborted(signal, "decrypt");
4751
4812
  throw new CofheError({
4752
4813
  code: "DECRYPT_FAILED" /* DecryptFailed */,
4753
4814
  message: `decrypt request failed`,
@@ -4844,13 +4905,14 @@ async function submitDecryptRequestV2(thresholdNetworkUrl, ctHash, chainId, acp,
4844
4905
  intervalMs: SUBMIT_RETRY_INTERVAL_MS2,
4845
4906
  timeoutMs
4846
4907
  });
4847
- await new Promise((resolve) => setTimeout(resolve, SUBMIT_RETRY_INTERVAL_MS2));
4908
+ await sleepUnlessAborted(SUBMIT_RETRY_INTERVAL_MS2, signal, "decrypt");
4848
4909
  attemptIndex += 1;
4849
4910
  }
4850
4911
  }
4851
- async function pollDecryptStatusV2(thresholdNetworkUrl, requestId, overallStartTime, timeoutMs, onPoll) {
4912
+ async function pollDecryptStatusV2(thresholdNetworkUrl, requestId, overallStartTime, timeoutMs, onPoll, signal) {
4852
4913
  let attemptIndex = 0;
4853
4914
  while (true) {
4915
+ throwIfAborted(signal, "decrypt");
4854
4916
  const elapsedMs = Date.now() - overallStartTime;
4855
4917
  const intervalMs = computeMinuteRampPollIntervalMs(elapsedMs, {
4856
4918
  minIntervalMs: POLL_INTERVAL_MS2,
@@ -4885,7 +4947,8 @@ async function pollDecryptStatusV2(thresholdNetworkUrl, requestId, overallStartT
4885
4947
  method: "GET",
4886
4948
  headers: {
4887
4949
  "Content-Type": "application/json"
4888
- }
4950
+ },
4951
+ signal
4889
4952
  }
4890
4953
  );
4891
4954
  } catch (e) {
@@ -4947,7 +5010,7 @@ async function pollDecryptStatusV2(thresholdNetworkUrl, requestId, overallStartT
4947
5010
  requestId
4948
5011
  });
4949
5012
  }
4950
- await new Promise((resolve) => setTimeout(resolve, intervalMs));
5013
+ await sleepUnlessAborted(intervalMs, signal, "decrypt");
4951
5014
  attemptIndex += 1;
4952
5015
  }
4953
5016
  throw new CofheError({
@@ -4960,7 +5023,7 @@ async function pollDecryptStatusV2(thresholdNetworkUrl, requestId, overallStartT
4960
5023
  });
4961
5024
  }
4962
5025
  async function tnDecryptV2(params) {
4963
- const { thresholdNetworkUrl, ctHash, chainId, acp, retry404TimeoutMs, onPoll } = params;
5026
+ const { thresholdNetworkUrl, ctHash, chainId, acp, retry404TimeoutMs, onPoll, signal } = params;
4964
5027
  const timeoutMs = params.timeoutMs ?? DEFAULT_DECRYPT_TIMEOUT_MS;
4965
5028
  const normalized404RetryTimeoutMs = normalize404RetryTimeoutMs({
4966
5029
  timeoutMs: retry404TimeoutMs,
@@ -4976,12 +5039,20 @@ async function tnDecryptV2(params) {
4976
5039
  overallStartTime,
4977
5040
  normalized404RetryTimeoutMs,
4978
5041
  timeoutMs,
4979
- onPoll
5042
+ onPoll,
5043
+ signal
4980
5044
  );
4981
5045
  if (submitResult.kind === "completed") {
4982
5046
  return submitResult;
4983
5047
  }
4984
- return await pollDecryptStatusV2(thresholdNetworkUrl, submitResult.requestId, overallStartTime, timeoutMs, onPoll);
5048
+ return await pollDecryptStatusV2(
5049
+ thresholdNetworkUrl,
5050
+ submitResult.requestId,
5051
+ overallStartTime,
5052
+ timeoutMs,
5053
+ onPoll,
5054
+ signal
5055
+ );
4985
5056
  }
4986
5057
 
4987
5058
  // core/decrypt/decryptForTxBuilder.ts
@@ -4994,6 +5065,8 @@ var DecryptForTxBuilder = class extends BaseBuilder {
4994
5065
  pollCallback;
4995
5066
  retry404TimeoutMs = DEFAULT_404_RETRY_TIMEOUT_MS3;
4996
5067
  timeoutMs;
5068
+ signal;
5069
+ limit;
4997
5070
  constructor(params) {
4998
5071
  super({
4999
5072
  config: params.config,
@@ -5004,6 +5077,7 @@ var DecryptForTxBuilder = class extends BaseBuilder {
5004
5077
  requireConnected: params.requireConnected
5005
5078
  });
5006
5079
  this.ctHash = params.ctHash;
5080
+ this.limit = params.limit ?? ((task) => task());
5007
5081
  }
5008
5082
  setChainId(chainId) {
5009
5083
  this.chainId = chainId;
@@ -5041,6 +5115,10 @@ var DecryptForTxBuilder = class extends BaseBuilder {
5041
5115
  this.timeoutMs = timeoutMs;
5042
5116
  return this;
5043
5117
  }
5118
+ setSignal(signal) {
5119
+ this.signal = signal;
5120
+ return this;
5121
+ }
5044
5122
  withACP(acpOrACPHash) {
5045
5123
  if (this.acpSelection === "with-acp") {
5046
5124
  throw new CofheError({
@@ -5168,15 +5246,20 @@ var DecryptForTxBuilder = class extends BaseBuilder {
5168
5246
  this.assertPublicClient();
5169
5247
  const thresholdNetworkUrl = await this.getThresholdNetworkUrl();
5170
5248
  const wireAcp = acp ? ACPUtils.getPublic(acp, true) : null;
5171
- const { decryptedValue, signature } = await tnDecryptV2({
5172
- ctHash: this.ctHash,
5173
- chainId: this.chainId,
5174
- acp: wireAcp,
5175
- thresholdNetworkUrl,
5176
- retry404TimeoutMs: this.retry404TimeoutMs,
5177
- timeoutMs: this.timeoutMs,
5178
- onPoll: this.pollCallback
5179
- });
5249
+ const { decryptedValue, signature } = await this.limit(
5250
+ () => tnDecryptV2({
5251
+ ctHash: this.ctHash,
5252
+ chainId: this.chainId,
5253
+ acp: wireAcp,
5254
+ thresholdNetworkUrl,
5255
+ retry404TimeoutMs: this.retry404TimeoutMs,
5256
+ timeoutMs: this.timeoutMs,
5257
+ onPoll: this.pollCallback,
5258
+ signal: this.signal
5259
+ }),
5260
+ "decrypt",
5261
+ this.signal
5262
+ );
5180
5263
  return {
5181
5264
  ctHash: this.ctHash,
5182
5265
  decryptedValue,
@@ -5214,6 +5297,39 @@ var DecryptForTxBuilder = class extends BaseBuilder {
5214
5297
  }
5215
5298
  }
5216
5299
  };
5300
+
5301
+ // core/decrypt/decryptLimiter.ts
5302
+ function createDecryptLimiter(max) {
5303
+ let active = 0;
5304
+ const waiting = [];
5305
+ return async (task, operationLabel, signal) => {
5306
+ if (signal?.aborted)
5307
+ throw decryptAbortedError(operationLabel, signal);
5308
+ if (active >= max) {
5309
+ await new Promise((resume, reject) => {
5310
+ const onAbort = () => {
5311
+ const index = waiting.indexOf(start);
5312
+ if (index >= 0)
5313
+ waiting.splice(index, 1);
5314
+ reject(decryptAbortedError(operationLabel, signal));
5315
+ };
5316
+ const start = () => {
5317
+ signal?.removeEventListener("abort", onAbort);
5318
+ resume();
5319
+ };
5320
+ signal?.addEventListener("abort", onAbort, { once: true });
5321
+ waiting.push(start);
5322
+ });
5323
+ }
5324
+ active += 1;
5325
+ try {
5326
+ return await task();
5327
+ } finally {
5328
+ active -= 1;
5329
+ waiting.shift()?.();
5330
+ }
5331
+ };
5332
+ }
5217
5333
  var decryptResultSignerAbi = viem.parseAbi(["function decryptResultSigner() view returns (address)"]);
5218
5334
  var UINT_TYPE_MASK2 = 0x7fn;
5219
5335
  var TYPE_BYTE_OFFSET2 = 8n;
@@ -5359,11 +5475,13 @@ function createCofheClientBase(opts) {
5359
5475
  requireConnected: _requireConnected
5360
5476
  });
5361
5477
  }
5478
+ const decryptLimiter = createDecryptLimiter(opts.config.decryptConcurrency);
5362
5479
  function decryptForView(ctHash, utype) {
5363
5480
  const state = connectStore.getState();
5364
5481
  return new DecryptForViewBuilder({
5365
5482
  ctHash,
5366
5483
  utype,
5484
+ limit: decryptLimiter,
5367
5485
  chainId: state.chainId,
5368
5486
  account: state.account,
5369
5487
  config: opts.config,
@@ -5376,6 +5494,7 @@ function createCofheClientBase(opts) {
5376
5494
  const state = connectStore.getState();
5377
5495
  return new DecryptForTxBuilder({
5378
5496
  ctHash,
5497
+ limit: decryptLimiter,
5379
5498
  chainId: state.chainId,
5380
5499
  account: state.account,
5381
5500
  config: opts.config,
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-BCAMwrqk.cjs';
1
+ import { I as IStorage, C as CofheInputConfig, a as CofheConfig, b as CofheClient, E as EncryptableItem } from './clientTypes-K6XNB9H2.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-LvslG7o0.js';
1
+ import { I as IStorage, C as CofheInputConfig, a as CofheConfig, b as CofheClient, E as EncryptableItem } from './clientTypes-DFXuL9kz.js';
2
2
  import 'viem';
3
3
  import './types-C07FK-cL.js';
4
4
  import 'zod';
package/dist/web.js CHANGED
@@ -1,9 +1,9 @@
1
- import { createCofheConfigBase, createCofheClientBase } from './chunk-KHM6LYLU.js';
1
+ import { createCofheConfigBase, createCofheClientBase } from './chunk-ZYCIUX5C.js';
2
2
  import './chunk-UKQAJK4N.js';
3
- import './chunk-WAA2U7CT.js';
3
+ import './chunk-37SG44CR.js';
4
4
  import { initTfheThreadPool } from './chunk-KSOV5B4B.js';
5
- import { fheTypeToString, fromHexString } from './chunk-3SD2UCRE.js';
6
- import { TFHE_RS_SAFE_SERIALIZATION_SIZE_LIMIT } from './chunk-OC5TGQGG.js';
5
+ import { fheTypeToString, fromHexString } from './chunk-PLHQYVND.js';
6
+ import { TFHE_RS_SAFE_SERIALIZATION_SIZE_LIMIT } from './chunk-NJTYZ3CW.js';
7
7
  import { constructClient } from 'iframe-shared-storage';
8
8
 
9
9
  // web/const.ts
@@ -1,6 +1,6 @@
1
1
  import { initTfheThreadPool } from './chunk-KSOV5B4B.js';
2
- import { fromHexString } from './chunk-3SD2UCRE.js';
3
- import { TFHE_RS_SAFE_SERIALIZATION_SIZE_LIMIT } from './chunk-OC5TGQGG.js';
2
+ import { fromHexString } from './chunk-PLHQYVND.js';
3
+ import { TFHE_RS_SAFE_SERIALIZATION_SIZE_LIMIT } from './chunk-NJTYZ3CW.js';
4
4
 
5
5
  // web/zkProve.worker.ts
6
6
  var tfheModule = null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cofhe/sdk",
3
- "version": "1.1.0-alpha.3",
3
+ "version": "1.1.0-alpha.4",
4
4
  "type": "module",
5
5
  "description": "SDK for Fhenix COFHE coprocessor interaction",
6
6
  "main": "./dist/core.cjs",