wao 0.30.0 → 0.30.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/cjs/id.js CHANGED
@@ -1,21 +1,19 @@
1
1
  "use strict";
2
2
 
3
- function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
4
3
  Object.defineProperty(exports, "__esModule", {
5
4
  value: true
6
5
  });
6
+ exports.base = base;
7
7
  exports.extractCommitmentIds = extractCommitmentIds;
8
8
  exports.generateCommitmentId = generateCommitmentId;
9
- exports.generateHmacCommitmentId = generateHmacCommitmentId;
10
- exports.generateRsaCommitmentId = generateRsaCommitmentId;
9
+ exports.hashpath = hashpath;
10
+ exports.hmacid = hmacid;
11
11
  exports.id = id;
12
12
  exports.parseStructuredFieldDictionary = parseStructuredFieldDictionary;
13
+ exports.rsaid = rsaid;
13
14
  exports.verifyCommitmentId = verifyCommitmentId;
14
15
  var _fastSha = require("fast-sha256");
15
- function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return e; }; var t, e = {}, r = Object.prototype, n = r.hasOwnProperty, o = Object.defineProperty || function (t, e, r) { t[e] = r.value; }, i = "function" == typeof Symbol ? Symbol : {}, a = i.iterator || "@@iterator", c = i.asyncIterator || "@@asyncIterator", u = i.toStringTag || "@@toStringTag"; function define(t, e, r) { return Object.defineProperty(t, e, { value: r, enumerable: !0, configurable: !0, writable: !0 }), t[e]; } try { define({}, ""); } catch (t) { define = function define(t, e, r) { return t[e] = r; }; } function wrap(t, e, r, n) { var i = e && e.prototype instanceof Generator ? e : Generator, a = Object.create(i.prototype), c = new Context(n || []); return o(a, "_invoke", { value: makeInvokeMethod(t, r, c) }), a; } function tryCatch(t, e, r) { try { return { type: "normal", arg: t.call(e, r) }; } catch (t) { return { type: "throw", arg: t }; } } e.wrap = wrap; var h = "suspendedStart", l = "suspendedYield", f = "executing", s = "completed", y = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var p = {}; define(p, a, function () { return this; }); var d = Object.getPrototypeOf, v = d && d(d(values([]))); v && v !== r && n.call(v, a) && (p = v); var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p); function defineIteratorMethods(t) { ["next", "throw", "return"].forEach(function (e) { define(t, e, function (t) { return this._invoke(e, t); }); }); } function AsyncIterator(t, e) { function invoke(r, o, i, a) { var c = tryCatch(t[r], t, o); if ("throw" !== c.type) { var u = c.arg, h = u.value; return h && "object" == _typeof(h) && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) { invoke("next", t, i, a); }, function (t) { invoke("throw", t, i, a); }) : e.resolve(h).then(function (t) { u.value = t, i(u); }, function (t) { return invoke("throw", t, i, a); }); } a(c.arg); } var r; o(this, "_invoke", { value: function value(t, n) { function callInvokeWithMethodAndArg() { return new e(function (e, r) { invoke(t, n, e, r); }); } return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(e, r, n) { var o = h; return function (i, a) { if (o === f) throw Error("Generator is already running"); if (o === s) { if ("throw" === i) throw a; return { value: t, done: !0 }; } for (n.method = i, n.arg = a;;) { var c = n.delegate; if (c) { var u = maybeInvokeDelegate(c, n); if (u) { if (u === y) continue; return u; } } if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) { if (o === h) throw o = s, n.arg; n.dispatchException(n.arg); } else "return" === n.method && n.abrupt("return", n.arg); o = f; var p = tryCatch(e, r, n); if ("normal" === p.type) { if (o = n.done ? s : l, p.arg === y) continue; return { value: p.arg, done: n.done }; } "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg); } }; } function maybeInvokeDelegate(e, r) { var n = r.method, o = e.iterator[n]; if (o === t) return r.delegate = null, "throw" === n && e.iterator["return"] && (r.method = "return", r.arg = t, maybeInvokeDelegate(e, r), "throw" === r.method) || "return" !== n && (r.method = "throw", r.arg = new TypeError("The iterator does not provide a '" + n + "' method")), y; var i = tryCatch(o, e.iterator, r.arg); if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y; var a = i.arg; return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, "return" !== r.method && (r.method = "next", r.arg = t), r.delegate = null, y) : a : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, y); } function pushTryEntry(t) { var e = { tryLoc: t[0] }; 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e); } function resetTryEntry(t) { var e = t.completion || {}; e.type = "normal", delete e.arg, t.completion = e; } function Context(t) { this.tryEntries = [{ tryLoc: "root" }], t.forEach(pushTryEntry, this), this.reset(!0); } function values(e) { if (e || "" === e) { var r = e[a]; if (r) return r.call(e); if ("function" == typeof e.next) return e; if (!isNaN(e.length)) { var o = -1, i = function next() { for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next; return next.value = t, next.done = !0, next; }; return i.next = i; } } throw new TypeError(_typeof(e) + " is not iterable"); } return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), o(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) { var e = "function" == typeof t && t.constructor; return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name)); }, e.mark = function (t) { return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t; }, e.awrap = function (t) { return { __await: t }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () { return this; }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) { void 0 === i && (i = Promise); var a = new AsyncIterator(wrap(t, r, n, o), i); return e.isGeneratorFunction(r) ? a : a.next().then(function (t) { return t.done ? t.value : a.next(); }); }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () { return this; }), define(g, "toString", function () { return "[object Generator]"; }), e.keys = function (t) { var e = Object(t), r = []; for (var n in e) r.push(n); return r.reverse(), function next() { for (; r.length;) { var t = r.pop(); if (t in e) return next.value = t, next.done = !1, next; } return next.done = !0, next; }; }, e.values = values, Context.prototype = { constructor: Context, reset: function reset(e) { if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) "t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t); }, stop: function stop() { this.done = !0; var t = this.tryEntries[0].completion; if ("throw" === t.type) throw t.arg; return this.rval; }, dispatchException: function dispatchException(e) { if (this.done) throw e; var r = this; function handle(n, o) { return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o; } for (var o = this.tryEntries.length - 1; o >= 0; --o) { var i = this.tryEntries[o], a = i.completion; if ("root" === i.tryLoc) return handle("end"); if (i.tryLoc <= this.prev) { var c = n.call(i, "catchLoc"), u = n.call(i, "finallyLoc"); if (c && u) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } else if (c) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); } else { if (!u) throw Error("try statement without catch or finally"); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } } } }, abrupt: function abrupt(t, e) { for (var r = this.tryEntries.length - 1; r >= 0; --r) { var o = this.tryEntries[r]; if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) { var i = o; break; } } i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null); var a = i ? i.completion : {}; return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a); }, complete: function complete(t, e) { if ("throw" === t.type) throw t.arg; return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), y; }, finish: function finish(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y; } }, "catch": function _catch(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.tryLoc === t) { var n = r.completion; if ("throw" === n.type) { var o = n.arg; resetTryEntry(r); } return o; } } throw Error("illegal catch attempt"); }, delegateYield: function delegateYield(e, r, n) { return this.delegate = { iterator: values(e), resultName: r, nextLoc: n }, "next" === this.method && (this.arg = t), y; } }, e; }
16
16
  function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
