@bcts/hubert 1.0.0-alpha.18 → 1.0.0-alpha.19

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.
Files changed (78) hide show
  1. package/dist/{arid-derivation-1CJuU-kZ.cjs → arid-derivation-CNfUKUp-.cjs} +2 -2
  2. package/dist/{arid-derivation-1CJuU-kZ.cjs.map → arid-derivation-CNfUKUp-.cjs.map} +1 -1
  3. package/dist/bin/hubert.cjs +18 -20
  4. package/dist/bin/hubert.cjs.map +1 -1
  5. package/dist/bin/hubert.mjs +3 -5
  6. package/dist/bin/hubert.mjs.map +1 -1
  7. package/dist/{chunk-CbDLau6x.cjs → chunk-C0xms8kb.cjs} +1 -1
  8. package/dist/hybrid/index.cjs +14 -13
  9. package/dist/hybrid/index.d.cts +1 -1
  10. package/dist/hybrid/index.d.mts +2 -2
  11. package/dist/hybrid/index.mjs +2 -2
  12. package/dist/index.cjs +48 -45
  13. package/dist/index.d.cts +8 -4
  14. package/dist/index.d.cts.map +1 -1
  15. package/dist/index.d.mts +9 -5
  16. package/dist/index.d.mts.map +1 -1
  17. package/dist/index.mjs +7 -5
  18. package/dist/ipfs/index.cjs +3 -3
  19. package/dist/ipfs/index.d.cts +1 -1
  20. package/dist/ipfs/index.d.mts +2 -2
  21. package/dist/ipfs/index.mjs +0 -1
  22. package/dist/{kv-yjvQa_LH.cjs → kv-1qBQRbV5.cjs} +3 -3
  23. package/dist/{kv-yjvQa_LH.cjs.map → kv-1qBQRbV5.cjs.map} +1 -1
  24. package/dist/{index-T1LHanIb.d.mts → kv-BS5Z28iJ.d.mts} +2 -2
  25. package/dist/kv-BS5Z28iJ.d.mts.map +1 -0
  26. package/dist/{index-jyzuOhFB.d.cts → kv-BXu_sOvl.d.cts} +1 -1
  27. package/dist/kv-BXu_sOvl.d.cts.map +1 -0
  28. package/dist/{index-CV6lZJqY.d.cts → kv-BZB64lt0.d.cts} +1 -1
  29. package/dist/kv-BZB64lt0.d.cts.map +1 -0
  30. package/dist/{index-C2F6ugLL.d.mts → kv-BcjifWIY.d.mts} +2 -2
  31. package/dist/kv-BcjifWIY.d.mts.map +1 -0
  32. package/dist/{server-DVyk9gqU.mjs → kv-BhFoL8bc.mjs} +1 -1
  33. package/dist/kv-BhFoL8bc.mjs.map +1 -0
  34. package/dist/{kv-BAmhmMOo.cjs → kv-BmCAYeR7.cjs} +3 -3
  35. package/dist/{kv-BAmhmMOo.cjs.map → kv-BmCAYeR7.cjs.map} +1 -1
  36. package/dist/{index-CY3TCzIm.d.cts → kv-Bv__Pl2s.d.cts} +1 -1
  37. package/dist/kv-Bv__Pl2s.d.cts.map +1 -0
  38. package/dist/{index-BEzpUC7r.d.mts → kv-CVvMuP73.d.mts} +2 -2
  39. package/dist/kv-CVvMuP73.d.mts.map +1 -0
  40. package/dist/{hybrid-BZhumygj.mjs → kv-CmxPWVB1.mjs} +2 -2
  41. package/dist/kv-CmxPWVB1.mjs.map +1 -0
  42. package/dist/{index-DEr4SR1J.d.cts → kv-DPTr4DWU.d.cts} +1 -1
  43. package/dist/kv-DPTr4DWU.d.cts.map +1 -0
  44. package/dist/{kv-C-emxv0w.mjs → kv-DVYfnjvh.mjs} +1 -1
  45. package/dist/{kv-C-emxv0w.mjs.map → kv-DVYfnjvh.mjs.map} +1 -1
  46. package/dist/{hybrid-dX5JLumO.cjs → kv-DfzRmYtR.cjs} +4 -4
  47. package/dist/kv-DfzRmYtR.cjs.map +1 -0
  48. package/dist/{server-BBNRZ30D.cjs → kv-DmjKQe11.cjs} +2 -2
  49. package/dist/kv-DmjKQe11.cjs.map +1 -0
  50. package/dist/{index-CUnDouMb.d.mts → kv-akxfGRZi.d.mts} +2 -2
  51. package/dist/kv-akxfGRZi.d.mts.map +1 -0
  52. package/dist/{kv-store-DmngWWuw.d.mts → kv-store-nL8CboDh.d.mts} +1 -1
  53. package/dist/{kv-store-DmngWWuw.d.mts.map → kv-store-nL8CboDh.d.mts.map} +1 -1
  54. package/dist/mainline/index.cjs +3 -3
  55. package/dist/mainline/index.d.cts +1 -1
  56. package/dist/mainline/index.d.mts +2 -2
  57. package/dist/mainline/index.mjs +1 -2
  58. package/dist/server/index.cjs +14 -13
  59. package/dist/server/index.d.cts +2 -2
  60. package/dist/server/index.d.mts +3 -3
  61. package/dist/server/index.mjs +1 -1
  62. package/package.json +9 -9
  63. package/dist/hybrid-BZhumygj.mjs.map +0 -1
  64. package/dist/hybrid-dX5JLumO.cjs.map +0 -1
  65. package/dist/index-BEzpUC7r.d.mts.map +0 -1
  66. package/dist/index-C2F6ugLL.d.mts.map +0 -1
  67. package/dist/index-CUnDouMb.d.mts.map +0 -1
  68. package/dist/index-CV6lZJqY.d.cts.map +0 -1
  69. package/dist/index-CY3TCzIm.d.cts.map +0 -1
  70. package/dist/index-DEr4SR1J.d.cts.map +0 -1
  71. package/dist/index-T1LHanIb.d.mts.map +0 -1
  72. package/dist/index-jyzuOhFB.d.cts.map +0 -1
  73. package/dist/ipfs-BRMMCBjv.mjs +0 -1
  74. package/dist/ipfs-CetOVQcO.cjs +0 -0
  75. package/dist/mainline-D_jfeFMh.cjs +0 -0
  76. package/dist/mainline-cFIuXbo-.mjs +0 -1
  77. package/dist/server-BBNRZ30D.cjs.map +0 -1
  78. package/dist/server-DVyk9gqU.mjs.map +0 -1
@@ -1,4 +1,4 @@
1
- const require_chunk = require('./chunk-CbDLau6x.cjs');
1
+ const require_chunk = require('./chunk-C0xms8kb.cjs');
2
2
  let _bcts_crypto = require("@bcts/crypto");
3
3
  let _noble_ciphers_chacha_js = require("@noble/ciphers/chacha.js");
4
4
 
@@ -147,4 +147,4 @@ Object.defineProperty(exports, 'obfuscateWithArid', {
147
147
  return obfuscateWithArid;
148
148
  }
149
149
  });
