@calimero-network/mero-js 19.24.0 → 19.24.1

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/index.cjs CHANGED
@@ -6760,6 +6760,8 @@ var HEADER_LEN = 1 + SESSION_ID_LEN + 8;
6760
6760
  var FRAME_HEAD = 0;
6761
6761
  var FRAME_DATA = 1;
6762
6762
  var FRAME_END = 2;
6763
+ var MAX_FRAME_LEN = 1 + 64 * 1024 + 16;
6764
+ var MAX_HANDSHAKE_REPLY = 1024;
6763
6765
  var RENEW_BEFORE_MS = 6e4;
6764
6766
  var TRANSPORT_BINDING_DOMAIN = "calimero.tee-attest.transport-key.v1";
6765
6767
  var NULL_BODY_STATUSES = [101, 204, 205, 304];
@@ -6771,10 +6773,11 @@ var StaleTransportKeyError = class extends Error {
6771
6773
  }
6772
6774
  };
6773
6775
  var SealedTransportError = class extends Error {
6774
- constructor(status, code, message) {
6776
+ constructor(status, code, message, retryAfterMs) {
6775
6777
  super(message);
6776
6778
  this.status = status;
6777
6779
  this.code = code;
6780
+ this.retryAfterMs = retryAfterMs;
6778
6781
  this.name = "SealedTransportError";
6779
6782
  }
6780
6783
  };
@@ -6878,6 +6881,15 @@ async function checkedKey(key) {
6878
6881
  return bytes;
6879
6882
  }
6880
6883
  async function handshake(baseFetch, nodeUrl, transportKey) {
6884
+ try {
6885
+ return await handshakeOnce(baseFetch, nodeUrl, transportKey);
6886
+ } catch (error) {
6887
+ if (!(error instanceof SealedTransportError) || error.code !== "busy") throw error;
6888
+ await new Promise((resolve) => setTimeout(resolve, error.retryAfterMs ?? 1e3));
6889
+ return handshakeOnce(baseFetch, nodeUrl, transportKey);
6890
+ }
6891
+ }
6892
+ async function handshakeOnce(baseFetch, nodeUrl, transportKey) {
6881
6893
  const noise = await initiate(transportKey, PROLOGUE);
6882
6894
  const response = await baseFetch(`${nodeUrl}${HANDSHAKE_PATH}`, {
6883
6895
  method: "POST",
@@ -6887,7 +6899,7 @@ async function handshake(baseFetch, nodeUrl, transportKey) {
6887
6899
  if (response.headers.get("content-type") !== SEALED_CONTENT_TYPE) {
6888
6900
  throw await envelopeRefusal(response);
6889
6901
  }
6890
- const reply = new Uint8Array(await response.arrayBuffer());
6902
+ const reply = await readAtMost(response, MAX_HANDSHAKE_REPLY);
6891
6903
  return sessionFrom(noise, reply);
6892
6904
  }
6893
6905
  async function sessionFrom(noise, reply) {
@@ -7013,6 +7025,10 @@ function frameReader(reader) {
7013
7025
  async next() {
7014
7026
  if (!await fill(4)) return null;
7015
7027
  const length = new DataView(buffer.buffer, buffer.byteOffset).getUint32(0, false);
7028
+ if (length > MAX_FRAME_LEN) {
7029
+ await reader.cancel();
7030
+ throw new Error("The sealed response is malformed: a frame is larger than the node sends");
7031
+ }
7016
7032
  if (!await fill(4 + length)) return null;
7017
7033
  const frame = buffer.slice(4, 4 + length);
7018
7034
  buffer = buffer.slice(4 + length);
@@ -7021,6 +7037,20 @@ function frameReader(reader) {
7021
7037
  cancel: () => reader.cancel()
7022
7038
  };
7023
7039
  }
7040
+ async function readAtMost(response, limit) {
7041
+ if (!response.body) return new Uint8Array();
7042
+ const reader = response.body.getReader();
7043
+ let bytes = new Uint8Array();
7044
+ for (; ; ) {
7045
+ const { done, value } = await reader.read();
7046
+ if (done) return bytes;
7047
+ bytes = concat(bytes, value);
7048
+ if (bytes.length > limit) {
7049
+ await reader.cancel();
7050
+ throw new Error("The handshake reply is malformed: it is too long");
7051
+ }
7052
+ }
7053
+ }
7024
7054
  async function envelopeRefusal(response) {
7025
7055
  let code;
7026
7056
  let message = `Sealed request refused: HTTP ${response.status}`;
@@ -7031,7 +7061,9 @@ async function envelopeRefusal(response) {
7031
7061
  } catch {
7032
7062
  }
7033
7063
  if (code === "stale_transport_key") return new StaleTransportKeyError();
7034
- return new SealedTransportError(response.status, code, message);
7064
+ const retryAfter = Number(response.headers.get("retry-after"));
7065
+ const retryAfterMs = Number.isFinite(retryAfter) && retryAfter > 0 ? Math.min(retryAfter, 5) * 1e3 : void 0;
7066
+ return new SealedTransportError(response.status, code, message, retryAfterMs);
7035
7067
  }
7036
7068
 
7037
7069
  // src/namespace-op/namespace-op.ts