17
- function asyncGeneratorStep(n, t, e, r, o, a, c) { try { var i = n[a](c), u = i.value; } catch (n) { return void e(n); } i.done ? t(u) : Promise.resolve(u).then(r, o); }
18
- function _asyncToGenerator(n) { return function () { var t = this, e = arguments; return new Promise(function (r, o) { var a = n.apply(t, e); function _next(n) { asyncGeneratorStep(a, r, o, _next, _throw, "next", n); } function _throw(n) { asyncGeneratorStep(a, r, o, _next, _throw, "throw", n); } _next(void 0); }); }; }
19
17
  function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
20
18
  function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
21
19
  function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
@@ -82,7 +80,7 @@ function base64urlToBase64(str) {
82
80
  * @param {Object} commitment - The commitment object containing signature
83
81
  * @returns {string} The commitment ID in base64url format
84
82
  */
85
- function generateRsaCommitmentId(commitment) {
83
+ function rsaid(commitment) {
86
84
  // Extract the base64 signature from structured field format
87
85
  // Format: "signature-name=:BASE64_SIGNATURE:"
88
86
  var match = commitment.signature.match(/^[^=]+=:([^:]+):/);
@@ -111,7 +109,7 @@ function generateRsaCommitmentId(commitment) {
111
109
  * @param {Object} message - The message with signature and signature-input
112
110
  * @returns {string} The commitment ID in base64url format
113
111
  */
114
- function generateHmacCommitmentId(message) {
112
+ function hmacid(message) {
115
113
  // Parse signature-input to get components
116
114
  var parsed = parseStructuredFieldDictionary(message["signature-input"]);
117
115
  if (!parsed || !parsed.components) {
@@ -168,12 +166,12 @@ function generateCommitmentId(commitment) {
168
166
  switch (commitment.alg) {
169
167
  case "rsa-pss-sha512":
170
168
  case "ecdsa-p256-sha256":
171
- return generateRsaCommitmentId(commitment);
169
+ return rsaid(commitment);
172
170
  case "hmac-sha256":
173
171
  if (!fullMessage) {
174
172
  throw new Error("HMAC commitment IDs require full message context");
175
173
  }
176
- return generateHmacCommitmentId(fullMessage);
174
+ return hmacid(fullMessage);
177
175
  default:
178
176
  throw new Error("Unsupported algorithm: ".concat(commitment.alg));
179
177
  }
@@ -252,177 +250,221 @@ function parseSignatureInput(sigInput) {
252
250
  /**
253
251
  * Calculate HMAC commitment ID for HyperBEAM messages
254
252
  */
255
- function calculateHmacId(_x) {
256
- return _calculateHmacId.apply(this, arguments);
253
+ function calculateHmacId(message) {
254
+ if (!message["signature-input"]) {
255
+ throw new Error("HMAC calculation requires signature-input");
256
+ }
257
+
258
+ // Parse components from signature-input
259
+ var components = parseSignatureInput(message["signature-input"]);
260
+
261
+ // Sort components AS-IS (with @ prefix)
262
+ var sortedComponents = _toConsumableArray(components).sort();
263
+
264
+ // Build signature base in sorted order
265
+ var lines = [];
266
+ var _iterator = _createForOfIteratorHelper(sortedComponents),
267
+ _step;
268
+ try {
269
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
270
+ var component = _step.value;
271
+ var fieldName = component;
272
+ var value = void 0;
273
+
274
+ // For derived components (starting with @), remove @ in the signature base
275
+ if (component.startsWith("@")) {
276
+ fieldName = component.substring(1);
277
+ value = message[fieldName];
278
+ } else {
279
+ value = message[component];
280
+ }
281
+ if (value === undefined || value === null) {
282
+ value = "";
283
+ } else if (typeof value === "number") {
284
+ value = value.toString();
285
+ }
286
+ lines.push("\"".concat(fieldName, "\": ").concat(value));
287
+ }
288
+
289
+ // Add signature-params line with sorted components (keeping @ prefix)
290
+ } catch (err) {
291
+ _iterator.e(err);
292
+ } finally {
293
+ _iterator.f();
294
+ }
295
+ var paramsComponents = sortedComponents.join(" ");
296
+ lines.push("\"@signature-params\": (".concat(paramsComponents, ");alg=\"hmac-sha256\";keyid=\"ao\""));
297
+ var signatureBase = lines.join("\n");
298
+
299
+ // Generate HMAC with key "ao"
300
+ var messageBytes = new TextEncoder().encode(signatureBase);
301
+ var keyBytes = new TextEncoder().encode("ao");
302
+ var hmacResult = (0, _fastSha.hmac)(keyBytes, messageBytes);
303
+ return uint8ArrayToBase64url(hmacResult);
257
304
  }
305
+
258
306
  /**
259
307
  * Calculate unsigned message ID following the exact Erlang flow
260
308
  */
261
- function _calculateHmacId() {
262
- _calculateHmacId = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee(message) {
263
- var components, sortedComponents, lines, _iterator, _step, component, fieldName, value, paramsComponents, signatureBase, messageBytes, keyBytes, hmacResult;
264
- return _regeneratorRuntime().wrap(function _callee$(_context) {
265
- while (1) switch (_context.prev = _context.next) {
266
- case 0:
267
- if (message["signature-input"]) {
268
- _context.next = 2;
269
- break;
270
- }
271
- throw new Error("HMAC calculation requires signature-input");
272
- case 2:
273
- // Parse components from signature-input
274
- components = parseSignatureInput(message["signature-input"]); // Sort components AS-IS (with @ prefix)
275
- sortedComponents = _toConsumableArray(components).sort(); // Build signature base in sorted order
276
- lines = [];
277
- _iterator = _createForOfIteratorHelper(sortedComponents);
278
- try {
279
- for (_iterator.s(); !(_step = _iterator.n()).done;) {
280
- component = _step.value;
281
- fieldName = component;
282
- value = void 0; // For derived components (starting with @), remove @ in the signature base
283
- if (component.startsWith("@")) {
284
- fieldName = component.substring(1);
285
- value = message[fieldName];
286
- } else {
287
- value = message[component];
288
- }
289
- if (value === undefined || value === null) {
290
- value = "";
291
- } else if (typeof value === "number") {
292
- value = value.toString();
293
- }
294
- lines.push("\"".concat(fieldName, "\": ").concat(value));
295
- }
296
-
297
- // Add signature-params line with sorted components (keeping @ prefix)
298
- } catch (err) {
299
- _iterator.e(err);
300
- } finally {
301
- _iterator.f();
302
- }
303
- paramsComponents = sortedComponents.join(" ");
304
- lines.push("\"@signature-params\": (".concat(paramsComponents, ");alg=\"hmac-sha256\";keyid=\"ao\""));
305
- signatureBase = lines.join("\n"); // Generate HMAC with key "ao"
306
- messageBytes = new TextEncoder().encode(signatureBase);
307
- keyBytes = new TextEncoder().encode("ao");
308
- _context.next = 14;
309
- return (0, _fastSha.hmac)(keyBytes, messageBytes);
310
- case 14:
311
- hmacResult = _context.sent;
312
- return _context.abrupt("return", uint8ArrayToBase64url(hmacResult));
313
- case 16:
314
- case "end":
315
- return _context.stop();
316
- }
317
- }, _callee);
318
- }));
319
- return _calculateHmacId.apply(this, arguments);
309
+ function calculateUnsignedId(message) {
310
+ // Derived components from Erlang ?DERIVED_COMPONENTS
311
+ var DERIVED_COMPONENTS = ["method", "target-uri", "authority", "scheme", "request-target", "path", "query", "query-param", "status"];
312
+
313
+ // Convert message for httpsig format
314
+ var httpsigMsg = {};
315
+ for (var _i2 = 0, _Object$entries2 = Object.entries(message); _i2 < _Object$entries2.length; _i2++) {
316
+ var _Object$entries2$_i = _slicedToArray(_Object$entries2[_i2], 2),
317
+ key = _Object$entries2$_i[0],
318
+ value = _Object$entries2$_i[1];
319
+ httpsigMsg[key.toLowerCase()] = value;
320
+ }
321
+
322
+ // Get keys and add @ to derived components
323
+ var keys = Object.keys(httpsigMsg);
324
+ var componentsWithPrefix = keys.map(function (key) {
325
+ // Check if this is a derived component
326
+ if (DERIVED_COMPONENTS.includes(key.replace(/_/g, "-"))) {
327
+ return "@" + key;
328
+ }
329
+ return key;
330
+ }).sort(); // Sort AFTER adding @ prefix
331
+
332
+ // Build signature base - use the components in order
333
+ var lines = [];
334
+ var _iterator2 = _createForOfIteratorHelper(componentsWithPrefix),
335
+ _step2;
336
+ try {
337
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
338
+ var component = _step2.value;
339
+ var _key = component.replace("@", "");
340
+ var _value = httpsigMsg[_key];
341
+ var valueStr = typeof _value === "string" ? _value : String(_value);
342
+ lines.push("\"".concat(_key, "\": ").concat(valueStr));
343
+ }
344
+
345
+ // Add signature-params line with the @ prefixes
346
+ } catch (err) {
347
+ _iterator2.e(err);
348
+ } finally {
349
+ _iterator2.f();
350
+ }
351
+ var componentsList = componentsWithPrefix.map(function (k) {
352
+ return "\"".concat(k, "\"");
353
+ }).join(" ");
354
+ lines.push("\"@signature-params\": (".concat(componentsList, ");alg=\"hmac-sha256\";keyid=\"ao\""));
355
+ var signatureBase = lines.join("\n");
356
+
357
+ // HMAC with key "ao"
358
+ var messageBytes = new TextEncoder().encode(signatureBase);
359
+ var keyBytes = new TextEncoder().encode("ao");
360
+ var hmacResult = (0, _fastSha.hmac)(keyBytes, messageBytes);
361
+ return uint8ArrayToBase64url(hmacResult);
320
362
  }
321
- function calculateUnsignedId(_x2) {
322
- return _calculateUnsignedId.apply(this, arguments);
363
+ function id(message) {
364
+ // Get commitment IDs
365
+ var commitmentIds = Object.keys(message.commitments || {});
366
+ if (commitmentIds.length === 0) {
367
+ // No commitments - calculate unsigned ID using HMAC
368
+ return calculateUnsignedId(message);
369
+ } else if (commitmentIds.length === 1) {
370
+ // Single commitment - the ID is just the commitment ID
371
+ return commitmentIds[0];
372
+ } else {
373
+ // Multiple commitments - sort, join with ", ", and hash
374
+ var sortedIds = commitmentIds.sort();
375
+ var idsLine = sortedIds.join(", ");
376
+
377
+ // Calculate SHA-256 hash using fast-sha256
378
+ var encoder = new TextEncoder();
379
+ var data = encoder.encode(idsLine);
380
+ var hashArray = (0, _fastSha.hash)(data);
381
+
382
+ // Convert to base64url
383
+ return uint8ArrayToBase64url(hashArray);
384
+ }
323
385
  }
324
- function _calculateUnsignedId() {
325
- _calculateUnsignedId = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee2(message) {
326
- var DERIVED_COMPONENTS, httpsigMsg, _i2, _Object$entries2, _Object$entries2$_i, key, value, keys, componentsWithPrefix, lines, _iterator2, _step2, component, _key, _value, valueStr, componentsList, signatureBase, messageBytes, keyBytes, hmacResult;
327
- return _regeneratorRuntime().wrap(function _callee2$(_context2) {
328
- while (1) switch (_context2.prev = _context2.next) {
329
- case 0:
330
- // Derived components from Erlang ?DERIVED_COMPONENTS
331
- DERIVED_COMPONENTS = ["method", "target-uri", "authority", "scheme", "request-target", "path", "query", "query-param", "status"]; // Convert message for httpsig format
332
- httpsigMsg = {};
333
- for (_i2 = 0, _Object$entries2 = Object.entries(message); _i2 < _Object$entries2.length; _i2++) {
334
- _Object$entries2$_i = _slicedToArray(_Object$entries2[_i2], 2), key = _Object$entries2$_i[0], value = _Object$entries2$_i[1];
335
- httpsigMsg[key.toLowerCase()] = value;
336
- }
337
-
338
- // Get keys and add @ to derived components
339
- keys = Object.keys(httpsigMsg);
340
- componentsWithPrefix = keys.map(function (key) {
341
- // Check if this is a derived component
342
- if (DERIVED_COMPONENTS.includes(key.replace(/_/g, "-"))) {
343
- return "@" + key;
344
- }
345
- return key;
346
- }).sort(); // Sort AFTER adding @ prefix
347
- // Build signature base - use the components in order
348
- lines = [];
349
- _iterator2 = _createForOfIteratorHelper(componentsWithPrefix);
350
- try {
351
- for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
352
- component = _step2.value;
353
- _key = component.replace("@", "");
354
- _value = httpsigMsg[_key];
355
- valueStr = typeof _value === "string" ? _value : String(_value);
356
- lines.push("\"".concat(_key, "\": ").concat(valueStr));
357
- }
358
-
359
- // Add signature-params line with the @ prefixes
360
- } catch (err) {
361
- _iterator2.e(err);
362
- } finally {
363
- _iterator2.f();
364
- }
365
- componentsList = componentsWithPrefix.map(function (k) {
366
- return "\"".concat(k, "\"");
367
- }).join(" ");
368
- lines.push("\"@signature-params\": (".concat(componentsList, ");alg=\"hmac-sha256\";keyid=\"ao\""));
369
- signatureBase = lines.join("\n"); // HMAC with key "ao"
370
- messageBytes = new TextEncoder().encode(signatureBase);
371
- keyBytes = new TextEncoder().encode("ao");
372
- _context2.next = 15;
373
- return (0, _fastSha.hmac)(keyBytes, messageBytes);
374
- case 15:
375
- hmacResult = _context2.sent;
376
- return _context2.abrupt("return", uint8ArrayToBase64url(hmacResult));
377
- case 17:
378
- case "end":
379
- return _context2.stop();
380
- }
381
- }, _callee2);
382
- }));
383
- return _calculateUnsignedId.apply(this, arguments);
386
+ // Export all functions
387
+
388
+ /**
389
+ * Calculate the next base from a hashpath
390
+ * A hashpath has the format: base/request
391
+ * The next base is calculated as: sha256(base + request)
392
+ *
393
+ * @param {string} hashpath - The current hashpath in format "base/request"
394
+ * @returns {string} The next base in base64url format
395
+ */
396
+ function base(hashpath) {
397
+ // Split the hashpath into base and request
398
+ var parts = hashpath.split("/");
399
+ if (parts.length !== 2) {
400
+ throw new Error("Invalid hashpath format. Expected 'base/request'");
401
+ }
402
+ var _parts = _slicedToArray(parts, 2),
403
+ base = _parts[0],
404
+ request = _parts[1];
405
+
406
+ // Convert base64url to native binary (Uint8Array)
407
+ var baseBinary = base64urlToUint8Array(base);
408
+ var requestBinary = base64urlToUint8Array(request);
409
+
410
+ // Concatenate base and request
411
+ var combined = new Uint8Array(baseBinary.length + requestBinary.length);
412
+ combined.set(baseBinary, 0);
413
+ combined.set(requestBinary, baseBinary.length);
414
+
415
+ // Calculate SHA256 of the combined data
416
+ var nextBaseHash = (0, _fastSha.hash)(combined);
417
+
418
+ // Convert to base64url
419
+ return uint8ArrayToBase64url(nextBaseHash);
384
420
  }
385
- function id(_x3) {
386
- return _id2.apply(this, arguments);
387
- } // Export all functions
388
- function _id2() {
389
- _id2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee3(message) {
390
- var commitmentIds, sortedIds, idsLine, encoder, data, hashBuffer, hashArray, base64, base64url;
391
- return _regeneratorRuntime().wrap(function _callee3$(_context3) {
392
- while (1) switch (_context3.prev = _context3.next) {
393
- case 0:
394
- // Get commitment IDs
395
- commitmentIds = Object.keys(message.commitments || {});
396
- if (!(commitmentIds.length === 0)) {
397
- _context3.next = 5;
398
- break;
399
- }
400
- return _context3.abrupt("return", calculateUnsignedId(message));
401
- case 5:
402
- if (!(commitmentIds.length === 1)) {
403
- _context3.next = 9;
404
- break;
405
- }
406
- return _context3.abrupt("return", commitmentIds[0]);
407
- case 9:
408
- // Multiple commitments - sort, join with ", ", and hash
409
- sortedIds = commitmentIds.sort();
410
- idsLine = sortedIds.join(", "); // Calculate SHA-256 hash
411
- encoder = new TextEncoder();
412
- data = encoder.encode(idsLine);
413
- _context3.next = 15;
414
- return crypto.subtle.digest("SHA-256", data);
415
- case 15:
416
- hashBuffer = _context3.sent;
417
- hashArray = new Uint8Array(hashBuffer); // Convert to base64url
418
- base64 = btoa(String.fromCharCode.apply(String, _toConsumableArray(hashArray)));
419
- base64url = base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
420
- return _context3.abrupt("return", base64url);
421
- case 20:
422
- case "end":
423
- return _context3.stop();
424
- }
425
- }, _callee3);
426
- }));
427
- return _id2.apply(this, arguments);
428
- }
421
+
422
+ /**
423
+ * Calculate the next hashpath given the current hashpath and a new message
424
+ *
425
+ * @param {string} currentHashpath - The current hashpath (or null for first operation)
426
+ * @param {Object} newMessage - The new message/request
427
+ * @returns {string} The next hashpath in format "nextBase/newMessageId"
428
+ */
429
+ function hashpath(currentHashpath, newMessage) {
430
+ // Calculate the ID of the new message
431
+ var newMessageId = id(newMessage);
432
+ if (!currentHashpath) {
433
+ // First operation: the hashpath is just the message ID
434
+ // In the Erlang code, the first hashpath is "baseId/requestId"
435
+ // where baseId is the ID of the initial message
436
+ throw new Error("For first operation, provide the base message ID as currentHashpath");
437
+ }
438
+
439
+ // Check if this is the first operation (currentHashpath is just an ID, not a path)
440
+ if (!currentHashpath.includes("/")) {
441
+ // First operation: currentHashpath is the base message ID
442
+ return "".concat(currentHashpath, "/").concat(newMessageId);
443
+ }
444
+
445
+ // Subsequent operations: calculate the next base from current hashpath
446
+ var nextBase = base(currentHashpath);
447
+
448
+ // Return the new hashpath
449
+ return "".concat(nextBase, "/").concat(newMessageId);
450
+ }
451
+
452
+ /**
453
+ * Helper function to convert base64url string to Uint8Array
454
+ */
455
+ function base64urlToUint8Array(base64url) {
456
+ // Convert base64url to base64
457
+ var base64 = base64urlToBase64(base64url);
458
+
459
+ // Decode base64 to binary string
460
+ var binaryString = atob(base64);
461
+
462
+ // Convert binary string to Uint8Array
463
+ var bytes = new Uint8Array(binaryString.length);
464
+ for (var i = 0; i < binaryString.length; i++) {
465
+ bytes[i] = binaryString.charCodeAt(i);
466
+ }
467
+ return bytes;
468
+ }
469
+
470
+ // Export the new functions
package/cjs/utils.js CHANGED
@@ -3,11 +3,24 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.getTagVal = exports.getTag = exports.dirname = exports.checkTag = exports.buildTags = exports.allChecked = exports.action = void 0;
6
+ exports.allChecked = exports.action = void 0;
7
+ Object.defineProperty(exports, "base", {
8
+ enumerable: true,
9
+ get: function get() {
10
+ return _id.base;
11
+ }
12
+ });
13
+ exports.getTagVal = exports.getTag = exports.dirname = exports.checkTag = exports.buildTags = void 0;
14
+ Object.defineProperty(exports, "hashpath", {
15
+ enumerable: true,
16
+ get: function get() {
17
+ return _id.hashpath;
18
+ }
19
+ });
7
20
  Object.defineProperty(exports, "hmacid", {
8
21
  enumerable: true,
9
22
  get: function get() {
10
- return _id.generateHmacCommitmentId;
23
+ return _id.hmacid;
11
24
  }
12
25
  });
13
26
  Object.defineProperty(exports, "id", {
@@ -23,7 +36,7 @@ exports.parseSignatureInput = parseSignatureInput;
23
36
  Object.defineProperty(exports, "rsaid", {
24
37
  enumerable: true,
25
38
  get: function get() {
26
- return _id.generateRsaCommitmentId;
39
+ return _id.rsaid;
27
40
  }
28
41
  });
29
42
  exports.tags = exports.tagEq = exports.tag = exports.srcs = exports.searchTag = void 0;
package/esm/id.js CHANGED
@@ -47,7 +47,7 @@ function base64urlToBase64(str) {
47
47
  * @param {Object} commitment - The commitment object containing signature
48
48
  * @returns {string} The commitment ID in base64url format
49
49
  */
50
- function generateRsaCommitmentId(commitment) {
50
+ function rsaid(commitment) {
51
51
  // Extract the base64 signature from structured field format
52
52
  // Format: "signature-name=:BASE64_SIGNATURE:"
53
53
  const match = commitment.signature.match(/^[^=]+=:([^:]+):/)
@@ -78,7 +78,7 @@ function generateRsaCommitmentId(commitment) {
78
78
  * @param {Object} message - The message with signature and signature-input
79
79
  * @returns {string} The commitment ID in base64url format
80
80
  */
81
- function generateHmacCommitmentId(message) {
81
+ function hmacid(message) {
82
82
  // Parse signature-input to get components
83
83
  const parsed = parseStructuredFieldDictionary(message["signature-input"])
84
84
  if (!parsed || !parsed.components) {
@@ -141,13 +141,13 @@ function generateCommitmentId(commitment, fullMessage = null) {
141
141
  switch (commitment.alg) {
142
142
  case "rsa-pss-sha512":
143
143
  case "ecdsa-p256-sha256":
144
- return generateRsaCommitmentId(commitment)
144
+ return rsaid(commitment)
145
145
 
146
146
  case "hmac-sha256":
147
147
  if (!fullMessage) {
148
148
  throw new Error("HMAC commitment IDs require full message context")
149
149
  }
150
- return generateHmacCommitmentId(fullMessage)
150
+ return hmacid(fullMessage)
151
151
 
152
152
  default:
153
153
  throw new Error(`Unsupported algorithm: ${commitment.alg}`)
@@ -224,7 +224,7 @@ function parseSignatureInput(sigInput) {
224
224
  /**
225
225
  * Calculate HMAC commitment ID for HyperBEAM messages
226
226
  */
227
- async function calculateHmacId(message) {
227
+ function calculateHmacId(message) {
228
228
  if (!message["signature-input"]) {
229
229
  throw new Error("HMAC calculation requires signature-input")
230
230
  }
@@ -271,14 +271,14 @@ async function calculateHmacId(message) {
271
271
  const messageBytes = new TextEncoder().encode(signatureBase)
272
272
  const keyBytes = new TextEncoder().encode("ao")
273
273
 
274
- const hmacResult = await hmac(keyBytes, messageBytes)
274
+ const hmacResult = hmac(keyBytes, messageBytes)
275
275
  return uint8ArrayToBase64url(hmacResult)
276
276
  }
277
277
 
278
278
  /**
279
279
  * Calculate unsigned message ID following the exact Erlang flow
280
280
  */
281
- async function calculateUnsignedId(message) {
281
+ function calculateUnsignedId(message) {
282
282
  // Derived components from Erlang ?DERIVED_COMPONENTS
283
283
  const DERIVED_COMPONENTS = [
284
284
  "method",
@@ -331,11 +331,11 @@ async function calculateUnsignedId(message) {
331
331
  const messageBytes = new TextEncoder().encode(signatureBase)
332
332
  const keyBytes = new TextEncoder().encode("ao")
333
333
 
334
- const hmacResult = await hmac(keyBytes, messageBytes)
334
+ const hmacResult = hmac(keyBytes, messageBytes)
335
335
  return uint8ArrayToBase64url(hmacResult)
336
336
  }
337
337
 
338
- async function id(message) {
338
+ function id(message) {
339
339
  // Get commitment IDs
340
340
  const commitmentIds = Object.keys(message.commitments || {})
341
341
 
@@ -350,30 +350,110 @@ async function id(message) {
350
350
  const sortedIds = commitmentIds.sort()
351
351
  const idsLine = sortedIds.join(", ")
352
352
 
353
- // Calculate SHA-256 hash
353
+ // Calculate SHA-256 hash using fast-sha256
354
354
  const encoder = new TextEncoder()
355
355
  const data = encoder.encode(idsLine)
356
- const hashBuffer = await crypto.subtle.digest("SHA-256", data)
357
- const hashArray = new Uint8Array(hashBuffer)
356
+ const hashArray = hash(data)
358
357
 
359
358
  // Convert to base64url
360
- const base64 = btoa(String.fromCharCode(...hashArray))
361
- const base64url = base64
362
- .replace(/\+/g, "-")
363
- .replace(/\//g, "_")
364
- .replace(/=/g, "")
365
-
366
- return base64url
359
+ return uint8ArrayToBase64url(hashArray)
367
360
  }
368
361
  }
369
-
370
362
  // Export all functions
371
363
  export {
372
364
  id,
373
365
  generateCommitmentId,
374
- generateRsaCommitmentId,
375
- generateHmacCommitmentId,
366
+ rsaid,
367
+ hmacid,
376
368
  extractCommitmentIds,
377
369
  verifyCommitmentId,
378
370
  parseStructuredFieldDictionary,
379
371
  }
372
+
373
+ /**
374
+ * Calculate the next base from a hashpath
375
+ * A hashpath has the format: base/request
376
+ * The next base is calculated as: sha256(base + request)
377
+ *
378
+ * @param {string} hashpath - The current hashpath in format "base/request"
379
+ * @returns {string} The next base in base64url format
380
+ */
381
+ function base(hashpath) {
382
+ // Split the hashpath into base and request
383
+ const parts = hashpath.split("/")
384
+ if (parts.length !== 2) {
385
+ throw new Error("Invalid hashpath format. Expected 'base/request'")
386
+ }
387
+
388
+ const [base, request] = parts
389
+
390
+ // Convert base64url to native binary (Uint8Array)
391
+ const baseBinary = base64urlToUint8Array(base)
392
+ const requestBinary = base64urlToUint8Array(request)
393
+
394
+ // Concatenate base and request
395
+ const combined = new Uint8Array(baseBinary.length + requestBinary.length)
396
+ combined.set(baseBinary, 0)
397
+ combined.set(requestBinary, baseBinary.length)
398
+
399
+ // Calculate SHA256 of the combined data
400
+ const nextBaseHash = hash(combined)
401
+
402
+ // Convert to base64url
403
+ return uint8ArrayToBase64url(nextBaseHash)
404
+ }
405
+
406
+ /**
407
+ * Calculate the next hashpath given the current hashpath and a new message
408
+ *
409
+ * @param {string} currentHashpath - The current hashpath (or null for first operation)
410
+ * @param {Object} newMessage - The new message/request
411
+ * @returns {string} The next hashpath in format "nextBase/newMessageId"
412
+ */
413
+ function hashpath(currentHashpath, newMessage) {
414
+ // Calculate the ID of the new message
415
+ const newMessageId = id(newMessage)
416
+
417
+ if (!currentHashpath) {
418
+ // First operation: the hashpath is just the message ID
419
+ // In the Erlang code, the first hashpath is "baseId/requestId"
420
+ // where baseId is the ID of the initial message
421
+ throw new Error(
422
+ "For first operation, provide the base message ID as currentHashpath"
423
+ )
424
+ }
425
+
426
+ // Check if this is the first operation (currentHashpath is just an ID, not a path)
427
+ if (!currentHashpath.includes("/")) {
428
+ // First operation: currentHashpath is the base message ID
429
+ return `${currentHashpath}/${newMessageId}`
430
+ }
431
+
432
+ // Subsequent operations: calculate the next base from current hashpath
433
+ const nextBase = base(currentHashpath)
434
+
435
+ // Return the new hashpath
436
+ return `${nextBase}/${newMessageId}`
437
+ }
438
+
439
+ /**
440
+ * Helper function to convert base64url string to Uint8Array
441
+ */
442
+ function base64urlToUint8Array(base64url) {
443
+ // Convert base64url to base64
444
+ const base64 = base64urlToBase64(base64url)
445
+
446
+ // Decode base64 to binary string
447
+ const binaryString = atob(base64)
448
+
449
+ // Convert binary string to Uint8Array
450
+ const bytes = new Uint8Array(binaryString.length)
451
+ for (let i = 0; i < binaryString.length; i++) {
452
+ bytes[i] = binaryString.charCodeAt(i)
453
+ }
454
+
455
+ return bytes
456
+ }
457
+
458
+ // Export the new functions
459
+ export { base, hashpath }
package/esm/utils.js CHANGED
@@ -1,13 +1,6 @@
1
1
  import { graphql, parse, validate, buildSchema } from "graphql"
2
2
  import sha256 from "fast-sha256"
3
- import {
4
- id,
5
- generateCommitmentId,
6
- generateRsaCommitmentId,
7
- generateHmacCommitmentId,
8
- verifyCommitmentId,
9
- } from "./id.js"
10
- export { generateRsaCommitmentId as rsaid, generateHmacCommitmentId as hmacid }
3
+ export { id, base, hashpath, rsaid, hmacid } from "./id.js"
11
4
  import {
12
5
  clone,
13
6
  is,
@@ -771,5 +764,4 @@ export {
771
764
  isJSON,
772
765
  dirname,
773
766
  toAddr,
774
- id,
775
767
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wao",
3
- "version": "0.30.0",
3
+ "version": "0.30.2",
4
4
  "bin": {
5
5
  "wao": "./cjs/cli.js",
6
6
  "wao-esm": "./esm/cli.js"