150
- //# sourceMappingURL=arid-derivation-1CJuU-kZ.cjs.map
150
+ //# sourceMappingURL=arid-derivation-CNfUKUp-.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"arid-derivation-1CJuU-kZ.cjs","names":[],"sources":["../src/arid-derivation.ts"],"sourcesContent":["/**\n * ARID key derivation and obfuscation utilities.\n *\n * Port of arid_derivation.rs from hubert-rust.\n *\n * @module\n */\n\nimport { type ARID } from \"@bcts/components\";\nimport { hkdfHmacSha256 } from \"@bcts/crypto\";\nimport { chacha20 } from \"@noble/ciphers/chacha.js\";\n\n/**\n * Derive a deterministic key from an ARID using a specific salt.\n *\n * Uses HKDF to derive key material from the ARID, ensuring that:\n * - Same ARID always produces same key for a given salt\n * - Keys are cryptographically derived (not guessable)\n * - Collision resistance inherited from ARID\n * - No identifying information in the key (fully anonymized)\n *\n * Port of `derive_key()` from arid_derivation.rs lines 8-29.\n *\n * @param salt - Domain-specific salt to ensure different backends derive different keys\n * @param arid - The ARID to derive from\n * @param outputLen - Length of output in bytes (typically 20 or 32)\n * @returns Derived key bytes\n * @category ARID Derivation\n *\n * @example\n * ```typescript\n * const key = deriveKey(new TextEncoder().encode(\"my-salt\"), arid, 32);\n * ```\n */\nexport function deriveKey(salt: Uint8Array, arid: ARID, outputLen: number): Uint8Array {\n const aridBytes = arid.data();\n // Note: @bcts/crypto hkdfHmacSha256 takes (keyMaterial, salt, keyLen)\n // Rust bc-crypto takes (salt, ikm, keyLen)\n return hkdfHmacSha256(aridBytes, salt, outputLen);\n}\n\n/**\n * Salt for IPFS IPNS key derivation.\n * @internal\n */\nconst IPFS_KEY_NAME_SALT = new TextEncoder().encode(\"hubert-ipfs-ipns-v1\");\n\n/**\n * Salt for Mainline DHT key derivation.\n * @internal\n */\nconst MAINLINE_KEY_SALT = new TextEncoder().encode(\"hubert-mainline-dht-v1\");\n\n/**\n * Salt for obfuscation key derivation.\n * @internal\n */\nconst OBFUSCATION_SALT = new TextEncoder().encode(\"hubert-obfuscation-v1\");\n\n/**\n * Derive an IPNS key name from an ARID.\n *\n * Returns a 64-character hex string suitable for use as an IPFS key name.\n *\n * Port of `derive_ipfs_key_name()` from arid_derivation.rs lines 31-37.\n *\n * @param arid - The ARID to derive from\n * @returns 64-character hex string\n * @category ARID Derivation\n *\n * @example\n * ```typescript\n * const keyName = deriveIpfsKeyName(arid);\n * // => \"a1b2c3d4e5f6...\" (64 hex characters)\n * ```\n */\nexport function deriveIpfsKeyName(arid: ARID): string {\n const keyBytes = deriveKey(IPFS_KEY_NAME_SALT, arid, 32);\n return bytesToHex(keyBytes);\n}\n\n/**\n * Derive Mainline DHT key material from an ARID.\n *\n * Returns 20 bytes of key material (SHA-1 compatible length).\n *\n * Port of `derive_mainline_key()` from arid_derivation.rs lines 39-45.\n *\n * @param arid - The ARID to derive from\n * @returns 20 bytes of key material\n * @category ARID Derivation\n *\n * @example\n * ```typescript\n * const key = deriveMainlineKey(arid);\n * // => Uint8Array(20) [...]\n * ```\n */\nexport function deriveMainlineKey(arid: ARID): Uint8Array {\n return deriveKey(MAINLINE_KEY_SALT, arid, 20);\n}\n\n/**\n * Obfuscate or deobfuscate data using ChaCha20 with an ARID-derived key.\n *\n * This function uses ChaCha20 as a stream cipher to XOR the data with a\n * keystream derived from the ARID. Since XOR is symmetric, the same function\n * is used for both obfuscation and deobfuscation.\n *\n * The result appears as uniform random data to anyone who doesn't have the\n * ARID, hiding both the structure and content of the reference envelope.\n *\n * Port of `obfuscate_with_arid()` from arid_derivation.rs lines 47-91.\n *\n * @param arid - The ARID used to derive the obfuscation key\n * @param data - The data to obfuscate or deobfuscate\n * @returns The obfuscated (or deobfuscated) data\n * @category ARID Derivation\n *\n * @example\n * ```typescript\n * const obfuscated = obfuscateWithArid(arid, plaintext);\n * const deobfuscated = obfuscateWithArid(arid, obfuscated);\n * // deobfuscated === plaintext\n * ```\n */\nexport function obfuscateWithArid(arid: ARID, data: Uint8Array): Uint8Array {\n if (data.length === 0) {\n return new Uint8Array(0);\n }\n\n // Derive a 32-byte key from the ARID using HKDF with domain-specific salt\n const key = deriveKey(OBFUSCATION_SALT, arid, 32);\n\n // Derive IV from the key (last 12 bytes, reversed)\n // Match Rust: key.iter().rev().take(12).copied().collect()\n const iv = new Uint8Array(12);\n for (let i = 0; i < 12; i++) {\n iv[i] = key[31 - i];\n }\n\n // Use ChaCha20 to XOR the data\n // @noble/ciphers chacha20 takes (key, nonce, data) and returns encrypted data\n return chacha20(key, iv, data);\n}\n\n/**\n * Convert bytes to lowercase hex string.\n * @internal\n */\nfunction bytesToHex(bytes: Uint8Array): string {\n return Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAkCA,SAAgB,UAAU,MAAkB,MAAY,WAA+B;AAIrF,yCAHkB,KAAK,MAAM,EAGI,MAAM,UAAU;;;;;;AAOnD,MAAM,qBAAqB,IAAI,aAAa,CAAC,OAAO,sBAAsB;;;;;AAM1E,MAAM,oBAAoB,IAAI,aAAa,CAAC,OAAO,yBAAyB;;;;;AAM5E,MAAM,mBAAmB,IAAI,aAAa,CAAC,OAAO,wBAAwB;;;;;;;;;;;;;;;;;;AAmB1E,SAAgB,kBAAkB,MAAoB;AAEpD,QAAO,WADU,UAAU,oBAAoB,MAAM,GAAG,CAC7B;;;;;;;;;;;;;;;;;;;AAoB7B,SAAgB,kBAAkB,MAAwB;AACxD,QAAO,UAAU,mBAAmB,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;AA2B/C,SAAgB,kBAAkB,MAAY,MAA8B;AAC1E,KAAI,KAAK,WAAW,EAClB,QAAO,IAAI,WAAW,EAAE;CAI1B,MAAM,MAAM,UAAU,kBAAkB,MAAM,GAAG;CAIjD,MAAM,KAAK,IAAI,WAAW,GAAG;AAC7B,MAAK,IAAI,IAAI,GAAG,IAAI,IAAI,IACtB,IAAG,KAAK,IAAI,KAAK;AAKnB,+CAAgB,KAAK,IAAI,KAAK;;;;;;AAOhC,SAAS,WAAW,OAA2B;AAC7C,QAAO,MAAM,KAAK,MAAM,CACrB,KAAK,MAAM,EAAE,SAAS,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC,CAC3C,KAAK,GAAG"}
1
+ {"version":3,"file":"arid-derivation-CNfUKUp-.cjs","names":[],"sources":["../src/arid-derivation.ts"],"sourcesContent":["/**\n * ARID key derivation and obfuscation utilities.\n *\n * Port of arid_derivation.rs from hubert-rust.\n *\n * @module\n */\n\nimport { type ARID } from \"@bcts/components\";\nimport { hkdfHmacSha256 } from \"@bcts/crypto\";\nimport { chacha20 } from \"@noble/ciphers/chacha.js\";\n\n/**\n * Derive a deterministic key from an ARID using a specific salt.\n *\n * Uses HKDF to derive key material from the ARID, ensuring that:\n * - Same ARID always produces same key for a given salt\n * - Keys are cryptographically derived (not guessable)\n * - Collision resistance inherited from ARID\n * - No identifying information in the key (fully anonymized)\n *\n * Port of `derive_key()` from arid_derivation.rs lines 8-29.\n *\n * @param salt - Domain-specific salt to ensure different backends derive different keys\n * @param arid - The ARID to derive from\n * @param outputLen - Length of output in bytes (typically 20 or 32)\n * @returns Derived key bytes\n * @category ARID Derivation\n *\n * @example\n * ```typescript\n * const key = deriveKey(new TextEncoder().encode(\"my-salt\"), arid, 32);\n * ```\n */\nexport function deriveKey(salt: Uint8Array, arid: ARID, outputLen: number): Uint8Array {\n const aridBytes = arid.data();\n // Note: @bcts/crypto hkdfHmacSha256 takes (keyMaterial, salt, keyLen)\n // Rust bc-crypto takes (salt, ikm, keyLen)\n return hkdfHmacSha256(aridBytes, salt, outputLen);\n}\n\n/**\n * Salt for IPFS IPNS key derivation.\n * @internal\n */\nconst IPFS_KEY_NAME_SALT = new TextEncoder().encode(\"hubert-ipfs-ipns-v1\");\n\n/**\n * Salt for Mainline DHT key derivation.\n * @internal\n */\nconst MAINLINE_KEY_SALT = new TextEncoder().encode(\"hubert-mainline-dht-v1\");\n\n/**\n * Salt for obfuscation key derivation.\n * @internal\n */\nconst OBFUSCATION_SALT = new TextEncoder().encode(\"hubert-obfuscation-v1\");\n\n/**\n * Derive an IPNS key name from an ARID.\n *\n * Returns a 64-character hex string suitable for use as an IPFS key name.\n *\n * Port of `derive_ipfs_key_name()` from arid_derivation.rs lines 31-37.\n *\n * @param arid - The ARID to derive from\n * @returns 64-character hex string\n * @category ARID Derivation\n *\n * @example\n * ```typescript\n * const keyName = deriveIpfsKeyName(arid);\n * // => \"a1b2c3d4e5f6...\" (64 hex characters)\n * ```\n */\nexport function deriveIpfsKeyName(arid: ARID): string {\n const keyBytes = deriveKey(IPFS_KEY_NAME_SALT, arid, 32);\n return bytesToHex(keyBytes);\n}\n\n/**\n * Derive Mainline DHT key material from an ARID.\n *\n * Returns 20 bytes of key material (SHA-1 compatible length).\n *\n * Port of `derive_mainline_key()` from arid_derivation.rs lines 39-45.\n *\n * @param arid - The ARID to derive from\n * @returns 20 bytes of key material\n * @category ARID Derivation\n *\n * @example\n * ```typescript\n * const key = deriveMainlineKey(arid);\n * // => Uint8Array(20) [...]\n * ```\n */\nexport function deriveMainlineKey(arid: ARID): Uint8Array {\n return deriveKey(MAINLINE_KEY_SALT, arid, 20);\n}\n\n/**\n * Obfuscate or deobfuscate data using ChaCha20 with an ARID-derived key.\n *\n * This function uses ChaCha20 as a stream cipher to XOR the data with a\n * keystream derived from the ARID. Since XOR is symmetric, the same function\n * is used for both obfuscation and deobfuscation.\n *\n * The result appears as uniform random data to anyone who doesn't have the\n * ARID, hiding both the structure and content of the reference envelope.\n *\n * Port of `obfuscate_with_arid()` from arid_derivation.rs lines 47-91.\n *\n * @param arid - The ARID used to derive the obfuscation key\n * @param data - The data to obfuscate or deobfuscate\n * @returns The obfuscated (or deobfuscated) data\n * @category ARID Derivation\n *\n * @example\n * ```typescript\n * const obfuscated = obfuscateWithArid(arid, plaintext);\n * const deobfuscated = obfuscateWithArid(arid, obfuscated);\n * // deobfuscated === plaintext\n * ```\n */\nexport function obfuscateWithArid(arid: ARID, data: Uint8Array): Uint8Array {\n if (data.length === 0) {\n return new Uint8Array(0);\n }\n\n // Derive a 32-byte key from the ARID using HKDF with domain-specific salt\n const key = deriveKey(OBFUSCATION_SALT, arid, 32);\n\n // Derive IV from the key (last 12 bytes, reversed)\n // Match Rust: key.iter().rev().take(12).copied().collect()\n const iv = new Uint8Array(12);\n for (let i = 0; i < 12; i++) {\n iv[i] = key[31 - i];\n }\n\n // Use ChaCha20 to XOR the data\n // @noble/ciphers chacha20 takes (key, nonce, data) and returns encrypted data\n return chacha20(key, iv, data);\n}\n\n/**\n * Convert bytes to lowercase hex string.\n * @internal\n */\nfunction bytesToHex(bytes: Uint8Array): string {\n return Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAkCA,SAAgB,UAAU,MAAkB,MAAY,WAA+B;AAIrF,yCAHkB,KAAK,MAAM,EAGI,MAAM,UAAU;;;;;;AAOnD,MAAM,qBAAqB,IAAI,aAAa,CAAC,OAAO,sBAAsB;;;;;AAM1E,MAAM,oBAAoB,IAAI,aAAa,CAAC,OAAO,yBAAyB;;;;;AAM5E,MAAM,mBAAmB,IAAI,aAAa,CAAC,OAAO,wBAAwB;;;;;;;;;;;;;;;;;;AAmB1E,SAAgB,kBAAkB,MAAoB;AAEpD,QAAO,WADU,UAAU,oBAAoB,MAAM,GAAG,CAC7B;;;;;;;;;;;;;;;;;;;AAoB7B,SAAgB,kBAAkB,MAAwB;AACxD,QAAO,UAAU,mBAAmB,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;AA2B/C,SAAgB,kBAAkB,MAAY,MAA8B;AAC1E,KAAI,KAAK,WAAW,EAClB,QAAO,IAAI,WAAW,EAAE;CAI1B,MAAM,MAAM,UAAU,kBAAkB,MAAM,GAAG;CAIjD,MAAM,KAAK,IAAI,WAAW,GAAG;AAC7B,MAAK,IAAI,IAAI,GAAG,IAAI,IAAI,IACtB,IAAG,KAAK,IAAI,KAAK;AAKnB,+CAAgB,KAAK,IAAI,KAAK;;;;;;AAOhC,SAAS,WAAW,OAA2B;AAC7C,QAAO,MAAM,KAAK,MAAM,CACrB,KAAK,MAAM,EAAE,SAAS,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC,CAC3C,KAAK,GAAG"}
@@ -1,13 +1,11 @@
1
1
  #!/usr/bin/env node
2
- const require_chunk = require('../chunk-CbDLau6x.cjs');
2
+ const require_chunk = require('../chunk-C0xms8kb.cjs');
3
3
  const require_logging = require('../logging-qc9uMgil.cjs');
4
- require('../arid-derivation-1CJuU-kZ.cjs');
5
- const require_server = require('../server-BBNRZ30D.cjs');
6
- const require_kv = require('../kv-yjvQa_LH.cjs');
7
- require('../ipfs-CetOVQcO.cjs');
8
- const require_kv$1 = require('../kv-BAmhmMOo.cjs');
9
- require('../mainline-D_jfeFMh.cjs');
10
- const require_hybrid = require('../hybrid-dX5JLumO.cjs');
4
+ require('../arid-derivation-CNfUKUp-.cjs');
5
+ const require_kv = require('../kv-DmjKQe11.cjs');
6
+ const require_kv$1 = require('../kv-1qBQRbV5.cjs');
7
+ const require_kv$2 = require('../kv-BmCAYeR7.cjs');
8
+ const require_kv$3 = require('../kv-DfzRmYtR.cjs');
11
9
  require('../index.cjs');
12
10
  let path = require("path");
13
11
  path = require_chunk.__toESM(path);
@@ -67,7 +65,7 @@ function generateRandomEnvelope(size) {
67
65
  */
68
66
  async function checkMainline() {
69
67
  try {
70
- await (await require_kv$1.MainlineDhtKv.create()).destroy();
68
+ await (await require_kv$2.MainlineDhtKv.create()).destroy();
71
69
  console.log("✓ Mainline DHT is available");
72
70
  } catch (e) {
73
71
  throw new Error(`✗ Mainline DHT is not available: ${e instanceof Error ? e.message : e}`);
@@ -126,7 +124,7 @@ async function checkServer(host, port) {
126
124
  * Port of `put_mainline()` from bin/hubert.rs lines 207-221.
127
125
  */
128
126
  async function putMainline(arid, envelope, verbose) {
129
- const store = await require_kv$1.MainlineDhtKv.create();
127
+ const store = await require_kv$2.MainlineDhtKv.create();
130
128
  try {
131
129
  await store.put(arid, envelope, void 0, verbose);
132
130
  if (verbose) require_logging.verbosePrintln("✓ Stored envelope at ARID");
@@ -140,7 +138,7 @@ async function putMainline(arid, envelope, verbose) {
140
138
  * Port of `put_ipfs()` from bin/hubert.rs lines 223-250.
141
139
  */
142
140
  async function putIpfs(arid, envelope, port, pin, verbose) {
143
- const result = await new require_kv.IpfsKv(`http://127.0.0.1:${port}`).withPinContent(pin).put(arid, envelope, void 0, verbose);
141
+ const result = await new require_kv$1.IpfsKv(`http://127.0.0.1:${port}`).withPinContent(pin).put(arid, envelope, void 0, verbose);
144
142
  if (verbose) require_logging.verbosePrintln("✓ Stored envelope at ARID");
145
143
  if (pin) {
146
144
  const cidPart = result.split("ipfs://")[1];
@@ -154,7 +152,7 @@ async function putIpfs(arid, envelope, port, pin, verbose) {
154
152
  */
155
153
  async function putHybrid(arid, envelope, port, pin, verbose) {
156
154
  const url = `http://127.0.0.1:${port}`;
157
- const store = (await require_hybrid.HybridKv.create(url)).withPinContent(pin);
155
+ const store = (await require_kv$3.HybridKv.create(url)).withPinContent(pin);
158
156
  try {
159
157
  const result = await store.put(arid, envelope, void 0, verbose);
160
158
  if (verbose) require_logging.verbosePrintln("✓ Stored envelope at ARID");
@@ -172,7 +170,7 @@ async function putHybrid(arid, envelope, port, pin, verbose) {
172
170
  * Port of `put_server()` from bin/hubert.rs lines 324-344.
173
171
  */
174
172
  async function putServer(host, port, arid, envelope, ttl, verbose) {
175
- await new require_server.ServerKvClient(`http://${host}:${port}`).put(arid, envelope, ttl, verbose);
173
+ await new require_kv.ServerKvClient(`http://${host}:${port}`).put(arid, envelope, ttl, verbose);
176
174
  if (verbose) require_logging.verbosePrintln("✓ Stored envelope at ARID");
177
175
  }
178
176
  /**
@@ -181,7 +179,7 @@ async function putServer(host, port, arid, envelope, ttl, verbose) {
181
179
  * Port of `get_mainline()` from bin/hubert.rs lines 252-262.
182
180
  */
183
181
  async function getMainline(arid, timeout, verbose) {
184
- const store = await require_kv$1.MainlineDhtKv.create();
182
+ const store = await require_kv$2.MainlineDhtKv.create();
185
183
  try {
186
184
  return await store.get(arid, timeout, verbose);
187
185
  } finally {
@@ -194,7 +192,7 @@ async function getMainline(arid, timeout, verbose) {
194
192
  * Port of `get_ipfs()` from bin/hubert.rs lines 264-276.
195
193
  */
196
194
  async function getIpfs(arid, timeout, port, verbose) {
197
- return await new require_kv.IpfsKv(`http://127.0.0.1:${port}`).get(arid, timeout, verbose);
195
+ return await new require_kv$1.IpfsKv(`http://127.0.0.1:${port}`).get(arid, timeout, verbose);
198
196
  }
199
197
  /**
200
198
  * Get envelope from Hybrid storage.
@@ -203,7 +201,7 @@ async function getIpfs(arid, timeout, port, verbose) {
203
201
  */
204
202
  async function getHybrid(arid, timeout, port, verbose) {
205
203
  const url = `http://127.0.0.1:${port}`;
206
- const store = await require_hybrid.HybridKv.create(url);
204
+ const store = await require_kv$3.HybridKv.create(url);
207
205
  try {
208
206
  return await store.get(arid, timeout, verbose);
209
207
  } finally {
@@ -216,7 +214,7 @@ async function getHybrid(arid, timeout, port, verbose) {
216
214
  * Port of `get_server()` from bin/hubert.rs lines 346-361.
217
215
  */
218
216
  async function getServer(host, port, arid, timeout, verbose) {
219
- return await new require_server.ServerKvClient(`http://${host}:${port}`).get(arid, timeout, verbose);
217
+ return await new require_kv.ServerKvClient(`http://${host}:${port}`).get(arid, timeout, verbose);
220
218
  }
221
219
  const program = new commander.Command();
222
220
  program.name("hubert").description("Distributed substrate for multiparty transactions").version("1.0.0-alpha.1").option("-v, --verbose", "Enable verbose logging", false);
@@ -364,12 +362,12 @@ program.command("server").description("Start the Hubert HTTP server").option("--
364
362
  try {
365
363
  if (fs.statSync(sqlitePath).isDirectory()) sqlitePath = path.default.join(sqlitePath, "hubert.sqlite");
366
364
  } catch {}
367
- const store = new require_server.SqliteKv(sqlitePath);
368
- const server = require_server.Server.newSqlite(config, store);
365
+ const store = new require_kv.SqliteKv(sqlitePath);
366
+ const server = require_kv.Server.newSqlite(config, store);
369
367
  console.log(`Starting Hubert server on port ${port} with SQLite storage: ${sqlitePath}`);
370
368
  await server.run();
371
369
  } else {
372
- const server = require_server.Server.newMemory(config);
370
+ const server = require_kv.Server.newMemory(config);
373
371
  console.log(`Starting Hubert server on port ${port} with in-memory storage`);
374
372
  await server.run();
375
373
  }
@@ -1 +1 @@
1
- {"version":3,"file":"hubert.cjs","names":["ARID","Envelope","MainlineDhtKv","IpfsKv","HybridKv","ServerKvClient","Command","SqliteKv","Server"],"sources":["../../src/bin/hubert.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * Hubert: Secure Distributed Substrate for Multiparty Transactions\n *\n * A command-line tool for storing and retrieving Gordian Envelopes using\n * distributed storage backends (BitTorrent Mainline DHT or IPFS).\n *\n * Port of bin/hubert.rs from hubert-rust.\n *\n * @module\n */\n\nimport { Command } from \"commander\";\nimport path from \"path\";\n\nimport { ARID } from \"@bcts/components\";\nimport { Envelope } from \"@bcts/envelope\";\nimport { randomData } from \"@bcts/rand\";\n\nimport {\n verbosePrintln,\n IpfsKv,\n MainlineDhtKv,\n HybridKv,\n Server,\n type ServerConfig,\n ServerKvClient,\n SqliteKv,\n} from \"../index.js\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\ntype StorageBackend = \"mainline\" | \"ipfs\" | \"hybrid\" | \"server\";\n\n// =============================================================================\n// Helper Functions\n// =============================================================================\n\n/**\n * Parse an ARID from ur:arid string format.\n *\n * Port of `parse_arid()` from bin/hubert.rs lines 150-153.\n */\nfunction parseArid(s: string): ARID {\n try {\n return ARID.fromUrString(s);\n } catch {\n throw new Error(\"Invalid ARID format. Expected ur:arid\");\n }\n}\n\n/**\n * Parse an Envelope from ur:envelope string format.\n *\n * Port of `parse_envelope()` from bin/hubert.rs lines 155-161.\n */\nfunction parseEnvelope(s: string): Envelope {\n try {\n return Envelope.fromUrString(s);\n } catch {\n throw new Error(\"Invalid envelope format. Expected ur:envelope\");\n }\n}\n\n/**\n * Generate a random envelope with the specified size.\n *\n * Port of `generate_random_envelope()` from bin/hubert.rs lines 163-167.\n */\nfunction generateRandomEnvelope(size: number): Envelope {\n const randomBytes = randomData(size);\n // Pass raw Uint8Array directly - Envelope.new accepts it as EnvelopeEncodableValue\n return Envelope.new(randomBytes);\n}\n\n// =============================================================================\n// Check Functions\n// =============================================================================\n\n/**\n * Check if Mainline DHT is available.\n *\n * Port of `check_mainline()` from bin/hubert.rs lines 169-182.\n */\nasync function checkMainline(): Promise<void> {\n try {\n const dht = await MainlineDhtKv.create();\n await dht.destroy();\n console.log(\"✓ Mainline DHT is available\");\n } catch (e) {\n throw new Error(`✗ Mainline DHT is not available: ${e instanceof Error ? e.message : e}`);\n }\n}\n\n/**\n * Check if IPFS is available.\n *\n * Port of `check_ipfs()` from bin/hubert.rs lines 184-205.\n */\nasync function checkIpfs(port: number): Promise<void> {\n try {\n const url = `http://127.0.0.1:${port}/api/v0/version`;\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 2000);\n\n const response = await fetch(url, {\n method: \"POST\",\n signal: controller.signal,\n });\n\n clearTimeout(timeout);\n\n if (response.ok) {\n console.log(`✓ IPFS is available at 127.0.0.1:${port}`);\n } else {\n throw new Error(`✗ IPFS daemon returned error: ${response.status}`);\n }\n } catch (e) {\n if (e instanceof Error && e.name === \"AbortError\") {\n throw new Error(`✗ IPFS is not available at 127.0.0.1:${port}: connection timeout`);\n }\n throw new Error(\n `✗ IPFS is not available at 127.0.0.1:${port}: ${e instanceof Error ? e.message : e}`,\n );\n }\n}\n\n/**\n * Check if Hubert server is available.\n */\nasync function checkServer(host: string, port: number): Promise<void> {\n try {\n const url = `http://${host}:${port}/health`;\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 2000);\n\n const response = await fetch(url, {\n method: \"GET\",\n signal: controller.signal,\n });\n\n clearTimeout(timeout);\n\n if (response.ok) {\n const json = (await response.json()) as { server?: string; version?: string };\n if (json.server === \"hubert\") {\n const version = json.version ?? \"unknown\";\n console.log(`✓ Hubert server is available at ${host}:${port} (version ${version})`);\n } else {\n throw new Error(`✗ Server at ${host}:${port} is not a Hubert server`);\n }\n } else {\n throw new Error(`✗ Server at ${host}:${port} is not available (status: ${response.status})`);\n }\n } catch (e) {\n if (e instanceof Error && e.name === \"AbortError\") {\n throw new Error(`✗ Server is not available at ${host}:${port}: connection timeout`);\n }\n throw new Error(\n `✗ Server is not available at ${host}:${port}: ${e instanceof Error ? e.message : e}`,\n );\n }\n}\n\n// =============================================================================\n// Put Functions\n// =============================================================================\n\n/**\n * Put envelope to Mainline DHT.\n *\n * Port of `put_mainline()` from bin/hubert.rs lines 207-221.\n */\nasync function putMainline(arid: ARID, envelope: Envelope, verbose: boolean): Promise<void> {\n const store = await MainlineDhtKv.create();\n try {\n await store.put(arid, envelope, undefined, verbose);\n if (verbose) {\n verbosePrintln(\"✓ Stored envelope at ARID\");\n }\n } finally {\n await store.destroy();\n }\n}\n\n/**\n * Put envelope to IPFS.\n *\n * Port of `put_ipfs()` from bin/hubert.rs lines 223-250.\n */\nasync function putIpfs(\n arid: ARID,\n envelope: Envelope,\n port: number,\n pin: boolean,\n verbose: boolean,\n): Promise<void> {\n const url = `http://127.0.0.1:${port}`;\n const store = new IpfsKv(url).withPinContent(pin);\n const result = await store.put(arid, envelope, undefined, verbose);\n\n if (verbose) {\n verbosePrintln(\"✓ Stored envelope at ARID\");\n }\n\n // Extract and print CID if pinning was requested\n if (pin) {\n const cidPart = result.split(\"ipfs://\")[1];\n if (cidPart) {\n console.log(`CID: ${cidPart}`);\n }\n }\n}\n\n/**\n * Put envelope to Hybrid storage.\n *\n * Port of `put_hybrid()` from bin/hubert.rs lines 278-308.\n */\nasync function putHybrid(\n arid: ARID,\n envelope: Envelope,\n port: number,\n pin: boolean,\n verbose: boolean,\n): Promise<void> {\n const url = `http://127.0.0.1:${port}`;\n const store = (await HybridKv.create(url)).withPinContent(pin);\n try {\n const result = await store.put(arid, envelope, undefined, verbose);\n\n if (verbose) {\n verbosePrintln(\"✓ Stored envelope at ARID\");\n }\n\n // Extract and print CID if pinning was requested and IPFS was used\n if (pin && result.includes(\"ipfs://\")) {\n const cidPart = result.split(\"ipfs://\")[1];\n if (cidPart) {\n console.log(`CID: ${cidPart}`);\n }\n }\n } finally {\n await store.destroy();\n }\n}\n\n/**\n * Put envelope to Hubert server.\n *\n * Port of `put_server()` from bin/hubert.rs lines 324-344.\n */\nasync function putServer(\n host: string,\n port: number,\n arid: ARID,\n envelope: Envelope,\n ttl: number | undefined,\n verbose: boolean,\n): Promise<void> {\n const url = `http://${host}:${port}`;\n const store = new ServerKvClient(url);\n await store.put(arid, envelope, ttl, verbose);\n if (verbose) {\n verbosePrintln(\"✓ Stored envelope at ARID\");\n }\n}\n\n// =============================================================================\n// Get Functions\n// =============================================================================\n\n/**\n * Get envelope from Mainline DHT.\n *\n * Port of `get_mainline()` from bin/hubert.rs lines 252-262.\n */\nasync function getMainline(\n arid: ARID,\n timeout: number,\n verbose: boolean,\n): Promise<Envelope | null> {\n const store = await MainlineDhtKv.create();\n try {\n return await store.get(arid, timeout, verbose);\n } finally {\n await store.destroy();\n }\n}\n\n/**\n * Get envelope from IPFS.\n *\n * Port of `get_ipfs()` from bin/hubert.rs lines 264-276.\n */\nasync function getIpfs(\n arid: ARID,\n timeout: number,\n port: number,\n verbose: boolean,\n): Promise<Envelope | null> {\n const url = `http://127.0.0.1:${port}`;\n const store = new IpfsKv(url);\n return await store.get(arid, timeout, verbose);\n}\n\n/**\n * Get envelope from Hybrid storage.\n *\n * Port of `get_hybrid()` from bin/hubert.rs lines 310-322.\n */\nasync function getHybrid(\n arid: ARID,\n timeout: number,\n port: number,\n verbose: boolean,\n): Promise<Envelope | null> {\n const url = `http://127.0.0.1:${port}`;\n const store = await HybridKv.create(url);\n try {\n return await store.get(arid, timeout, verbose);\n } finally {\n await store.destroy();\n }\n}\n\n/**\n * Get envelope from Hubert server.\n *\n * Port of `get_server()` from bin/hubert.rs lines 346-361.\n */\nasync function getServer(\n host: string,\n port: number,\n arid: ARID,\n timeout: number,\n verbose: boolean,\n): Promise<Envelope | null> {\n const url = `http://${host}:${port}`;\n const store = new ServerKvClient(url);\n return await store.get(arid, timeout, verbose);\n}\n\n// =============================================================================\n// CLI Setup\n// =============================================================================\n\nconst program = new Command();\n\nprogram\n .name(\"hubert\")\n .description(\"Distributed substrate for multiparty transactions\")\n .version(\"1.0.0-alpha.1\")\n .option(\"-v, --verbose\", \"Enable verbose logging\", false);\n\n// Generate command\nconst generateCmd = program\n .command(\"generate\")\n .description(\"Generate a new ARID or example Envelope\");\n\ngenerateCmd\n .command(\"arid\")\n .description(\"Generate a new ARID\")\n .action(() => {\n const arid = ARID.new();\n console.log(arid.urString());\n });\n\ngenerateCmd\n .command(\"envelope <size>\")\n .description(\"Generate a test envelope with random data\")\n .action((sizeStr: string) => {\n const size = parseInt(sizeStr, 10);\n if (isNaN(size) || size < 0) {\n console.error(\"Size must be a positive integer\");\n process.exit(1);\n }\n const envelope = generateRandomEnvelope(size);\n console.log(envelope.urString());\n });\n\n// Put command\nprogram\n .command(\"put <arid> <envelope>\")\n .description(\"Store an envelope at an ARID\")\n .option(\"-s, --storage <backend>\", \"Storage backend to use\", \"mainline\")\n .option(\"--host <host>\", \"Server host (for --storage server)\")\n .option(\"--port <port>\", \"Port (for --storage server/ipfs/hybrid)\")\n .option(\"--ttl <seconds>\", \"Time-to-live in seconds (for --storage server)\")\n .option(\"--pin\", \"Pin content in IPFS (only for --storage ipfs or --storage hybrid)\", false)\n .action(\n async (\n aridStr: string,\n envelopeStr: string,\n options: {\n storage: StorageBackend;\n host?: string;\n port?: string;\n ttl?: string;\n pin: boolean;\n },\n ) => {\n const verbose = program.opts()[\"verbose\"] as boolean;\n const storage = options.storage;\n const port = options.port ? parseInt(options.port, 10) : undefined;\n const ttl = options.ttl ? parseInt(options.ttl, 10) : undefined;\n\n try {\n // Validate options based on storage backend\n if (storage === \"mainline\") {\n if (port !== undefined) {\n throw new Error(\"--port option is not supported for --storage mainline\");\n }\n if (options.host !== undefined) {\n throw new Error(\"--host option is not supported for --storage mainline\");\n }\n if (ttl !== undefined) {\n throw new Error(\"--ttl option is only supported for --storage server\");\n }\n if (options.pin) {\n throw new Error(\n \"--pin option is only supported for --storage ipfs or --storage hybrid\",\n );\n }\n } else if (storage === \"ipfs\") {\n if (options.host !== undefined) {\n throw new Error(\n \"--host option is not supported for --storage ipfs (always uses 127.0.0.1)\",\n );\n }\n if (ttl !== undefined) {\n throw new Error(\"--ttl option is only supported for --storage server\");\n }\n } else if (storage === \"hybrid\") {\n if (options.host !== undefined) {\n throw new Error(\n \"--host option is not supported for --storage hybrid (always uses 127.0.0.1)\",\n );\n }\n if (ttl !== undefined) {\n throw new Error(\"--ttl option is only supported for --storage server\");\n }\n } else if (storage === \"server\") {\n if (options.pin) {\n throw new Error(\n \"--pin option is only supported for --storage ipfs or --storage hybrid\",\n );\n }\n }\n\n const arid = parseArid(aridStr);\n const envelope = parseEnvelope(envelopeStr);\n\n switch (storage) {\n case \"mainline\":\n await putMainline(arid, envelope, verbose);\n console.log(\"Stored in Mainline DHT\");\n break;\n case \"ipfs\":\n await putIpfs(arid, envelope, port ?? 5001, options.pin, verbose);\n console.log(\"Stored in IPFS\");\n break;\n case \"hybrid\":\n await putHybrid(arid, envelope, port ?? 5001, options.pin, verbose);\n console.log(\"Stored in Hybrid storage\");\n break;\n case \"server\": {\n const host = options.host ?? \"127.0.0.1\";\n await putServer(host, port ?? 45678, arid, envelope, ttl, verbose);\n console.log(\"Stored in server\");\n break;\n }\n }\n } catch (e) {\n console.error(e instanceof Error ? e.message : e);\n process.exit(1);\n }\n },\n );\n\n// Get command\nprogram\n .command(\"get <arid>\")\n .description(\"Retrieve an envelope by ARID\")\n .option(\"-s, --storage <backend>\", \"Storage backend to use\", \"mainline\")\n .option(\"--host <host>\", \"Server host (for --storage server)\")\n .option(\"--port <port>\", \"Port (for --storage server/ipfs/hybrid)\")\n .option(\"-t, --timeout <seconds>\", \"Maximum time to wait in seconds\", \"30\")\n .action(\n async (\n aridStr: string,\n options: {\n storage: StorageBackend;\n host?: string;\n port?: string;\n timeout: string;\n },\n ) => {\n const verbose = program.opts()[\"verbose\"] as boolean;\n const storage = options.storage;\n const port = options.port ? parseInt(options.port, 10) : undefined;\n const timeout = parseInt(options.timeout, 10);\n\n try {\n // Validate options based on storage backend\n if (storage === \"mainline\") {\n if (port !== undefined) {\n throw new Error(\"--port option is not supported for --storage mainline\");\n }\n if (options.host !== undefined) {\n throw new Error(\"--host option is not supported for --storage mainline\");\n }\n } else if (storage === \"ipfs\") {\n if (options.host !== undefined) {\n throw new Error(\n \"--host option is not supported for --storage ipfs (always uses 127.0.0.1)\",\n );\n }\n } else if (storage === \"hybrid\") {\n if (options.host !== undefined) {\n throw new Error(\n \"--host option is not supported for --storage hybrid (always uses 127.0.0.1)\",\n );\n }\n }\n\n const arid = parseArid(aridStr);\n\n let envelope: Envelope | null;\n switch (storage) {\n case \"mainline\":\n envelope = await getMainline(arid, timeout, verbose);\n break;\n case \"ipfs\":\n envelope = await getIpfs(arid, timeout, port ?? 5001, verbose);\n break;\n case \"hybrid\":\n envelope = await getHybrid(arid, timeout, port ?? 5001, verbose);\n break;\n case \"server\": {\n const host = options.host ?? \"127.0.0.1\";\n envelope = await getServer(host, port ?? 45678, arid, timeout, verbose);\n break;\n }\n }\n\n if (envelope) {\n console.log(envelope.urString());\n } else {\n throw new Error(`Value not found within ${timeout} seconds`);\n }\n } catch (e) {\n console.error(e instanceof Error ? e.message : e);\n process.exit(1);\n }\n },\n );\n\n// Check command\nprogram\n .command(\"check\")\n .description(\"Check if storage backend is available\")\n .option(\"-s, --storage <backend>\", \"Storage backend to use\", \"mainline\")\n .option(\"--host <host>\", \"Server host (for --storage server)\")\n .option(\"--port <port>\", \"Port (for --storage server/ipfs/hybrid)\")\n .action(async (options: { storage: StorageBackend; host?: string; port?: string }) => {\n const storage = options.storage;\n const port = options.port ? parseInt(options.port, 10) : undefined;\n\n try {\n // Validate options based on storage backend\n if (storage === \"mainline\") {\n if (port !== undefined) {\n throw new Error(\"--port option is not supported for --storage mainline\");\n }\n if (options.host !== undefined) {\n throw new Error(\"--host option is not supported for --storage mainline\");\n }\n } else if (storage === \"ipfs\") {\n if (options.host !== undefined) {\n throw new Error(\n \"--host option is not supported for --storage ipfs (always uses 127.0.0.1)\",\n );\n }\n } else if (storage === \"hybrid\") {\n if (options.host !== undefined) {\n throw new Error(\n \"--host option is not supported for --storage hybrid (always uses 127.0.0.1)\",\n );\n }\n }\n\n switch (storage) {\n case \"mainline\":\n await checkMainline();\n break;\n case \"ipfs\":\n await checkIpfs(port ?? 5001);\n break;\n case \"hybrid\":\n await checkMainline();\n await checkIpfs(port ?? 5001);\n console.log(\"✓ Hybrid storage is available (DHT + IPFS)\");\n break;\n case \"server\": {\n const host = options.host ?? \"127.0.0.1\";\n await checkServer(host, port ?? 45678);\n break;\n }\n }\n } catch (e) {\n console.error(e instanceof Error ? e.message : e);\n process.exit(1);\n }\n });\n\n// Server command\nprogram\n .command(\"server\")\n .description(\"Start the Hubert HTTP server\")\n .option(\"--port <port>\", \"Port for the server to listen on\", \"45678\")\n .option(\"--sqlite <path>\", \"SQLite database file path for persistent storage\")\n .action(async (options: { port: string; sqlite?: string }) => {\n const verbose = program.opts()[\"verbose\"] as boolean;\n const port = parseInt(options.port, 10);\n\n try {\n const config: ServerConfig = {\n port,\n maxTtl: 86400, // 24 hours\n verbose,\n };\n\n if (options.sqlite) {\n // Use SQLite storage\n let sqlitePath = options.sqlite;\n // Check if it's a directory\n const fs = await import(\"fs\");\n try {\n const stats = fs.statSync(sqlitePath);\n if (stats.isDirectory()) {\n sqlitePath = path.join(sqlitePath, \"hubert.sqlite\");\n }\n } catch {\n // Path doesn't exist, treat as file path\n }\n\n const store = new SqliteKv(sqlitePath);\n const server = Server.newSqlite(config, store);\n console.log(`Starting Hubert server on port ${port} with SQLite storage: ${sqlitePath}`);\n await server.run();\n } else {\n // Use in-memory storage\n const server = Server.newMemory(config);\n console.log(`Starting Hubert server on port ${port} with in-memory storage`);\n await server.run();\n }\n } catch (e) {\n console.error(e instanceof Error ? e.message : e);\n process.exit(1);\n }\n });\n\n// Parse and run\nprogram.parse();\n"],"mappings":"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"}
1
+ {"version":3,"file":"hubert.cjs","names":["ARID","Envelope","MainlineDhtKv","IpfsKv","HybridKv","ServerKvClient","Command","SqliteKv","Server"],"sources":["../../src/bin/hubert.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * Hubert: Secure Distributed Substrate for Multiparty Transactions\n *\n * A command-line tool for storing and retrieving Gordian Envelopes using\n * distributed storage backends (BitTorrent Mainline DHT or IPFS).\n *\n * Port of bin/hubert.rs from hubert-rust.\n *\n * @module\n */\n\nimport { Command } from \"commander\";\nimport path from \"path\";\n\nimport { ARID } from \"@bcts/components\";\nimport { Envelope } from \"@bcts/envelope\";\nimport { randomData } from \"@bcts/rand\";\n\nimport {\n verbosePrintln,\n IpfsKv,\n MainlineDhtKv,\n HybridKv,\n Server,\n type ServerConfig,\n ServerKvClient,\n SqliteKv,\n} from \"../index.js\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\ntype StorageBackend = \"mainline\" | \"ipfs\" | \"hybrid\" | \"server\";\n\n// =============================================================================\n// Helper Functions\n// =============================================================================\n\n/**\n * Parse an ARID from ur:arid string format.\n *\n * Port of `parse_arid()` from bin/hubert.rs lines 150-153.\n */\nfunction parseArid(s: string): ARID {\n try {\n return ARID.fromUrString(s);\n } catch {\n throw new Error(\"Invalid ARID format. Expected ur:arid\");\n }\n}\n\n/**\n * Parse an Envelope from ur:envelope string format.\n *\n * Port of `parse_envelope()` from bin/hubert.rs lines 155-161.\n */\nfunction parseEnvelope(s: string): Envelope {\n try {\n return Envelope.fromUrString(s);\n } catch {\n throw new Error(\"Invalid envelope format. Expected ur:envelope\");\n }\n}\n\n/**\n * Generate a random envelope with the specified size.\n *\n * Port of `generate_random_envelope()` from bin/hubert.rs lines 163-167.\n */\nfunction generateRandomEnvelope(size: number): Envelope {\n const randomBytes = randomData(size);\n // Pass raw Uint8Array directly - Envelope.new accepts it as EnvelopeEncodableValue\n return Envelope.new(randomBytes);\n}\n\n// =============================================================================\n// Check Functions\n// =============================================================================\n\n/**\n * Check if Mainline DHT is available.\n *\n * Port of `check_mainline()` from bin/hubert.rs lines 169-182.\n */\nasync function checkMainline(): Promise<void> {\n try {\n const dht = await MainlineDhtKv.create();\n await dht.destroy();\n console.log(\"✓ Mainline DHT is available\");\n } catch (e) {\n throw new Error(`✗ Mainline DHT is not available: ${e instanceof Error ? e.message : e}`);\n }\n}\n\n/**\n * Check if IPFS is available.\n *\n * Port of `check_ipfs()` from bin/hubert.rs lines 184-205.\n */\nasync function checkIpfs(port: number): Promise<void> {\n try {\n const url = `http://127.0.0.1:${port}/api/v0/version`;\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 2000);\n\n const response = await fetch(url, {\n method: \"POST\",\n signal: controller.signal,\n });\n\n clearTimeout(timeout);\n\n if (response.ok) {\n console.log(`✓ IPFS is available at 127.0.0.1:${port}`);\n } else {\n throw new Error(`✗ IPFS daemon returned error: ${response.status}`);\n }\n } catch (e) {\n if (e instanceof Error && e.name === \"AbortError\") {\n throw new Error(`✗ IPFS is not available at 127.0.0.1:${port}: connection timeout`);\n }\n throw new Error(\n `✗ IPFS is not available at 127.0.0.1:${port}: ${e instanceof Error ? e.message : e}`,\n );\n }\n}\n\n/**\n * Check if Hubert server is available.\n */\nasync function checkServer(host: string, port: number): Promise<void> {\n try {\n const url = `http://${host}:${port}/health`;\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 2000);\n\n const response = await fetch(url, {\n method: \"GET\",\n signal: controller.signal,\n });\n\n clearTimeout(timeout);\n\n if (response.ok) {\n const json = (await response.json()) as { server?: string; version?: string };\n if (json.server === \"hubert\") {\n const version = json.version ?? \"unknown\";\n console.log(`✓ Hubert server is available at ${host}:${port} (version ${version})`);\n } else {\n throw new Error(`✗ Server at ${host}:${port} is not a Hubert server`);\n }\n } else {\n throw new Error(`✗ Server at ${host}:${port} is not available (status: ${response.status})`);\n }\n } catch (e) {\n if (e instanceof Error && e.name === \"AbortError\") {\n throw new Error(`✗ Server is not available at ${host}:${port}: connection timeout`);\n }\n throw new Error(\n `✗ Server is not available at ${host}:${port}: ${e instanceof Error ? e.message : e}`,\n );\n }\n}\n\n// =============================================================================\n// Put Functions\n// =============================================================================\n\n/**\n * Put envelope to Mainline DHT.\n *\n * Port of `put_mainline()` from bin/hubert.rs lines 207-221.\n */\nasync function putMainline(arid: ARID, envelope: Envelope, verbose: boolean): Promise<void> {\n const store = await MainlineDhtKv.create();\n try {\n await store.put(arid, envelope, undefined, verbose);\n if (verbose) {\n verbosePrintln(\"✓ Stored envelope at ARID\");\n }\n } finally {\n await store.destroy();\n }\n}\n\n/**\n * Put envelope to IPFS.\n *\n * Port of `put_ipfs()` from bin/hubert.rs lines 223-250.\n */\nasync function putIpfs(\n arid: ARID,\n envelope: Envelope,\n port: number,\n pin: boolean,\n verbose: boolean,\n): Promise<void> {\n const url = `http://127.0.0.1:${port}`;\n const store = new IpfsKv(url).withPinContent(pin);\n const result = await store.put(arid, envelope, undefined, verbose);\n\n if (verbose) {\n verbosePrintln(\"✓ Stored envelope at ARID\");\n }\n\n // Extract and print CID if pinning was requested\n if (pin) {\n const cidPart = result.split(\"ipfs://\")[1];\n if (cidPart) {\n console.log(`CID: ${cidPart}`);\n }\n }\n}\n\n/**\n * Put envelope to Hybrid storage.\n *\n * Port of `put_hybrid()` from bin/hubert.rs lines 278-308.\n */\nasync function putHybrid(\n arid: ARID,\n envelope: Envelope,\n port: number,\n pin: boolean,\n verbose: boolean,\n): Promise<void> {\n const url = `http://127.0.0.1:${port}`;\n const store = (await HybridKv.create(url)).withPinContent(pin);\n try {\n const result = await store.put(arid, envelope, undefined, verbose);\n\n if (verbose) {\n verbosePrintln(\"✓ Stored envelope at ARID\");\n }\n\n // Extract and print CID if pinning was requested and IPFS was used\n if (pin && result.includes(\"ipfs://\")) {\n const cidPart = result.split(\"ipfs://\")[1];\n if (cidPart) {\n console.log(`CID: ${cidPart}`);\n }\n }\n } finally {\n await store.destroy();\n }\n}\n\n/**\n * Put envelope to Hubert server.\n *\n * Port of `put_server()` from bin/hubert.rs lines 324-344.\n */\nasync function putServer(\n host: string,\n port: number,\n arid: ARID,\n envelope: Envelope,\n ttl: number | undefined,\n verbose: boolean,\n): Promise<void> {\n const url = `http://${host}:${port}`;\n const store = new ServerKvClient(url);\n await store.put(arid, envelope, ttl, verbose);\n if (verbose) {\n verbosePrintln(\"✓ Stored envelope at ARID\");\n }\n}\n\n// =============================================================================\n// Get Functions\n// =============================================================================\n\n/**\n * Get envelope from Mainline DHT.\n *\n * Port of `get_mainline()` from bin/hubert.rs lines 252-262.\n */\nasync function getMainline(\n arid: ARID,\n timeout: number,\n verbose: boolean,\n): Promise<Envelope | null> {\n const store = await MainlineDhtKv.create();\n try {\n return await store.get(arid, timeout, verbose);\n } finally {\n await store.destroy();\n }\n}\n\n/**\n * Get envelope from IPFS.\n *\n * Port of `get_ipfs()` from bin/hubert.rs lines 264-276.\n */\nasync function getIpfs(\n arid: ARID,\n timeout: number,\n port: number,\n verbose: boolean,\n): Promise<Envelope | null> {\n const url = `http://127.0.0.1:${port}`;\n const store = new IpfsKv(url);\n return await store.get(arid, timeout, verbose);\n}\n\n/**\n * Get envelope from Hybrid storage.\n *\n * Port of `get_hybrid()` from bin/hubert.rs lines 310-322.\n */\nasync function getHybrid(\n arid: ARID,\n timeout: number,\n port: number,\n verbose: boolean,\n): Promise<Envelope | null> {\n const url = `http://127.0.0.1:${port}`;\n const store = await HybridKv.create(url);\n try {\n return await store.get(arid, timeout, verbose);\n } finally {\n await store.destroy();\n }\n}\n\n/**\n * Get envelope from Hubert server.\n *\n * Port of `get_server()` from bin/hubert.rs lines 346-361.\n */\nasync function getServer(\n host: string,\n port: number,\n arid: ARID,\n timeout: number,\n verbose: boolean,\n): Promise<Envelope | null> {\n const url = `http://${host}:${port}`;\n const store = new ServerKvClient(url);\n return await store.get(arid, timeout, verbose);\n}\n\n// =============================================================================\n// CLI Setup\n// =============================================================================\n\nconst program = new Command();\n\nprogram\n .name(\"hubert\")\n .description(\"Distributed substrate for multiparty transactions\")\n .version(\"1.0.0-alpha.1\")\n .option(\"-v, --verbose\", \"Enable verbose logging\", false);\n\n// Generate command\nconst generateCmd = program\n .command(\"generate\")\n .description(\"Generate a new ARID or example Envelope\");\n\ngenerateCmd\n .command(\"arid\")\n .description(\"Generate a new ARID\")\n .action(() => {\n const arid = ARID.new();\n console.log(arid.urString());\n });\n\ngenerateCmd\n .command(\"envelope <size>\")\n .description(\"Generate a test envelope with random data\")\n .action((sizeStr: string) => {\n const size = parseInt(sizeStr, 10);\n if (isNaN(size) || size < 0) {\n console.error(\"Size must be a positive integer\");\n process.exit(1);\n }\n const envelope = generateRandomEnvelope(size);\n console.log(envelope.urString());\n });\n\n// Put command\nprogram\n .command(\"put <arid> <envelope>\")\n .description(\"Store an envelope at an ARID\")\n .option(\"-s, --storage <backend>\", \"Storage backend to use\", \"mainline\")\n .option(\"--host <host>\", \"Server host (for --storage server)\")\n .option(\"--port <port>\", \"Port (for --storage server/ipfs/hybrid)\")\n .option(\"--ttl <seconds>\", \"Time-to-live in seconds (for --storage server)\")\n .option(\"--pin\", \"Pin content in IPFS (only for --storage ipfs or --storage hybrid)\", false)\n .action(\n async (\n aridStr: string,\n envelopeStr: string,\n options: {\n storage: StorageBackend;\n host?: string;\n port?: string;\n ttl?: string;\n pin: boolean;\n },\n ) => {\n const verbose = program.opts()[\"verbose\"] as boolean;\n const storage = options.storage;\n const port = options.port ? parseInt(options.port, 10) : undefined;\n const ttl = options.ttl ? parseInt(options.ttl, 10) : undefined;\n\n try {\n // Validate options based on storage backend\n if (storage === \"mainline\") {\n if (port !== undefined) {\n throw new Error(\"--port option is not supported for --storage mainline\");\n }\n if (options.host !== undefined) {\n throw new Error(\"--host option is not supported for --storage mainline\");\n }\n if (ttl !== undefined) {\n throw new Error(\"--ttl option is only supported for --storage server\");\n }\n if (options.pin) {\n throw new Error(\n \"--pin option is only supported for --storage ipfs or --storage hybrid\",\n );\n }\n } else if (storage === \"ipfs\") {\n if (options.host !== undefined) {\n throw new Error(\n \"--host option is not supported for --storage ipfs (always uses 127.0.0.1)\",\n );\n }\n if (ttl !== undefined) {\n throw new Error(\"--ttl option is only supported for --storage server\");\n }\n } else if (storage === \"hybrid\") {\n if (options.host !== undefined) {\n throw new Error(\n \"--host option is not supported for --storage hybrid (always uses 127.0.0.1)\",\n );\n }\n if (ttl !== undefined) {\n throw new Error(\"--ttl option is only supported for --storage server\");\n }\n } else if (storage === \"server\") {\n if (options.pin) {\n throw new Error(\n \"--pin option is only supported for --storage ipfs or --storage hybrid\",\n );\n }\n }\n\n const arid = parseArid(aridStr);\n const envelope = parseEnvelope(envelopeStr);\n\n switch (storage) {\n case \"mainline\":\n await putMainline(arid, envelope, verbose);\n console.log(\"Stored in Mainline DHT\");\n break;\n case \"ipfs\":\n await putIpfs(arid, envelope, port ?? 5001, options.pin, verbose);\n console.log(\"Stored in IPFS\");\n break;\n case \"hybrid\":\n await putHybrid(arid, envelope, port ?? 5001, options.pin, verbose);\n console.log(\"Stored in Hybrid storage\");\n break;\n case \"server\": {\n const host = options.host ?? \"127.0.0.1\";\n await putServer(host, port ?? 45678, arid, envelope, ttl, verbose);\n console.log(\"Stored in server\");\n break;\n }\n }\n } catch (e) {\n console.error(e instanceof Error ? e.message : e);\n process.exit(1);\n }\n },\n );\n\n// Get command\nprogram\n .command(\"get <arid>\")\n .description(\"Retrieve an envelope by ARID\")\n .option(\"-s, --storage <backend>\", \"Storage backend to use\", \"mainline\")\n .option(\"--host <host>\", \"Server host (for --storage server)\")\n .option(\"--port <port>\", \"Port (for --storage server/ipfs/hybrid)\")\n .option(\"-t, --timeout <seconds>\", \"Maximum time to wait in seconds\", \"30\")\n .action(\n async (\n aridStr: string,\n options: {\n storage: StorageBackend;\n host?: string;\n port?: string;\n timeout: string;\n },\n ) => {\n const verbose = program.opts()[\"verbose\"] as boolean;\n const storage = options.storage;\n const port = options.port ? parseInt(options.port, 10) : undefined;\n const timeout = parseInt(options.timeout, 10);\n\n try {\n // Validate options based on storage backend\n if (storage === \"mainline\") {\n if (port !== undefined) {\n throw new Error(\"--port option is not supported for --storage mainline\");\n }\n if (options.host !== undefined) {\n throw new Error(\"--host option is not supported for --storage mainline\");\n }\n } else if (storage === \"ipfs\") {\n if (options.host !== undefined) {\n throw new Error(\n \"--host option is not supported for --storage ipfs (always uses 127.0.0.1)\",\n );\n }\n } else if (storage === \"hybrid\") {\n if (options.host !== undefined) {\n throw new Error(\n \"--host option is not supported for --storage hybrid (always uses 127.0.0.1)\",\n );\n }\n }\n\n const arid = parseArid(aridStr);\n\n let envelope: Envelope | null;\n switch (storage) {\n case \"mainline\":\n envelope = await getMainline(arid, timeout, verbose);\n break;\n case \"ipfs\":\n envelope = await getIpfs(arid, timeout, port ?? 5001, verbose);\n break;\n case \"hybrid\":\n envelope = await getHybrid(arid, timeout, port ?? 5001, verbose);\n break;\n case \"server\": {\n const host = options.host ?? \"127.0.0.1\";\n envelope = await getServer(host, port ?? 45678, arid, timeout, verbose);\n break;\n }\n }\n\n if (envelope) {\n console.log(envelope.urString());\n } else {\n throw new Error(`Value not found within ${timeout} seconds`);\n }\n } catch (e) {\n console.error(e instanceof Error ? e.message : e);\n process.exit(1);\n }\n },\n );\n\n// Check command\nprogram\n .command(\"check\")\n .description(\"Check if storage backend is available\")\n .option(\"-s, --storage <backend>\", \"Storage backend to use\", \"mainline\")\n .option(\"--host <host>\", \"Server host (for --storage server)\")\n .option(\"--port <port>\", \"Port (for --storage server/ipfs/hybrid)\")\n .action(async (options: { storage: StorageBackend; host?: string; port?: string }) => {\n const storage = options.storage;\n const port = options.port ? parseInt(options.port, 10) : undefined;\n\n try {\n // Validate options based on storage backend\n if (storage === \"mainline\") {\n if (port !== undefined) {\n throw new Error(\"--port option is not supported for --storage mainline\");\n }\n if (options.host !== undefined) {\n throw new Error(\"--host option is not supported for --storage mainline\");\n }\n } else if (storage === \"ipfs\") {\n if (options.host !== undefined) {\n throw new Error(\n \"--host option is not supported for --storage ipfs (always uses 127.0.0.1)\",\n );\n }\n } else if (storage === \"hybrid\") {\n if (options.host !== undefined) {\n throw new Error(\n \"--host option is not supported for --storage hybrid (always uses 127.0.0.1)\",\n );\n }\n }\n\n switch (storage) {\n case \"mainline\":\n await checkMainline();\n break;\n case \"ipfs\":\n await checkIpfs(port ?? 5001);\n break;\n case \"hybrid\":\n await checkMainline();\n await checkIpfs(port ?? 5001);\n console.log(\"✓ Hybrid storage is available (DHT + IPFS)\");\n break;\n case \"server\": {\n const host = options.host ?? \"127.0.0.1\";\n await checkServer(host, port ?? 45678);\n break;\n }\n }\n } catch (e) {\n console.error(e instanceof Error ? e.message : e);\n process.exit(1);\n }\n });\n\n// Server command\nprogram\n .command(\"server\")\n .description(\"Start the Hubert HTTP server\")\n .option(\"--port <port>\", \"Port for the server to listen on\", \"45678\")\n .option(\"--sqlite <path>\", \"SQLite database file path for persistent storage\")\n .action(async (options: { port: string; sqlite?: string }) => {\n const verbose = program.opts()[\"verbose\"] as boolean;\n const port = parseInt(options.port, 10);\n\n try {\n const config: ServerConfig = {\n port,\n maxTtl: 86400, // 24 hours\n verbose,\n };\n\n if (options.sqlite) {\n // Use SQLite storage\n let sqlitePath = options.sqlite;\n // Check if it's a directory\n const fs = await import(\"fs\");\n try {\n const stats = fs.statSync(sqlitePath);\n if (stats.isDirectory()) {\n sqlitePath = path.join(sqlitePath, \"hubert.sqlite\");\n }\n } catch {\n // Path doesn't exist, treat as file path\n }\n\n const store = new SqliteKv(sqlitePath);\n const server = Server.newSqlite(config, store);\n console.log(`Starting Hubert server on port ${port} with SQLite storage: ${sqlitePath}`);\n await server.run();\n } else {\n // Use in-memory storage\n const server = Server.newMemory(config);\n console.log(`Starting Hubert server on port ${port} with in-memory storage`);\n await server.run();\n }\n } catch (e) {\n console.error(e instanceof Error ? e.message : e);\n process.exit(1);\n }\n });\n\n// Parse and run\nprogram.parse();\n"],"mappings":"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"}
@@ -1,12 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import { i as verbosePrintln } from "../logging-hmzNzifq.mjs";
3
3
  import "../arid-derivation-CbqACjdg.mjs";
4
- import { n as Server, o as SqliteKv, t as ServerKvClient } from "../server-DVyk9gqU.mjs";
4
+ import { n as Server, o as SqliteKv, t as ServerKvClient } from "../kv-BhFoL8bc.mjs";
5
5
  import { t as IpfsKv } from "../kv-DJiKvypY.mjs";
6
- import "../ipfs-BRMMCBjv.mjs";
7
- import { t as MainlineDhtKv } from "../kv-C-emxv0w.mjs";
8
- import "../mainline-cFIuXbo-.mjs";
9
- import { t as HybridKv } from "../hybrid-BZhumygj.mjs";
6
+ import { t as MainlineDhtKv } from "../kv-DVYfnjvh.mjs";
7
+ import { t as HybridKv } from "../kv-CmxPWVB1.mjs";
10
8
  import "../index.mjs";
11
9
  import path from "path";
12
10
  import { ARID } from "@bcts/components";
@@ -1 +1 @@
1
- {"version":3,"file":"hubert.mjs","names":[],"sources":["../../src/bin/hubert.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * Hubert: Secure Distributed Substrate for Multiparty Transactions\n *\n * A command-line tool for storing and retrieving Gordian Envelopes using\n * distributed storage backends (BitTorrent Mainline DHT or IPFS).\n *\n * Port of bin/hubert.rs from hubert-rust.\n *\n * @module\n */\n\nimport { Command } from \"commander\";\nimport path from \"path\";\n\nimport { ARID } from \"@bcts/components\";\nimport { Envelope } from \"@bcts/envelope\";\nimport { randomData } from \"@bcts/rand\";\n\nimport {\n verbosePrintln,\n IpfsKv,\n MainlineDhtKv,\n HybridKv,\n Server,\n type ServerConfig,\n ServerKvClient,\n SqliteKv,\n} from \"../index.js\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\ntype StorageBackend = \"mainline\" | \"ipfs\" | \"hybrid\" | \"server\";\n\n// =============================================================================\n// Helper Functions\n// =============================================================================\n\n/**\n * Parse an ARID from ur:arid string format.\n *\n * Port of `parse_arid()` from bin/hubert.rs lines 150-153.\n */\nfunction parseArid(s: string): ARID {\n try {\n return ARID.fromUrString(s);\n } catch {\n throw new Error(\"Invalid ARID format. Expected ur:arid\");\n }\n}\n\n/**\n * Parse an Envelope from ur:envelope string format.\n *\n * Port of `parse_envelope()` from bin/hubert.rs lines 155-161.\n */\nfunction parseEnvelope(s: string): Envelope {\n try {\n return Envelope.fromUrString(s);\n } catch {\n throw new Error(\"Invalid envelope format. Expected ur:envelope\");\n }\n}\n\n/**\n * Generate a random envelope with the specified size.\n *\n * Port of `generate_random_envelope()` from bin/hubert.rs lines 163-167.\n */\nfunction generateRandomEnvelope(size: number): Envelope {\n const randomBytes = randomData(size);\n // Pass raw Uint8Array directly - Envelope.new accepts it as EnvelopeEncodableValue\n return Envelope.new(randomBytes);\n}\n\n// =============================================================================\n// Check Functions\n// =============================================================================\n\n/**\n * Check if Mainline DHT is available.\n *\n * Port of `check_mainline()` from bin/hubert.rs lines 169-182.\n */\nasync function checkMainline(): Promise<void> {\n try {\n const dht = await MainlineDhtKv.create();\n await dht.destroy();\n console.log(\"✓ Mainline DHT is available\");\n } catch (e) {\n throw new Error(`✗ Mainline DHT is not available: ${e instanceof Error ? e.message : e}`);\n }\n}\n\n/**\n * Check if IPFS is available.\n *\n * Port of `check_ipfs()` from bin/hubert.rs lines 184-205.\n */\nasync function checkIpfs(port: number): Promise<void> {\n try {\n const url = `http://127.0.0.1:${port}/api/v0/version`;\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 2000);\n\n const response = await fetch(url, {\n method: \"POST\",\n signal: controller.signal,\n });\n\n clearTimeout(timeout);\n\n if (response.ok) {\n console.log(`✓ IPFS is available at 127.0.0.1:${port}`);\n } else {\n throw new Error(`✗ IPFS daemon returned error: ${response.status}`);\n }\n } catch (e) {\n if (e instanceof Error && e.name === \"AbortError\") {\n throw new Error(`✗ IPFS is not available at 127.0.0.1:${port}: connection timeout`);\n }\n throw new Error(\n `✗ IPFS is not available at 127.0.0.1:${port}: ${e instanceof Error ? e.message : e}`,\n );\n }\n}\n\n/**\n * Check if Hubert server is available.\n */\nasync function checkServer(host: string, port: number): Promise<void> {\n try {\n const url = `http://${host}:${port}/health`;\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 2000);\n\n const response = await fetch(url, {\n method: \"GET\",\n signal: controller.signal,\n });\n\n clearTimeout(timeout);\n\n if (response.ok) {\n const json = (await response.json()) as { server?: string; version?: string };\n if (json.server === \"hubert\") {\n const version = json.version ?? \"unknown\";\n console.log(`✓ Hubert server is available at ${host}:${port} (version ${version})`);\n } else {\n throw new Error(`✗ Server at ${host}:${port} is not a Hubert server`);\n }\n } else {\n throw new Error(`✗ Server at ${host}:${port} is not available (status: ${response.status})`);\n }\n } catch (e) {\n if (e instanceof Error && e.name === \"AbortError\") {\n throw new Error(`✗ Server is not available at ${host}:${port}: connection timeout`);\n }\n throw new Error(\n `✗ Server is not available at ${host}:${port}: ${e instanceof Error ? e.message : e}`,\n );\n }\n}\n\n// =============================================================================\n// Put Functions\n// =============================================================================\n\n/**\n * Put envelope to Mainline DHT.\n *\n * Port of `put_mainline()` from bin/hubert.rs lines 207-221.\n */\nasync function putMainline(arid: ARID, envelope: Envelope, verbose: boolean): Promise<void> {\n const store = await MainlineDhtKv.create();\n try {\n await store.put(arid, envelope, undefined, verbose);\n if (verbose) {\n verbosePrintln(\"✓ Stored envelope at ARID\");\n }\n } finally {\n await store.destroy();\n }\n}\n\n/**\n * Put envelope to IPFS.\n *\n * Port of `put_ipfs()` from bin/hubert.rs lines 223-250.\n */\nasync function putIpfs(\n arid: ARID,\n envelope: Envelope,\n port: number,\n pin: boolean,\n verbose: boolean,\n): Promise<void> {\n const url = `http://127.0.0.1:${port}`;\n const store = new IpfsKv(url).withPinContent(pin);\n const result = await store.put(arid, envelope, undefined, verbose);\n\n if (verbose) {\n verbosePrintln(\"✓ Stored envelope at ARID\");\n }\n\n // Extract and print CID if pinning was requested\n if (pin) {\n const cidPart = result.split(\"ipfs://\")[1];\n if (cidPart) {\n console.log(`CID: ${cidPart}`);\n }\n }\n}\n\n/**\n * Put envelope to Hybrid storage.\n *\n * Port of `put_hybrid()` from bin/hubert.rs lines 278-308.\n */\nasync function putHybrid(\n arid: ARID,\n envelope: Envelope,\n port: number,\n pin: boolean,\n verbose: boolean,\n): Promise<void> {\n const url = `http://127.0.0.1:${port}`;\n const store = (await HybridKv.create(url)).withPinContent(pin);\n try {\n const result = await store.put(arid, envelope, undefined, verbose);\n\n if (verbose) {\n verbosePrintln(\"✓ Stored envelope at ARID\");\n }\n\n // Extract and print CID if pinning was requested and IPFS was used\n if (pin && result.includes(\"ipfs://\")) {\n const cidPart = result.split(\"ipfs://\")[1];\n if (cidPart) {\n console.log(`CID: ${cidPart}`);\n }\n }\n } finally {\n await store.destroy();\n }\n}\n\n/**\n * Put envelope to Hubert server.\n *\n * Port of `put_server()` from bin/hubert.rs lines 324-344.\n */\nasync function putServer(\n host: string,\n port: number,\n arid: ARID,\n envelope: Envelope,\n ttl: number | undefined,\n verbose: boolean,\n): Promise<void> {\n const url = `http://${host}:${port}`;\n const store = new ServerKvClient(url);\n await store.put(arid, envelope, ttl, verbose);\n if (verbose) {\n verbosePrintln(\"✓ Stored envelope at ARID\");\n }\n}\n\n// =============================================================================\n// Get Functions\n// =============================================================================\n\n/**\n * Get envelope from Mainline DHT.\n *\n * Port of `get_mainline()` from bin/hubert.rs lines 252-262.\n */\nasync function getMainline(\n arid: ARID,\n timeout: number,\n verbose: boolean,\n): Promise<Envelope | null> {\n const store = await MainlineDhtKv.create();\n try {\n return await store.get(arid, timeout, verbose);\n } finally {\n await store.destroy();\n }\n}\n\n/**\n * Get envelope from IPFS.\n *\n * Port of `get_ipfs()` from bin/hubert.rs lines 264-276.\n */\nasync function getIpfs(\n arid: ARID,\n timeout: number,\n port: number,\n verbose: boolean,\n): Promise<Envelope | null> {\n const url = `http://127.0.0.1:${port}`;\n const store = new IpfsKv(url);\n return await store.get(arid, timeout, verbose);\n}\n\n/**\n * Get envelope from Hybrid storage.\n *\n * Port of `get_hybrid()` from bin/hubert.rs lines 310-322.\n */\nasync function getHybrid(\n arid: ARID,\n timeout: number,\n port: number,\n verbose: boolean,\n): Promise<Envelope | null> {\n const url = `http://127.0.0.1:${port}`;\n const store = await HybridKv.create(url);\n try {\n return await store.get(arid, timeout, verbose);\n } finally {\n await store.destroy();\n }\n}\n\n/**\n * Get envelope from Hubert server.\n *\n * Port of `get_server()` from bin/hubert.rs lines 346-361.\n */\nasync function getServer(\n host: string,\n port: number,\n arid: ARID,\n timeout: number,\n verbose: boolean,\n): Promise<Envelope | null> {\n const url = `http://${host}:${port}`;\n const store = new ServerKvClient(url);\n return await store.get(arid, timeout, verbose);\n}\n\n// =============================================================================\n// CLI Setup\n// =============================================================================\n\nconst program = new Command();\n\nprogram\n .name(\"hubert\")\n .description(\"Distributed substrate for multiparty transactions\")\n .version(\"1.0.0-alpha.1\")\n .option(\"-v, --verbose\", \"Enable verbose logging\", false);\n\n// Generate command\nconst generateCmd = program\n .command(\"generate\")\n .description(\"Generate a new ARID or example Envelope\");\n\ngenerateCmd\n .command(\"arid\")\n .description(\"Generate a new ARID\")\n .action(() => {\n const arid = ARID.new();\n console.log(arid.urString());\n });\n\ngenerateCmd\n .command(\"envelope <size>\")\n .description(\"Generate a test envelope with random data\")\n .action((sizeStr: string) => {\n const size = parseInt(sizeStr, 10);\n if (isNaN(size) || size < 0) {\n console.error(\"Size must be a positive integer\");\n process.exit(1);\n }\n const envelope = generateRandomEnvelope(size);\n console.log(envelope.urString());\n });\n\n// Put command\nprogram\n .command(\"put <arid> <envelope>\")\n .description(\"Store an envelope at an ARID\")\n .option(\"-s, --storage <backend>\", \"Storage backend to use\", \"mainline\")\n .option(\"--host <host>\", \"Server host (for --storage server)\")\n .option(\"--port <port>\", \"Port (for --storage server/ipfs/hybrid)\")\n .option(\"--ttl <seconds>\", \"Time-to-live in seconds (for --storage server)\")\n .option(\"--pin\", \"Pin content in IPFS (only for --storage ipfs or --storage hybrid)\", false)\n .action(\n async (\n aridStr: string,\n envelopeStr: string,\n options: {\n storage: StorageBackend;\n host?: string;\n port?: string;\n ttl?: string;\n pin: boolean;\n },\n ) => {\n const verbose = program.opts()[\"verbose\"] as boolean;\n const storage = options.storage;\n const port = options.port ? parseInt(options.port, 10) : undefined;\n const ttl = options.ttl ? parseInt(options.ttl, 10) : undefined;\n\n try {\n // Validate options based on storage backend\n if (storage === \"mainline\") {\n if (port !== undefined) {\n throw new Error(\"--port option is not supported for --storage mainline\");\n }\n if (options.host !== undefined) {\n throw new Error(\"--host option is not supported for --storage mainline\");\n }\n if (ttl !== undefined) {\n throw new Error(\"--ttl option is only supported for --storage server\");\n }\n if (options.pin) {\n throw new Error(\n \"--pin option is only supported for --storage ipfs or --storage hybrid\",\n );\n }\n } else if (storage === \"ipfs\") {\n if (options.host !== undefined) {\n throw new Error(\n \"--host option is not supported for --storage ipfs (always uses 127.0.0.1)\",\n );\n }\n if (ttl !== undefined) {\n throw new Error(\"--ttl option is only supported for --storage server\");\n }\n } else if (storage === \"hybrid\") {\n if (options.host !== undefined) {\n throw new Error(\n \"--host option is not supported for --storage hybrid (always uses 127.0.0.1)\",\n );\n }\n if (ttl !== undefined) {\n throw new Error(\"--ttl option is only supported for --storage server\");\n }\n } else if (storage === \"server\") {\n if (options.pin) {\n throw new Error(\n \"--pin option is only supported for --storage ipfs or --storage hybrid\",\n );\n }\n }\n\n const arid = parseArid(aridStr);\n const envelope = parseEnvelope(envelopeStr);\n\n switch (storage) {\n case \"mainline\":\n await putMainline(arid, envelope, verbose);\n console.log(\"Stored in Mainline DHT\");\n break;\n case \"ipfs\":\n await putIpfs(arid, envelope, port ?? 5001, options.pin, verbose);\n console.log(\"Stored in IPFS\");\n break;\n case \"hybrid\":\n await putHybrid(arid, envelope, port ?? 5001, options.pin, verbose);\n console.log(\"Stored in Hybrid storage\");\n break;\n case \"server\": {\n const host = options.host ?? \"127.0.0.1\";\n await putServer(host, port ?? 45678, arid, envelope, ttl, verbose);\n console.log(\"Stored in server\");\n break;\n }\n }\n } catch (e) {\n console.error(e instanceof Error ? e.message : e);\n process.exit(1);\n }\n },\n );\n\n// Get command\nprogram\n .command(\"get <arid>\")\n .description(\"Retrieve an envelope by ARID\")\n .option(\"-s, --storage <backend>\", \"Storage backend to use\", \"mainline\")\n .option(\"--host <host>\", \"Server host (for --storage server)\")\n .option(\"--port <port>\", \"Port (for --storage server/ipfs/hybrid)\")\n .option(\"-t, --timeout <seconds>\", \"Maximum time to wait in seconds\", \"30\")\n .action(\n async (\n aridStr: string,\n options: {\n storage: StorageBackend;\n host?: string;\n port?: string;\n timeout: string;\n },\n ) => {\n const verbose = program.opts()[\"verbose\"] as boolean;\n const storage = options.storage;\n const port = options.port ? parseInt(options.port, 10) : undefined;\n const timeout = parseInt(options.timeout, 10);\n\n try {\n // Validate options based on storage backend\n if (storage === \"mainline\") {\n if (port !== undefined) {\n throw new Error(\"--port option is not supported for --storage mainline\");\n }\n if (options.host !== undefined) {\n throw new Error(\"--host option is not supported for --storage mainline\");\n }\n } else if (storage === \"ipfs\") {\n if (options.host !== undefined) {\n throw new Error(\n \"--host option is not supported for --storage ipfs (always uses 127.0.0.1)\",\n );\n }\n } else if (storage === \"hybrid\") {\n if (options.host !== undefined) {\n throw new Error(\n \"--host option is not supported for --storage hybrid (always uses 127.0.0.1)\",\n );\n }\n }\n\n const arid = parseArid(aridStr);\n\n let envelope: Envelope | null;\n switch (storage) {\n case \"mainline\":\n envelope = await getMainline(arid, timeout, verbose);\n break;\n case \"ipfs\":\n envelope = await getIpfs(arid, timeout, port ?? 5001, verbose);\n break;\n case \"hybrid\":\n envelope = await getHybrid(arid, timeout, port ?? 5001, verbose);\n break;\n case \"server\": {\n const host = options.host ?? \"127.0.0.1\";\n envelope = await getServer(host, port ?? 45678, arid, timeout, verbose);\n break;\n }\n }\n\n if (envelope) {\n console.log(envelope.urString());\n } else {\n throw new Error(`Value not found within ${timeout} seconds`);\n }\n } catch (e) {\n console.error(e instanceof Error ? e.message : e);\n process.exit(1);\n }\n },\n );\n\n// Check command\nprogram\n .command(\"check\")\n .description(\"Check if storage backend is available\")\n .option(\"-s, --storage <backend>\", \"Storage backend to use\", \"mainline\")\n .option(\"--host <host>\", \"Server host (for --storage server)\")\n .option(\"--port <port>\", \"Port (for --storage server/ipfs/hybrid)\")\n .action(async (options: { storage: StorageBackend; host?: string; port?: string }) => {\n const storage = options.storage;\n const port = options.port ? parseInt(options.port, 10) : undefined;\n\n try {\n // Validate options based on storage backend\n if (storage === \"mainline\") {\n if (port !== undefined) {\n throw new Error(\"--port option is not supported for --storage mainline\");\n }\n if (options.host !== undefined) {\n throw new Error(\"--host option is not supported for --storage mainline\");\n }\n } else if (storage === \"ipfs\") {\n if (options.host !== undefined) {\n throw new Error(\n \"--host option is not supported for --storage ipfs (always uses 127.0.0.1)\",\n );\n }\n } else if (storage === \"hybrid\") {\n if (options.host !== undefined) {\n throw new Error(\n \"--host option is not supported for --storage hybrid (always uses 127.0.0.1)\",\n );\n }\n }\n\n switch (storage) {\n case \"mainline\":\n await checkMainline();\n break;\n case \"ipfs\":\n await checkIpfs(port ?? 5001);\n break;\n case \"hybrid\":\n await checkMainline();\n await checkIpfs(port ?? 5001);\n console.log(\"✓ Hybrid storage is available (DHT + IPFS)\");\n break;\n case \"server\": {\n const host = options.host ?? \"127.0.0.1\";\n await checkServer(host, port ?? 45678);\n break;\n }\n }\n } catch (e) {\n console.error(e instanceof Error ? e.message : e);\n process.exit(1);\n }\n });\n\n// Server command\nprogram\n .command(\"server\")\n .description(\"Start the Hubert HTTP server\")\n .option(\"--port <port>\", \"Port for the server to listen on\", \"45678\")\n .option(\"--sqlite <path>\", \"SQLite database file path for persistent storage\")\n .action(async (options: { port: string; sqlite?: string }) => {\n const verbose = program.opts()[\"verbose\"] as boolean;\n const port = parseInt(options.port, 10);\n\n try {\n const config: ServerConfig = {\n port,\n maxTtl: 86400, // 24 hours\n verbose,\n };\n\n if (options.sqlite) {\n // Use SQLite storage\n let sqlitePath = options.sqlite;\n // Check if it's a directory\n const fs = await import(\"fs\");\n try {\n const stats = fs.statSync(sqlitePath);\n if (stats.isDirectory()) {\n sqlitePath = path.join(sqlitePath, \"hubert.sqlite\");\n }\n } catch {\n // Path doesn't exist, treat as file path\n }\n\n const store = new SqliteKv(sqlitePath);\n const server = Server.newSqlite(config, store);\n console.log(`Starting Hubert server on port ${port} with SQLite storage: ${sqlitePath}`);\n await server.run();\n } else {\n // Use in-memory storage\n const server = Server.newMemory(config);\n console.log(`Starting Hubert server on port ${port} with in-memory storage`);\n await server.run();\n }\n } catch (e) {\n console.error(e instanceof Error ? e.message : e);\n process.exit(1);\n }\n });\n\n// Parse and run\nprogram.parse();\n"],"mappings":"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"}
1
+ {"version":3,"file":"hubert.mjs","names":[],"sources":["../../src/bin/hubert.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * Hubert: Secure Distributed Substrate for Multiparty Transactions\n *\n * A command-line tool for storing and retrieving Gordian Envelopes using\n * distributed storage backends (BitTorrent Mainline DHT or IPFS).\n *\n * Port of bin/hubert.rs from hubert-rust.\n *\n * @module\n */\n\nimport { Command } from \"commander\";\nimport path from \"path\";\n\nimport { ARID } from \"@bcts/components\";\nimport { Envelope } from \"@bcts/envelope\";\nimport { randomData } from \"@bcts/rand\";\n\nimport {\n verbosePrintln,\n IpfsKv,\n MainlineDhtKv,\n HybridKv,\n Server,\n type ServerConfig,\n ServerKvClient,\n SqliteKv,\n} from \"../index.js\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\ntype StorageBackend = \"mainline\" | \"ipfs\" | \"hybrid\" | \"server\";\n\n// =============================================================================\n// Helper Functions\n// =============================================================================\n\n/**\n * Parse an ARID from ur:arid string format.\n *\n * Port of `parse_arid()` from bin/hubert.rs lines 150-153.\n */\nfunction parseArid(s: string): ARID {\n try {\n return ARID.fromUrString(s);\n } catch {\n throw new Error(\"Invalid ARID format. Expected ur:arid\");\n }\n}\n\n/**\n * Parse an Envelope from ur:envelope string format.\n *\n * Port of `parse_envelope()` from bin/hubert.rs lines 155-161.\n */\nfunction parseEnvelope(s: string): Envelope {\n try {\n return Envelope.fromUrString(s);\n } catch {\n throw new Error(\"Invalid envelope format. Expected ur:envelope\");\n }\n}\n\n/**\n * Generate a random envelope with the specified size.\n *\n * Port of `generate_random_envelope()` from bin/hubert.rs lines 163-167.\n */\nfunction generateRandomEnvelope(size: number): Envelope {\n const randomBytes = randomData(size);\n // Pass raw Uint8Array directly - Envelope.new accepts it as EnvelopeEncodableValue\n return Envelope.new(randomBytes);\n}\n\n// =============================================================================\n// Check Functions\n// =============================================================================\n\n/**\n * Check if Mainline DHT is available.\n *\n * Port of `check_mainline()` from bin/hubert.rs lines 169-182.\n */\nasync function checkMainline(): Promise<void> {\n try {\n const dht = await MainlineDhtKv.create();\n await dht.destroy();\n console.log(\"✓ Mainline DHT is available\");\n } catch (e) {\n throw new Error(`✗ Mainline DHT is not available: ${e instanceof Error ? e.message : e}`);\n }\n}\n\n/**\n * Check if IPFS is available.\n *\n * Port of `check_ipfs()` from bin/hubert.rs lines 184-205.\n */\nasync function checkIpfs(port: number): Promise<void> {\n try {\n const url = `http://127.0.0.1:${port}/api/v0/version`;\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 2000);\n\n const response = await fetch(url, {\n method: \"POST\",\n signal: controller.signal,\n });\n\n clearTimeout(timeout);\n\n if (response.ok) {\n console.log(`✓ IPFS is available at 127.0.0.1:${port}`);\n } else {\n throw new Error(`✗ IPFS daemon returned error: ${response.status}`);\n }\n } catch (e) {\n if (e instanceof Error && e.name === \"AbortError\") {\n throw new Error(`✗ IPFS is not available at 127.0.0.1:${port}: connection timeout`);\n }\n throw new Error(\n `✗ IPFS is not available at 127.0.0.1:${port}: ${e instanceof Error ? e.message : e}`,\n );\n }\n}\n\n/**\n * Check if Hubert server is available.\n */\nasync function checkServer(host: string, port: number): Promise<void> {\n try {\n const url = `http://${host}:${port}/health`;\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 2000);\n\n const response = await fetch(url, {\n method: \"GET\",\n signal: controller.signal,\n });\n\n clearTimeout(timeout);\n\n if (response.ok) {\n const json = (await response.json()) as { server?: string; version?: string };\n if (json.server === \"hubert\") {\n const version = json.version ?? \"unknown\";\n console.log(`✓ Hubert server is available at ${host}:${port} (version ${version})`);\n } else {\n throw new Error(`✗ Server at ${host}:${port} is not a Hubert server`);\n }\n } else {\n throw new Error(`✗ Server at ${host}:${port} is not available (status: ${response.status})`);\n }\n } catch (e) {\n if (e instanceof Error && e.name === \"AbortError\") {\n throw new Error(`✗ Server is not available at ${host}:${port}: connection timeout`);\n }\n throw new Error(\n `✗ Server is not available at ${host}:${port}: ${e instanceof Error ? e.message : e}`,\n );\n }\n}\n\n// =============================================================================\n// Put Functions\n// =============================================================================\n\n/**\n * Put envelope to Mainline DHT.\n *\n * Port of `put_mainline()` from bin/hubert.rs lines 207-221.\n */\nasync function putMainline(arid: ARID, envelope: Envelope, verbose: boolean): Promise<void> {\n const store = await MainlineDhtKv.create();\n try {\n await store.put(arid, envelope, undefined, verbose);\n if (verbose) {\n verbosePrintln(\"✓ Stored envelope at ARID\");\n }\n } finally {\n await store.destroy();\n }\n}\n\n/**\n * Put envelope to IPFS.\n *\n * Port of `put_ipfs()` from bin/hubert.rs lines 223-250.\n */\nasync function putIpfs(\n arid: ARID,\n envelope: Envelope,\n port: number,\n pin: boolean,\n verbose: boolean,\n): Promise<void> {\n const url = `http://127.0.0.1:${port}`;\n const store = new IpfsKv(url).withPinContent(pin);\n const result = await store.put(arid, envelope, undefined, verbose);\n\n if (verbose) {\n verbosePrintln(\"✓ Stored envelope at ARID\");\n }\n\n // Extract and print CID if pinning was requested\n if (pin) {\n const cidPart = result.split(\"ipfs://\")[1];\n if (cidPart) {\n console.log(`CID: ${cidPart}`);\n }\n }\n}\n\n/**\n * Put envelope to Hybrid storage.\n *\n * Port of `put_hybrid()` from bin/hubert.rs lines 278-308.\n */\nasync function putHybrid(\n arid: ARID,\n envelope: Envelope,\n port: number,\n pin: boolean,\n verbose: boolean,\n): Promise<void> {\n const url = `http://127.0.0.1:${port}`;\n const store = (await HybridKv.create(url)).withPinContent(pin);\n try {\n const result = await store.put(arid, envelope, undefined, verbose);\n\n if (verbose) {\n verbosePrintln(\"✓ Stored envelope at ARID\");\n }\n\n // Extract and print CID if pinning was requested and IPFS was used\n if (pin && result.includes(\"ipfs://\")) {\n const cidPart = result.split(\"ipfs://\")[1];\n if (cidPart) {\n console.log(`CID: ${cidPart}`);\n }\n }\n } finally {\n await store.destroy();\n }\n}\n\n/**\n * Put envelope to Hubert server.\n *\n * Port of `put_server()` from bin/hubert.rs lines 324-344.\n */\nasync function putServer(\n host: string,\n port: number,\n arid: ARID,\n envelope: Envelope,\n ttl: number | undefined,\n verbose: boolean,\n): Promise<void> {\n const url = `http://${host}:${port}`;\n const store = new ServerKvClient(url);\n await store.put(arid, envelope, ttl, verbose);\n if (verbose) {\n verbosePrintln(\"✓ Stored envelope at ARID\");\n }\n}\n\n// =============================================================================\n// Get Functions\n// =============================================================================\n\n/**\n * Get envelope from Mainline DHT.\n *\n * Port of `get_mainline()` from bin/hubert.rs lines 252-262.\n */\nasync function getMainline(\n arid: ARID,\n timeout: number,\n verbose: boolean,\n): Promise<Envelope | null> {\n const store = await MainlineDhtKv.create();\n try {\n return await store.get(arid, timeout, verbose);\n } finally {\n await store.destroy();\n }\n}\n\n/**\n * Get envelope from IPFS.\n *\n * Port of `get_ipfs()` from bin/hubert.rs lines 264-276.\n */\nasync function getIpfs(\n arid: ARID,\n timeout: number,\n port: number,\n verbose: boolean,\n): Promise<Envelope | null> {\n const url = `http://127.0.0.1:${port}`;\n const store = new IpfsKv(url);\n return await store.get(arid, timeout, verbose);\n}\n\n/**\n * Get envelope from Hybrid storage.\n *\n * Port of `get_hybrid()` from bin/hubert.rs lines 310-322.\n */\nasync function getHybrid(\n arid: ARID,\n timeout: number,\n port: number,\n verbose: boolean,\n): Promise<Envelope | null> {\n const url = `http://127.0.0.1:${port}`;\n const store = await HybridKv.create(url);\n try {\n return await store.get(arid, timeout, verbose);\n } finally {\n await store.destroy();\n }\n}\n\n/**\n * Get envelope from Hubert server.\n *\n * Port of `get_server()` from bin/hubert.rs lines 346-361.\n */\nasync function getServer(\n host: string,\n port: number,\n arid: ARID,\n timeout: number,\n verbose: boolean,\n): Promise<Envelope | null> {\n const url = `http://${host}:${port}`;\n const store = new ServerKvClient(url);\n return await store.get(arid, timeout, verbose);\n}\n\n// =============================================================================\n// CLI Setup\n// =============================================================================\n\nconst program = new Command();\n\nprogram\n .name(\"hubert\")\n .description(\"Distributed substrate for multiparty transactions\")\n .version(\"1.0.0-alpha.1\")\n .option(\"-v, --verbose\", \"Enable verbose logging\", false);\n\n// Generate command\nconst generateCmd = program\n .command(\"generate\")\n .description(\"Generate a new ARID or example Envelope\");\n\ngenerateCmd\n .command(\"arid\")\n .description(\"Generate a new ARID\")\n .action(() => {\n const arid = ARID.new();\n console.log(arid.urString());\n });\n\ngenerateCmd\n .command(\"envelope <size>\")\n .description(\"Generate a test envelope with random data\")\n .action((sizeStr: string) => {\n const size = parseInt(sizeStr, 10);\n if (isNaN(size) || size < 0) {\n console.error(\"Size must be a positive integer\");\n process.exit(1);\n }\n const envelope = generateRandomEnvelope(size);\n console.log(envelope.urString());\n });\n\n// Put command\nprogram\n .command(\"put <arid> <envelope>\")\n .description(\"Store an envelope at an ARID\")\n .option(\"-s, --storage <backend>\", \"Storage backend to use\", \"mainline\")\n .option(\"--host <host>\", \"Server host (for --storage server)\")\n .option(\"--port <port>\", \"Port (for --storage server/ipfs/hybrid)\")\n .option(\"--ttl <seconds>\", \"Time-to-live in seconds (for --storage server)\")\n .option(\"--pin\", \"Pin content in IPFS (only for --storage ipfs or --storage hybrid)\", false)\n .action(\n async (\n aridStr: string,\n envelopeStr: string,\n options: {\n storage: StorageBackend;\n host?: string;\n port?: string;\n ttl?: string;\n pin: boolean;\n },\n ) => {\n const verbose = program.opts()[\"verbose\"] as boolean;\n const storage = options.storage;\n const port = options.port ? parseInt(options.port, 10) : undefined;\n const ttl = options.ttl ? parseInt(options.ttl, 10) : undefined;\n\n try {\n // Validate options based on storage backend\n if (storage === \"mainline\") {\n if (port !== undefined) {\n throw new Error(\"--port option is not supported for --storage mainline\");\n }\n if (options.host !== undefined) {\n throw new Error(\"--host option is not supported for --storage mainline\");\n }\n if (ttl !== undefined) {\n throw new Error(\"--ttl option is only supported for --storage server\");\n }\n if (options.pin) {\n throw new Error(\n \"--pin option is only supported for --storage ipfs or --storage hybrid\",\n );\n }\n } else if (storage === \"ipfs\") {\n if (options.host !== undefined) {\n throw new Error(\n \"--host option is not supported for --storage ipfs (always uses 127.0.0.1)\",\n );\n }\n if (ttl !== undefined) {\n throw new Error(\"--ttl option is only supported for --storage server\");\n }\n } else if (storage === \"hybrid\") {\n if (options.host !== undefined) {\n throw new Error(\n \"--host option is not supported for --storage hybrid (always uses 127.0.0.1)\",\n );\n }\n if (ttl !== undefined) {\n throw new Error(\"--ttl option is only supported for --storage server\");\n }\n } else if (storage === \"server\") {\n if (options.pin) {\n throw new Error(\n \"--pin option is only supported for --storage ipfs or --storage hybrid\",\n );\n }\n }\n\n const arid = parseArid(aridStr);\n const envelope = parseEnvelope(envelopeStr);\n\n switch (storage) {\n case \"mainline\":\n await putMainline(arid, envelope, verbose);\n console.log(\"Stored in Mainline DHT\");\n break;\n case \"ipfs\":\n await putIpfs(arid, envelope, port ?? 5001, options.pin, verbose);\n console.log(\"Stored in IPFS\");\n break;\n case \"hybrid\":\n await putHybrid(arid, envelope, port ?? 5001, options.pin, verbose);\n console.log(\"Stored in Hybrid storage\");\n break;\n case \"server\": {\n const host = options.host ?? \"127.0.0.1\";\n await putServer(host, port ?? 45678, arid, envelope, ttl, verbose);\n console.log(\"Stored in server\");\n break;\n }\n }\n } catch (e) {\n console.error(e instanceof Error ? e.message : e);\n process.exit(1);\n }\n },\n );\n\n// Get command\nprogram\n .command(\"get <arid>\")\n .description(\"Retrieve an envelope by ARID\")\n .option(\"-s, --storage <backend>\", \"Storage backend to use\", \"mainline\")\n .option(\"--host <host>\", \"Server host (for --storage server)\")\n .option(\"--port <port>\", \"Port (for --storage server/ipfs/hybrid)\")\n .option(\"-t, --timeout <seconds>\", \"Maximum time to wait in seconds\", \"30\")\n .action(\n async (\n aridStr: string,\n options: {\n storage: StorageBackend;\n host?: string;\n port?: string;\n timeout: string;\n },\n ) => {\n const verbose = program.opts()[\"verbose\"] as boolean;\n const storage = options.storage;\n const port = options.port ? parseInt(options.port, 10) : undefined;\n const timeout = parseInt(options.timeout, 10);\n\n try {\n // Validate options based on storage backend\n if (storage === \"mainline\") {\n if (port !== undefined) {\n throw new Error(\"--port option is not supported for --storage mainline\");\n }\n if (options.host !== undefined) {\n throw new Error(\"--host option is not supported for --storage mainline\");\n }\n } else if (storage === \"ipfs\") {\n if (options.host !== undefined) {\n throw new Error(\n \"--host option is not supported for --storage ipfs (always uses 127.0.0.1)\",\n );\n }\n } else if (storage === \"hybrid\") {\n if (options.host !== undefined) {\n throw new Error(\n \"--host option is not supported for --storage hybrid (always uses 127.0.0.1)\",\n );\n }\n }\n\n const arid = parseArid(aridStr);\n\n let envelope: Envelope | null;\n switch (storage) {\n case \"mainline\":\n envelope = await getMainline(arid, timeout, verbose);\n break;\n case \"ipfs\":\n envelope = await getIpfs(arid, timeout, port ?? 5001, verbose);\n break;\n case \"hybrid\":\n envelope = await getHybrid(arid, timeout, port ?? 5001, verbose);\n break;\n case \"server\": {\n const host = options.host ?? \"127.0.0.1\";\n envelope = await getServer(host, port ?? 45678, arid, timeout, verbose);\n break;\n }\n }\n\n if (envelope) {\n console.log(envelope.urString());\n } else {\n throw new Error(`Value not found within ${timeout} seconds`);\n }\n } catch (e) {\n console.error(e instanceof Error ? e.message : e);\n process.exit(1);\n }\n },\n );\n\n// Check command\nprogram\n .command(\"check\")\n .description(\"Check if storage backend is available\")\n .option(\"-s, --storage <backend>\", \"Storage backend to use\", \"mainline\")\n .option(\"--host <host>\", \"Server host (for --storage server)\")\n .option(\"--port <port>\", \"Port (for --storage server/ipfs/hybrid)\")\n .action(async (options: { storage: StorageBackend; host?: string; port?: string }) => {\n const storage = options.storage;\n const port = options.port ? parseInt(options.port, 10) : undefined;\n\n try {\n // Validate options based on storage backend\n if (storage === \"mainline\") {\n if (port !== undefined) {\n throw new Error(\"--port option is not supported for --storage mainline\");\n }\n if (options.host !== undefined) {\n throw new Error(\"--host option is not supported for --storage mainline\");\n }\n } else if (storage === \"ipfs\") {\n if (options.host !== undefined) {\n throw new Error(\n \"--host option is not supported for --storage ipfs (always uses 127.0.0.1)\",\n );\n }\n } else if (storage === \"hybrid\") {\n if (options.host !== undefined) {\n throw new Error(\n \"--host option is not supported for --storage hybrid (always uses 127.0.0.1)\",\n );\n }\n }\n\n switch (storage) {\n case \"mainline\":\n await checkMainline();\n break;\n case \"ipfs\":\n await checkIpfs(port ?? 5001);\n break;\n case \"hybrid\":\n await checkMainline();\n await checkIpfs(port ?? 5001);\n console.log(\"✓ Hybrid storage is available (DHT + IPFS)\");\n break;\n case \"server\": {\n const host = options.host ?? \"127.0.0.1\";\n await checkServer(host, port ?? 45678);\n break;\n }\n }\n } catch (e) {\n console.error(e instanceof Error ? e.message : e);\n process.exit(1);\n }\n });\n\n// Server command\nprogram\n .command(\"server\")\n .description(\"Start the Hubert HTTP server\")\n .option(\"--port <port>\", \"Port for the server to listen on\", \"45678\")\n .option(\"--sqlite <path>\", \"SQLite database file path for persistent storage\")\n .action(async (options: { port: string; sqlite?: string }) => {\n const verbose = program.opts()[\"verbose\"] as boolean;\n const port = parseInt(options.port, 10);\n\n try {\n const config: ServerConfig = {\n port,\n maxTtl: 86400, // 24 hours\n verbose,\n };\n\n if (options.sqlite) {\n // Use SQLite storage\n let sqlitePath = options.sqlite;\n // Check if it's a directory\n const fs = await import(\"fs\");\n try {\n const stats = fs.statSync(sqlitePath);\n if (stats.isDirectory()) {\n sqlitePath = path.join(sqlitePath, \"hubert.sqlite\");\n }\n } catch {\n // Path doesn't exist, treat as file path\n }\n\n const store = new SqliteKv(sqlitePath);\n const server = Server.newSqlite(config, store);\n console.log(`Starting Hubert server on port ${port} with SQLite storage: ${sqlitePath}`);\n await server.run();\n } else {\n // Use in-memory storage\n const server = Server.newMemory(config);\n console.log(`Starting Hubert server on port ${port} with in-memory storage`);\n await server.run();\n }\n } catch (e) {\n console.error(e instanceof Error ? e.message : e);\n process.exit(1);\n }\n });\n\n// Parse and run\nprogram.parse();\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- //#region rolldown:runtime
1
+ //#region \0rolldown/runtime.js
2
2
  var __create = Object.create;
3
3
  var __defProp = Object.defineProperty;
4
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -1,14 +1,15 @@
1
- require('../arid-derivation-1CJuU-kZ.cjs');
2
- require('../kv-yjvQa_LH.cjs');
3
- require('../kv-BAmhmMOo.cjs');
4
- const require_hybrid = require('../hybrid-dX5JLumO.cjs');
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+ require('../arid-derivation-CNfUKUp-.cjs');
3
+ require('../kv-1qBQRbV5.cjs');
4
+ require('../kv-BmCAYeR7.cjs');
5
+ const require_kv$2 = require('../kv-DfzRmYtR.cjs');
5
6
 
6
- exports.ContentNotFoundError = require_hybrid.ContentNotFoundError;
7
- exports.HybridError = require_hybrid.HybridError;
8
- exports.HybridKv = require_hybrid.HybridKv;
9
- exports.InvalidReferenceAridError = require_hybrid.InvalidReferenceAridError;
10
- exports.NoIdAssertionError = require_hybrid.NoIdAssertionError;
11
- exports.NotReferenceEnvelopeError = require_hybrid.NotReferenceEnvelopeError;
12
- exports.createReferenceEnvelope = require_hybrid.createReferenceEnvelope;
13
- exports.extractReferenceArid = require_hybrid.extractReferenceArid;
14
- exports.isReferenceEnvelope = require_hybrid.isReferenceEnvelope;
7
+ exports.ContentNotFoundError = require_kv$2.ContentNotFoundError;
8
+ exports.HybridError = require_kv$2.HybridError;
9
+ exports.HybridKv = require_kv$2.HybridKv;
10
+ exports.InvalidReferenceAridError = require_kv$2.InvalidReferenceAridError;
11
+ exports.NoIdAssertionError = require_kv$2.NoIdAssertionError;
12
+ exports.NotReferenceEnvelopeError = require_kv$2.NotReferenceEnvelopeError;
13
+ exports.createReferenceEnvelope = require_kv$2.createReferenceEnvelope;
14
+ exports.extractReferenceArid = require_kv$2.extractReferenceArid;
15
+ exports.isReferenceEnvelope = require_kv$2.isReferenceEnvelope;
@@ -1,3 +1,3 @@
1
1
  import "../kv-store-ww-AUyLd.cjs";
2
- import { a as ContentNotFoundError, c as NoIdAssertionError, i as isReferenceEnvelope, l as NotReferenceEnvelopeError, n as createReferenceEnvelope, o as HybridError, r as extractReferenceArid, s as InvalidReferenceAridError, t as HybridKv } from "../index-CY3TCzIm.cjs";
2
+ import { a as ContentNotFoundError, c as NoIdAssertionError, i as isReferenceEnvelope, l as NotReferenceEnvelopeError, n as createReferenceEnvelope, o as HybridError, r as extractReferenceArid, s as InvalidReferenceAridError, t as HybridKv } from "../kv-Bv__Pl2s.cjs";
3
3
  export { ContentNotFoundError, HybridError, HybridKv, InvalidReferenceAridError, NoIdAssertionError, NotReferenceEnvelopeError, createReferenceEnvelope, extractReferenceArid, isReferenceEnvelope };
@@ -1,3 +1,3 @@
1
- import "../kv-store-DmngWWuw.mjs";
2
- import { a as ContentNotFoundError, c as NoIdAssertionError, i as isReferenceEnvelope, l as NotReferenceEnvelopeError, n as createReferenceEnvelope, o as HybridError, r as extractReferenceArid, s as InvalidReferenceAridError, t as HybridKv } from "../index-T1LHanIb.mjs";
1
+ import "../kv-store-nL8CboDh.mjs";
2
+ import { a as ContentNotFoundError, c as NoIdAssertionError, i as isReferenceEnvelope, l as NotReferenceEnvelopeError, n as createReferenceEnvelope, o as HybridError, r as extractReferenceArid, s as InvalidReferenceAridError, t as HybridKv } from "../kv-BS5Z28iJ.mjs";
3
3
  export { ContentNotFoundError, HybridError, HybridKv, InvalidReferenceAridError, NoIdAssertionError, NotReferenceEnvelopeError, createReferenceEnvelope, extractReferenceArid, isReferenceEnvelope };
@@ -1,6 +1,6 @@
1
1
  import "../arid-derivation-CbqACjdg.mjs";
2
2
  import "../kv-DJiKvypY.mjs";
3
- import "../kv-C-emxv0w.mjs";
4
- import { a as ContentNotFoundError, c as NoIdAssertionError, i as isReferenceEnvelope, l as NotReferenceEnvelopeError, n as createReferenceEnvelope, o as HybridError, r as extractReferenceArid, s as InvalidReferenceAridError, t as HybridKv } from "../hybrid-BZhumygj.mjs";
3
+ import "../kv-DVYfnjvh.mjs";
4
+ import { a as ContentNotFoundError, c as NoIdAssertionError, i as isReferenceEnvelope, l as NotReferenceEnvelopeError, n as createReferenceEnvelope, o as HybridError, r as extractReferenceArid, s as InvalidReferenceAridError, t as HybridKv } from "../kv-CmxPWVB1.mjs";
5
5
 
6
6
  export { ContentNotFoundError, HybridError, HybridKv, InvalidReferenceAridError, NoIdAssertionError, NotReferenceEnvelopeError, createReferenceEnvelope, extractReferenceArid, isReferenceEnvelope };