@hol-org/rb-client 0.1.172 → 0.1.174

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -57,11 +57,10 @@ __export(src_exports, {
57
57
  });
58
58
  module.exports = __toCommonJS(src_exports);
59
59
 
60
- // ../../src/services/registry-broker/client/encryption.ts
61
- var path = __toESM(require("path"), 1);
62
- var import_buffer = require("buffer");
63
- var import_crypto = require("crypto");
64
- var import_secp256k1 = require("@noble/curves/secp256k1.js");
60
+ // ../../src/services/registry-broker/client/base-client.ts
61
+ var import_buffer4 = require("buffer");
62
+ var import_secp256k12 = require("@noble/curves/secp256k1.js");
63
+ var import_zod3 = require("zod");
65
64
 
66
65
  // ../../src/services/registry-broker/schemas.ts
67
66
  var import_zod2 = require("zod");
@@ -1353,6 +1352,50 @@ var skillDeprecationsResponseSchema = import_zod2.z.object({
1353
1352
  name: import_zod2.z.string(),
1354
1353
  items: import_zod2.z.array(skillDeprecationRecordSchema)
1355
1354
  }).passthrough();
1355
+ var skillPublisherQuickstartCommandSchema = import_zod2.z.object({
1356
+ id: import_zod2.z.string(),
1357
+ label: import_zod2.z.string(),
1358
+ description: import_zod2.z.string(),
1359
+ command: import_zod2.z.string(),
1360
+ href: import_zod2.z.string().nullable().optional()
1361
+ }).passthrough();
1362
+ var skillPublisherTemplatePresetSchema = import_zod2.z.object({
1363
+ presetId: import_zod2.z.string(),
1364
+ label: import_zod2.z.string(),
1365
+ description: import_zod2.z.string(),
1366
+ recommendedFor: import_zod2.z.string(),
1367
+ command: import_zod2.z.string()
1368
+ }).passthrough();
1369
+ var skillPublisherMetadataSchema = import_zod2.z.object({
1370
+ cliPackageUrl: import_zod2.z.string(),
1371
+ cliCommand: import_zod2.z.string(),
1372
+ actionMarketplaceUrl: import_zod2.z.string(),
1373
+ repositoryUrl: import_zod2.z.string(),
1374
+ guideUrl: import_zod2.z.string().nullable().optional(),
1375
+ docsUrl: import_zod2.z.string().nullable().optional(),
1376
+ submitUrl: import_zod2.z.string().nullable().optional(),
1377
+ skillsIndexUrl: import_zod2.z.string().nullable().optional(),
1378
+ quickstartCommands: import_zod2.z.array(skillPublisherQuickstartCommandSchema),
1379
+ templatePresets: import_zod2.z.array(skillPublisherTemplatePresetSchema)
1380
+ }).passthrough();
1381
+ var skillTrustTierSchema = import_zod2.z.enum([
1382
+ "unpublished",
1383
+ "published",
1384
+ "verified",
1385
+ "hardened"
1386
+ ]);
1387
+ var skillStatusChecksSchema = import_zod2.z.object({
1388
+ repoCommitIntegrity: import_zod2.z.boolean(),
1389
+ manifestIntegrity: import_zod2.z.boolean(),
1390
+ domainProof: import_zod2.z.boolean()
1391
+ }).passthrough();
1392
+ var skillStatusNextStepSchema = import_zod2.z.object({
1393
+ id: import_zod2.z.string(),
1394
+ label: import_zod2.z.string(),
1395
+ description: import_zod2.z.string(),
1396
+ href: import_zod2.z.string().nullable().optional(),
1397
+ command: import_zod2.z.string().nullable().optional()
1398
+ }).passthrough();
1356
1399
  var skillBadgeMetricSchema = import_zod2.z.enum([
1357
1400
  "version",
1358
1401
  "status",
@@ -1361,10 +1404,22 @@ var skillBadgeMetricSchema = import_zod2.z.enum([
1361
1404
  "manifest",
1362
1405
  "domain",
1363
1406
  "trust",
1407
+ "tier",
1364
1408
  "safety",
1365
1409
  "upvotes",
1366
1410
  "updated"
1367
1411
  ]);
1412
+ var skillStatusResponseSchema = import_zod2.z.object({
1413
+ name: import_zod2.z.string(),
1414
+ version: import_zod2.z.string().nullable(),
1415
+ published: import_zod2.z.boolean(),
1416
+ verifiedDomain: import_zod2.z.boolean(),
1417
+ trustTier: skillTrustTierSchema,
1418
+ badgeMetric: skillBadgeMetricSchema,
1419
+ checks: skillStatusChecksSchema,
1420
+ nextSteps: import_zod2.z.array(skillStatusNextStepSchema),
1421
+ publisher: skillPublisherMetadataSchema.nullable().optional()
1422
+ }).passthrough();
1368
1423
  var skillBadgeStyleSchema = import_zod2.z.enum([
1369
1424
  "flat",
1370
1425
  "flat-square",
@@ -1478,7 +1533,8 @@ var skillRegistryConfigResponseSchema = import_zod2.z.object({
1478
1533
  maxFiles: import_zod2.z.number().int().nullable().optional(),
1479
1534
  maxTotalSizeBytes: import_zod2.z.number().int().nullable().optional(),
1480
1535
  allowedMimeTypes: import_zod2.z.array(import_zod2.z.string()).nullable().optional(),
1481
- network: import_zod2.z.union([import_zod2.z.literal("mainnet"), import_zod2.z.literal("testnet")]).nullable().optional()
1536
+ network: import_zod2.z.union([import_zod2.z.literal("mainnet"), import_zod2.z.literal("testnet")]).nullable().optional(),
1537
+ publisher: skillPublisherMetadataSchema.nullable().optional()
1482
1538
  }).passthrough();
1483
1539
  var skillRegistryOwnershipResponseSchema = import_zod2.z.object({
1484
1540
  name: import_zod2.z.string(),
@@ -1641,285 +1697,171 @@ var skillVerificationDomainProofVerifyResponseSchema = import_zod2.z.object({
1641
1697
  signal: skillVerificationDomainProofSignalSchema
1642
1698
  }).passthrough();
1643
1699
 
1644
- // ../../src/utils/is-browser.ts
1645
- var isBrowser = typeof window !== "undefined" && typeof window.document !== "undefined";
1646
-
1647
- // ../../src/utils/dynamic-import.ts
1648
- var nodeRequire;
1649
- function isModuleNotFound(specifier, error) {
1650
- if (!error || typeof error !== "object") {
1700
+ // ../../src/services/registry-broker/client/chat-history.ts
1701
+ var import_buffer = require("buffer");
1702
+ function identitiesMatch(a, b) {
1703
+ if (!a && !b) {
1704
+ return true;
1705
+ }
1706
+ if (!a || !b) {
1651
1707
  return false;
1652
1708
  }
1653
- const code = Reflect.get(error, "code");
1654
- const message = Reflect.get(error, "message");
1655
- const messageText = typeof message === "string" ? message : "";
1656
- if (typeof code === "string" && code.includes("MODULE_NOT_FOUND")) {
1657
- return messageText.includes(specifier);
1709
+ if (a.uaid && b.uaid && a.uaid.toLowerCase() === b.uaid.toLowerCase()) {
1710
+ return true;
1658
1711
  }
1659
- if (messageText) {
1660
- const lowered = messageText.toLowerCase();
1661
- if (lowered.includes("cannot find module") || lowered.includes("module not found") || lowered.includes("cannot find package")) {
1662
- return lowered.includes(specifier.toLowerCase());
1663
- }
1712
+ if (a.ledgerAccountId && b.ledgerAccountId && a.ledgerAccountId.toLowerCase() === b.ledgerAccountId.toLowerCase()) {
1713
+ return true;
1714
+ }
1715
+ if (a.userId && b.userId && a.userId === b.userId) {
1716
+ return true;
1717
+ }
1718
+ if (a.email && b.email && a.email.toLowerCase() === b.email.toLowerCase()) {
1719
+ return true;
1664
1720
  }
1665
1721
  return false;
1666
1722
  }
1667
- async function resolveNodeRequire() {
1668
- if (nodeRequire !== void 0) {
1669
- return nodeRequire;
1723
+ async function fetchHistorySnapshot(conversationContexts, client, sessionId, options) {
1724
+ if (!sessionId || sessionId.trim().length === 0) {
1725
+ throw new Error("sessionId is required to fetch chat history");
1670
1726
  }
1671
- if (isBrowser) {
1672
- nodeRequire = null;
1673
- return nodeRequire;
1727
+ const raw = await client.requestJson(
1728
+ `/chat/session/${encodeURIComponent(sessionId)}/history`,
1729
+ {
1730
+ method: "GET"
1731
+ }
1732
+ );
1733
+ const snapshot = client.parseWithSchema(
1734
+ raw,
1735
+ chatHistorySnapshotResponseSchema,
1736
+ "chat history snapshot response"
1737
+ );
1738
+ return attachDecryptedHistory(
1739
+ conversationContexts,
1740
+ client,
1741
+ sessionId,
1742
+ snapshot,
1743
+ options
1744
+ );
1745
+ }
1746
+ function attachDecryptedHistory(conversationContexts, client, sessionId, snapshot, options) {
1747
+ const shouldDecrypt = options?.decrypt !== void 0 ? options.decrypt : client.encryptionOptions?.autoDecryptHistory === true;
1748
+ if (!shouldDecrypt) {
1749
+ return snapshot;
1674
1750
  }
1675
- try {
1676
- const globalObject = typeof global !== "undefined" ? global : globalThis;
1677
- const req = globalObject.process?.mainModule?.require ?? globalObject.require;
1678
- nodeRequire = typeof req === "function" && typeof req.resolve === "function" ? req : null;
1679
- } catch {
1680
- nodeRequire = null;
1751
+ const requiresContext = snapshot.history.some(
1752
+ (entry) => Boolean(entry.cipherEnvelope)
1753
+ );
1754
+ if (!requiresContext) {
1755
+ return {
1756
+ ...snapshot,
1757
+ decryptedHistory: snapshot.history.map((entry) => ({
1758
+ entry,
1759
+ plaintext: entry.content
1760
+ }))
1761
+ };
1681
1762
  }
1682
- return nodeRequire;
1763
+ const context = resolveDecryptionContext(
1764
+ conversationContexts,
1765
+ client,
1766
+ sessionId,
1767
+ options
1768
+ );
1769
+ if (!context) {
1770
+ throw new Error(
1771
+ "Unable to decrypt chat history: encryption context unavailable"
1772
+ );
1773
+ }
1774
+ const decryptedHistory = snapshot.history.map((entry) => ({
1775
+ entry,
1776
+ plaintext: decryptHistoryEntryFromContext(client, entry, context)
1777
+ }));
1778
+ return { ...snapshot, decryptedHistory };
1683
1779
  }
1684
- async function dynamicImport(specifier) {
1685
- try {
1686
- return await import(specifier);
1687
- } catch (error) {
1688
- if (isModuleNotFound(specifier, error)) {
1689
- return null;
1690
- }
1691
- throw error;
1780
+ function registerConversationContextForEncryption(conversationContexts, context) {
1781
+ const normalized = {
1782
+ sessionId: context.sessionId,
1783
+ sharedSecret: import_buffer.Buffer.from(context.sharedSecret),
1784
+ identity: context.identity ? { ...context.identity } : void 0
1785
+ };
1786
+ const entries = conversationContexts.get(context.sessionId) ?? [];
1787
+ const existingIndex = entries.findIndex(
1788
+ (existing) => identitiesMatch(existing.identity, normalized.identity)
1789
+ );
1790
+ if (existingIndex >= 0) {
1791
+ entries[existingIndex] = normalized;
1792
+ } else {
1793
+ entries.push(normalized);
1692
1794
  }
1795
+ conversationContexts.set(context.sessionId, entries);
1693
1796
  }
1694
- async function optionalImport(specifier, options = {}) {
1695
- if (isBrowser) {
1696
- return dynamicImport(specifier);
1797
+ function resolveDecryptionContext(conversationContexts, client, sessionId, options) {
1798
+ if (options?.sharedSecret) {
1799
+ return {
1800
+ sessionId,
1801
+ sharedSecret: client.normalizeSharedSecret(options.sharedSecret),
1802
+ identity: options.identity
1803
+ };
1697
1804
  }
1698
- if (!options.preferImport) {
1699
- const requireFn = await resolveNodeRequire();
1700
- if (requireFn) {
1701
- try {
1702
- return requireFn(specifier);
1703
- } catch (error) {
1704
- if (!isModuleNotFound(specifier, error)) {
1705
- throw error;
1706
- }
1707
- }
1805
+ const contexts = conversationContexts.get(sessionId);
1806
+ if (!contexts || contexts.length === 0) {
1807
+ return null;
1808
+ }
1809
+ if (options?.identity) {
1810
+ const match = contexts.find(
1811
+ (context) => identitiesMatch(context.identity, options.identity)
1812
+ );
1813
+ if (match) {
1814
+ return match;
1708
1815
  }
1709
1816
  }
1710
- return dynamicImport(specifier);
1817
+ return contexts[0];
1711
1818
  }
1712
- function optionalImportSync(specifier) {
1713
- if (isBrowser) {
1714
- return null;
1819
+ function decryptHistoryEntryFromContext(client, entry, context) {
1820
+ const envelope = entry.cipherEnvelope;
1821
+ if (!envelope) {
1822
+ return entry.content;
1715
1823
  }
1824
+ const secret = import_buffer.Buffer.from(context.sharedSecret);
1716
1825
  try {
1717
- const globalObject = typeof global !== "undefined" ? global : globalThis;
1718
- const req = globalObject.process?.mainModule?.require ?? globalObject.require;
1719
- if (typeof req === "function" && typeof req.resolve === "function") {
1720
- return req(specifier);
1721
- }
1722
- } catch (error) {
1723
- if (!isModuleNotFound(specifier, error)) {
1724
- throw error;
1725
- }
1826
+ return client.encryption.decryptCipherEnvelope({
1827
+ envelope,
1828
+ sharedSecret: secret
1829
+ });
1830
+ } catch (_error) {
1831
+ return null;
1726
1832
  }
1727
- return null;
1728
1833
  }
1729
1834
 
1730
- // ../../src/services/registry-broker/client/encryption.ts
1731
- var getFs = async () => {
1732
- const fsModule = await optionalImport("node:fs");
1733
- if (fsModule && typeof fsModule.existsSync === "function" && typeof fsModule.readFileSync === "function" && typeof fsModule.writeFileSync === "function" && typeof fsModule.appendFileSync === "function") {
1734
- return fsModule;
1835
+ // ../../src/services/registry-broker/client/utils.ts
1836
+ var DEFAULT_USER_AGENT = "@hol-org/rb-client";
1837
+ var DEFAULT_PROGRESS_INTERVAL_MS = 1500;
1838
+ var DEFAULT_PROGRESS_TIMEOUT_MS = 5 * 60 * 1e3;
1839
+ var DEFAULT_BASE_URL = "https://hol.org/registry/api/v1";
1840
+ var JSON_CONTENT_TYPE = /application\/json/i;
1841
+ var DEFAULT_HISTORY_TOP_UP_HBAR = 0.25;
1842
+ var MINIMUM_REGISTRATION_AUTO_TOP_UP_CREDITS = 1;
1843
+ var stripTrailingSlashes = (value) => {
1844
+ let end = value.length;
1845
+ while (end > 0 && value.charCodeAt(end - 1) === 47) {
1846
+ end -= 1;
1735
1847
  }
1736
- return null;
1848
+ return end === value.length ? value : value.slice(0, end);
1737
1849
  };
1738
- async function registerEncryptionKey(client, payload) {
1739
- const raw = await client.requestJson("/encryption/keys", {
1740
- method: "POST",
1741
- headers: { "content-type": "application/json" },
1742
- body: payload
1743
- });
1744
- return client.parseWithSchema(
1745
- raw,
1746
- registerEncryptionKeyResponseSchema,
1747
- "register encryption key response"
1748
- );
1749
- }
1750
- function normalizeAutoRegisterIdentity(config) {
1751
- const identity = {};
1752
- if (config.uaid) {
1753
- identity.uaid = config.uaid;
1754
- }
1755
- if (config.ledgerAccountId) {
1756
- identity.ledgerAccountId = config.ledgerAccountId;
1757
- if (config.ledgerNetwork) {
1758
- identity.ledgerNetwork = config.ledgerNetwork;
1759
- }
1850
+ var createAbortError = () => typeof DOMException === "function" ? new DOMException("Aborted", "AbortError") : new Error("The operation was aborted");
1851
+ var normaliseHeaderName = (name) => name.trim().toLowerCase();
1852
+ var isBrowserRuntime = () => typeof window !== "undefined" && typeof window.fetch === "function";
1853
+ var toJsonValue = (value) => {
1854
+ if (value === null) {
1855
+ return null;
1760
1856
  }
1761
- if (config.email) {
1762
- identity.email = config.email;
1857
+ if (value instanceof Date) {
1858
+ return value.toISOString();
1763
1859
  }
1764
- if (identity.uaid || identity.ledgerAccountId || identity.email) {
1765
- return identity;
1860
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
1861
+ return value;
1766
1862
  }
1767
- return null;
1768
- }
1769
- function derivePublicKeyFromPrivateKey(client, privateKey) {
1770
- const normalized = client.hexToBuffer(privateKey);
1771
- const publicKey = import_secp256k1.secp256k1.getPublicKey(normalized, true);
1772
- return import_buffer.Buffer.from(publicKey).toString("hex");
1773
- }
1774
- async function resolveAutoRegisterKeyMaterial(client, config) {
1775
- if (config.publicKey?.trim()) {
1776
- return { publicKey: config.publicKey.trim() };
1777
- }
1778
- let privateKey = config.privateKey?.trim();
1779
- const envVar = config.envVar ?? "RB_ENCRYPTION_PRIVATE_KEY";
1780
- if (!privateKey && envVar && process?.env?.[envVar]?.trim()) {
1781
- privateKey = process.env[envVar]?.trim();
1782
- }
1783
- if (!privateKey && config.generateIfMissing) {
1784
- const pair = await client.generateEncryptionKeyPair({
1785
- keyType: config.keyType ?? "secp256k1",
1786
- envVar,
1787
- envPath: config.envPath,
1788
- overwrite: config.overwriteEnv
1789
- });
1790
- return { publicKey: pair.publicKey, privateKey: pair.privateKey };
1791
- }
1792
- if (privateKey) {
1793
- const publicKey = derivePublicKeyFromPrivateKey(client, privateKey);
1794
- return { publicKey, privateKey };
1795
- }
1796
- return null;
1797
- }
1798
- async function autoRegisterEncryptionKey(client, config) {
1799
- const identity = normalizeAutoRegisterIdentity(config);
1800
- if (!identity) {
1801
- throw new Error(
1802
- "Auto-registration requires uaid, ledgerAccountId, or email"
1803
- );
1804
- }
1805
- const material = await resolveAutoRegisterKeyMaterial(client, config);
1806
- if (!material) {
1807
- throw new Error(
1808
- "Unable to resolve encryption public key for auto-registration"
1809
- );
1810
- }
1811
- await registerEncryptionKey(client, {
1812
- keyType: config.keyType ?? "secp256k1",
1813
- publicKey: material.publicKey,
1814
- ...identity
1815
- });
1816
- return material;
1817
- }
1818
- async function ensureAgentEncryptionKey(client, options) {
1819
- return autoRegisterEncryptionKey(client, {
1820
- ...options,
1821
- uaid: options.uaid,
1822
- enabled: true
1823
- });
1824
- }
1825
- function createEncryptionApi(client) {
1826
- return {
1827
- registerKey: (payload) => registerEncryptionKey(client, payload),
1828
- generateEphemeralKeyPair: () => client.createEphemeralKeyPair(),
1829
- deriveSharedSecret: (options) => client.deriveSharedSecret(options),
1830
- encryptCipherEnvelope: (options) => client.buildCipherEnvelope(options),
1831
- decryptCipherEnvelope: (options) => client.openCipherEnvelope(options),
1832
- ensureAgentKey: (options) => ensureAgentEncryptionKey(client, options)
1833
- };
1834
- }
1835
- async function bootstrapEncryptionOptions(client, options) {
1836
- if (!options?.autoRegister || options.autoRegister.enabled === false) {
1837
- return null;
1838
- }
1839
- return autoRegisterEncryptionKey(client, options.autoRegister);
1840
- }
1841
- async function generateEncryptionKeyPair(client, options = {}) {
1842
- client.assertNodeRuntime("generateEncryptionKeyPair");
1843
- const keyType = options.keyType ?? "secp256k1";
1844
- if (keyType !== "secp256k1") {
1845
- throw new Error("Only secp256k1 key generation is supported currently");
1846
- }
1847
- const privateKeyBytes = (0, import_crypto.randomBytes)(32);
1848
- const privateKey = import_buffer.Buffer.from(privateKeyBytes).toString("hex");
1849
- const publicKeyBytes = import_secp256k1.secp256k1.getPublicKey(privateKeyBytes, true);
1850
- const publicKey = import_buffer.Buffer.from(publicKeyBytes).toString("hex");
1851
- const envVar = options.envVar ?? "RB_ENCRYPTION_PRIVATE_KEY";
1852
- const resolvedPath = options.envPath ? path.resolve(options.envPath) : void 0;
1853
- if (resolvedPath) {
1854
- const fsModule = await getFs();
1855
- if (!fsModule) {
1856
- throw new Error(
1857
- "File system module is not available; cannot write encryption key env file"
1858
- );
1859
- }
1860
- const envLine = `${envVar}=${privateKey}`;
1861
- if (fsModule.existsSync(resolvedPath)) {
1862
- const content = fsModule.readFileSync(resolvedPath, "utf-8");
1863
- const lineRegex = new RegExp(`^${envVar}=.*$`, "m");
1864
- if (lineRegex.test(content)) {
1865
- if (!options.overwrite) {
1866
- throw new Error(
1867
- `${envVar} already exists in ${resolvedPath}; set overwrite=true to replace it`
1868
- );
1869
- }
1870
- const updated = content.replace(lineRegex, envLine);
1871
- fsModule.writeFileSync(resolvedPath, updated);
1872
- } else {
1873
- const needsNewline = !content.endsWith("\n");
1874
- fsModule.appendFileSync(
1875
- resolvedPath,
1876
- `${needsNewline ? "\n" : ""}${envLine}
1877
- `
1878
- );
1879
- }
1880
- } else {
1881
- fsModule.writeFileSync(resolvedPath, `${envLine}
1882
- `);
1883
- }
1884
- }
1885
- return {
1886
- privateKey,
1887
- publicKey,
1888
- envPath: resolvedPath,
1889
- envVar
1890
- };
1891
- }
1892
-
1893
- // ../../src/services/registry-broker/client/utils.ts
1894
- var DEFAULT_USER_AGENT = "@hol-org/rb-client";
1895
- var DEFAULT_PROGRESS_INTERVAL_MS = 1500;
1896
- var DEFAULT_PROGRESS_TIMEOUT_MS = 5 * 60 * 1e3;
1897
- var DEFAULT_BASE_URL = "https://hol.org/registry/api/v1";
1898
- var JSON_CONTENT_TYPE = /application\/json/i;
1899
- var DEFAULT_HISTORY_TOP_UP_HBAR = 0.25;
1900
- var MINIMUM_REGISTRATION_AUTO_TOP_UP_CREDITS = 1;
1901
- var stripTrailingSlashes = (value) => {
1902
- let end = value.length;
1903
- while (end > 0 && value.charCodeAt(end - 1) === 47) {
1904
- end -= 1;
1905
- }
1906
- return end === value.length ? value : value.slice(0, end);
1907
- };
1908
- var createAbortError = () => typeof DOMException === "function" ? new DOMException("Aborted", "AbortError") : new Error("The operation was aborted");
1909
- var normaliseHeaderName = (name) => name.trim().toLowerCase();
1910
- var isBrowserRuntime = () => typeof window !== "undefined" && typeof window.fetch === "function";
1911
- var toJsonValue = (value) => {
1912
- if (value === null) {
1913
- return null;
1914
- }
1915
- if (value instanceof Date) {
1916
- return value.toISOString();
1917
- }
1918
- if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
1919
- return value;
1920
- }
1921
- if (Array.isArray(value)) {
1922
- return value.map((item) => item === void 0 ? null : toJsonValue(item));
1863
+ if (Array.isArray(value)) {
1864
+ return value.map((item) => item === void 0 ? null : toJsonValue(item));
1923
1865
  }
1924
1866
  if (typeof value === "object") {
1925
1867
  const result = {};
@@ -2113,1926 +2055,2091 @@ function buildSearchQuery(params) {
2113
2055
  return queryString.length > 0 ? `?${queryString}` : "";
2114
2056
  }
2115
2057
 
2116
- // ../../src/services/registry-broker/client/errors.ts
2117
- var RegistryBrokerError = class extends Error {
2118
- constructor(message, details) {
2119
- super(message);
2120
- this.status = details.status;
2121
- this.statusText = details.statusText;
2122
- this.body = details.body;
2123
- }
2124
- };
2125
- var RegistryBrokerParseError = class extends Error {
2126
- constructor(message, cause, rawValue) {
2127
- super(message);
2128
- this.cause = cause;
2129
- this.rawValue = rawValue;
2058
+ // ../../src/services/registry-broker/client/encrypted-chat-manager.ts
2059
+ var EncryptionUnavailableError = class extends Error {
2060
+ constructor(sessionId, summary) {
2061
+ super("Encryption is not enabled for this session");
2062
+ this.sessionId = sessionId;
2063
+ this.summary = summary;
2130
2064
  }
2131
2065
  };
2132
-
2133
- // ../../src/services/registry-broker/client/search.ts
2134
- function buildVectorFallbackSearchParams(request) {
2135
- const params = {
2136
- q: request.query
2137
- };
2138
- let effectiveLimit;
2139
- if (typeof request.limit === "number" && Number.isFinite(request.limit)) {
2140
- effectiveLimit = request.limit;
2141
- params.limit = request.limit;
2142
- }
2143
- if (typeof request.offset === "number" && Number.isFinite(request.offset) && request.offset > 0) {
2144
- const limit = effectiveLimit && effectiveLimit > 0 ? effectiveLimit : 20;
2145
- params.limit = limit;
2146
- params.page = Math.floor(request.offset / limit) + 1;
2147
- }
2148
- if (request.filter?.registry) {
2149
- params.registry = request.filter.registry;
2066
+ var EncryptedChatManager = class {
2067
+ constructor(client) {
2068
+ this.client = client;
2150
2069
  }
2151
- if (request.filter?.protocols?.length) {
2152
- params.protocols = [...request.filter.protocols];
2070
+ registerConversationContext(context) {
2071
+ this.client.registerConversationContextForEncryption(context);
2153
2072
  }
2154
- if (request.filter?.adapter?.length) {
2155
- params.adapters = [...request.filter.adapter];
2073
+ async startSession(options) {
2074
+ await this.client.encryptionReady();
2075
+ const session = await this.client.chat.createSession({
2076
+ uaid: options.uaid,
2077
+ senderUaid: options.senderUaid,
2078
+ encryptionRequested: true,
2079
+ historyTtlSeconds: options.historyTtlSeconds,
2080
+ auth: options.auth
2081
+ });
2082
+ options.onSessionCreated?.(session.sessionId);
2083
+ const summary = session.encryption;
2084
+ if (!summary?.enabled) {
2085
+ throw new EncryptionUnavailableError(
2086
+ session.sessionId,
2087
+ session.encryption ?? null
2088
+ );
2089
+ }
2090
+ const handle = await this.establishRequesterContext({
2091
+ sessionId: session.sessionId,
2092
+ summary,
2093
+ senderUaid: options.senderUaid,
2094
+ handshakeTimeoutMs: options.handshakeTimeoutMs,
2095
+ pollIntervalMs: options.pollIntervalMs
2096
+ });
2097
+ return handle;
2156
2098
  }
2157
- if (request.filter?.capabilities?.length) {
2158
- params.capabilities = request.filter.capabilities.map(
2159
- (value) => typeof value === "number" ? value.toString(10) : value
2099
+ async acceptSession(options) {
2100
+ await this.client.encryptionReady();
2101
+ const summary = await this.waitForEncryptionSummary(
2102
+ options.sessionId,
2103
+ options.handshakeTimeoutMs,
2104
+ options.pollIntervalMs
2160
2105
  );
2106
+ const handle = await this.establishResponderContext({
2107
+ sessionId: options.sessionId,
2108
+ summary,
2109
+ responderUaid: options.responderUaid,
2110
+ handshakeTimeoutMs: options.handshakeTimeoutMs,
2111
+ pollIntervalMs: options.pollIntervalMs
2112
+ });
2113
+ return handle;
2161
2114
  }
2162
- if (request.filter?.type) {
2163
- params.type = request.filter.type;
2164
- }
2165
- return params;
2166
- }
2167
- function convertSearchResultToVectorResponse(result) {
2168
- const hits = result.hits.map((agent) => ({
2169
- agent,
2170
- score: 0,
2171
- highlights: {}
2172
- }));
2173
- const total = result.total;
2174
- const limit = result.limit;
2175
- const page = result.page;
2176
- const totalVisible = page * limit;
2177
- const limited = total > totalVisible || page > 1;
2178
- return {
2179
- hits,
2180
- total,
2181
- took: 0,
2182
- totalAvailable: total,
2183
- visible: hits.length,
2184
- limited,
2185
- credits_used: 0
2186
- };
2187
- }
2188
- async function search(client, params = {}) {
2189
- const query = buildSearchQuery(params);
2190
- const raw = await client.requestJson(`/search${query}`, {
2191
- method: "GET"
2192
- });
2193
- return client.parseWithSchema(raw, searchResponseSchema, "search response");
2194
- }
2195
- async function delegate(client, request) {
2196
- const raw = await client.requestJson("/delegate", {
2197
- method: "POST",
2198
- body: request,
2199
- headers: { "content-type": "application/json" }
2200
- });
2201
- return client.parseWithSchema(
2202
- raw,
2203
- delegationPlanResponseSchema,
2204
- "delegate response"
2205
- );
2206
- }
2207
- async function stats(client) {
2208
- const raw = await client.requestJson("/stats", { method: "GET" });
2209
- return client.parseWithSchema(raw, statsResponseSchema, "stats response");
2210
- }
2211
- async function registries(client) {
2212
- const raw = await client.requestJson("/registries", {
2213
- method: "GET"
2214
- });
2215
- return client.parseWithSchema(
2216
- raw,
2217
- registriesResponseSchema,
2218
- "registries response"
2219
- );
2220
- }
2221
- async function getAdditionalRegistries(client) {
2222
- const raw = await client.requestJson(
2223
- "/register/additional-registries",
2224
- {
2225
- method: "GET"
2115
+ async establishRequesterContext(params) {
2116
+ const keyPair = this.client.encryption.generateEphemeralKeyPair();
2117
+ await this.client.chat.submitEncryptionHandshake(params.sessionId, {
2118
+ role: "requester",
2119
+ keyType: "secp256k1",
2120
+ ephemeralPublicKey: keyPair.publicKey,
2121
+ uaid: params.senderUaid ?? params.summary.requester?.uaid ?? void 0
2122
+ });
2123
+ const { summary, record } = await this.waitForHandshakeCompletion(
2124
+ params.sessionId,
2125
+ params.handshakeTimeoutMs,
2126
+ params.pollIntervalMs
2127
+ );
2128
+ const responderKey = record.responder?.ephemeralPublicKey;
2129
+ if (!responderKey) {
2130
+ throw new Error("Responder handshake was not completed in time");
2226
2131
  }
2227
- );
2228
- return client.parseWithSchema(
2229
- raw,
2230
- additionalRegistryCatalogResponseSchema,
2231
- "additional registry catalog response"
2232
- );
2233
- }
2234
- async function popularSearches(client) {
2235
- const raw = await client.requestJson("/popular", {
2236
- method: "GET"
2237
- });
2238
- return client.parseWithSchema(
2239
- raw,
2240
- popularResponseSchema,
2241
- "popular searches response"
2242
- );
2243
- }
2244
- async function listProtocols(client) {
2245
- const raw = await client.requestJson("/protocols", {
2246
- method: "GET"
2247
- });
2248
- return client.parseWithSchema(
2249
- raw,
2250
- protocolsResponseSchema,
2251
- "protocols response"
2252
- );
2253
- }
2254
- async function detectProtocol(client, message) {
2255
- const raw = await client.requestJson("/detect-protocol", {
2256
- method: "POST",
2257
- body: { message },
2258
- headers: { "content-type": "application/json" }
2259
- });
2260
- return client.parseWithSchema(
2261
- raw,
2262
- detectProtocolResponseSchema,
2263
- "detect protocol response"
2264
- );
2265
- }
2266
- async function registrySearchByNamespace(client, registry, query) {
2267
- const params = new URLSearchParams();
2268
- if (query) {
2269
- params.set("q", query);
2132
+ const sharedSecret = this.client.encryption.deriveSharedSecret({
2133
+ privateKey: keyPair.privateKey,
2134
+ peerPublicKey: responderKey
2135
+ }).subarray();
2136
+ const recipients = this.buildRecipients(summary);
2137
+ return this.createHandle({
2138
+ sessionId: params.sessionId,
2139
+ sharedSecret,
2140
+ summary,
2141
+ recipients,
2142
+ identity: summary.requester ?? void 0
2143
+ });
2270
2144
  }
2271
- const suffix = params.size > 0 ? `?${params.toString()}` : "";
2272
- const raw = await client.requestJson(
2273
- `/registries/${encodeURIComponent(registry)}/search${suffix}`,
2274
- {
2275
- method: "GET"
2145
+ async establishResponderContext(params) {
2146
+ const keyPair = this.client.encryption.generateEphemeralKeyPair();
2147
+ await this.client.chat.submitEncryptionHandshake(params.sessionId, {
2148
+ role: "responder",
2149
+ keyType: "secp256k1",
2150
+ ephemeralPublicKey: keyPair.publicKey,
2151
+ uaid: params.responderUaid ?? params.summary.responder?.uaid ?? void 0
2152
+ });
2153
+ const { summary, record } = await this.waitForHandshakeCompletion(
2154
+ params.sessionId,
2155
+ params.handshakeTimeoutMs,
2156
+ params.pollIntervalMs
2157
+ );
2158
+ const requesterKey = record.requester?.ephemeralPublicKey;
2159
+ if (!requesterKey) {
2160
+ throw new Error("Requester handshake was not detected in time");
2276
2161
  }
2277
- );
2278
- return client.parseWithSchema(
2279
- raw,
2280
- registrySearchByNamespaceSchema,
2281
- "registry search response"
2282
- );
2162
+ const sharedSecret = this.client.encryption.deriveSharedSecret({
2163
+ privateKey: keyPair.privateKey,
2164
+ peerPublicKey: requesterKey
2165
+ }).subarray();
2166
+ const recipients = this.buildRecipients(summary);
2167
+ return this.createHandle({
2168
+ sessionId: params.sessionId,
2169
+ sharedSecret,
2170
+ summary,
2171
+ recipients,
2172
+ identity: summary.responder ?? void 0
2173
+ });
2174
+ }
2175
+ async waitForHandshakeCompletion(sessionId, timeoutMs = 3e4, pollIntervalMs = 1e3) {
2176
+ const deadline = Date.now() + timeoutMs;
2177
+ while (true) {
2178
+ const status = await this.client.chat.getEncryptionStatus(sessionId);
2179
+ const summary = status.encryption;
2180
+ const record = summary?.handshake;
2181
+ if (summary && record && record.status === "complete") {
2182
+ return { summary, record };
2183
+ }
2184
+ if (Date.now() >= deadline) {
2185
+ throw new Error("Timed out waiting for encrypted handshake completion");
2186
+ }
2187
+ await this.delay(pollIntervalMs);
2188
+ }
2189
+ }
2190
+ async waitForEncryptionSummary(sessionId, _timeoutMs = 3e4, _pollIntervalMs = 1e3) {
2191
+ const status = await this.client.chat.getEncryptionStatus(sessionId);
2192
+ if (!status.encryption?.enabled) {
2193
+ throw new EncryptionUnavailableError(
2194
+ sessionId,
2195
+ status.encryption ?? null
2196
+ );
2197
+ }
2198
+ return status.encryption;
2199
+ }
2200
+ buildRecipients(summary) {
2201
+ const candidates = [summary.requester, summary.responder].filter(Boolean);
2202
+ const normalized = candidates.map((candidate) => {
2203
+ if (!candidate) {
2204
+ return null;
2205
+ }
2206
+ const recipient = {};
2207
+ if (candidate.uaid) {
2208
+ recipient.uaid = candidate.uaid;
2209
+ }
2210
+ if (candidate.ledgerAccountId) {
2211
+ recipient.ledgerAccountId = candidate.ledgerAccountId;
2212
+ }
2213
+ if (candidate.userId) {
2214
+ recipient.userId = candidate.userId;
2215
+ }
2216
+ if (candidate.email) {
2217
+ recipient.email = candidate.email;
2218
+ }
2219
+ return recipient;
2220
+ }).filter(
2221
+ (entry) => Boolean(
2222
+ entry?.uaid || entry?.ledgerAccountId || entry?.userId || entry?.email
2223
+ )
2224
+ );
2225
+ if (normalized.length > 0) {
2226
+ return normalized;
2227
+ }
2228
+ if (summary.responder?.uaid) {
2229
+ return [{ uaid: summary.responder.uaid }];
2230
+ }
2231
+ return [];
2232
+ }
2233
+ createHandle(context) {
2234
+ const sharedSecret = context.sharedSecret;
2235
+ const uaid = context.summary.requester?.uaid ?? context.summary.responder?.uaid ?? context.identity?.uaid;
2236
+ const decryptHistoryEntry = (entry) => this.decryptEntry(entry, context.identity, sharedSecret);
2237
+ const fetchHistory = async (options) => {
2238
+ const snapshot = await this.client.fetchHistorySnapshot(
2239
+ context.sessionId,
2240
+ options
2241
+ );
2242
+ if (snapshot.decryptedHistory) {
2243
+ return snapshot.decryptedHistory;
2244
+ }
2245
+ return snapshot.history.map((entry) => ({
2246
+ entry,
2247
+ plaintext: decryptHistoryEntry(entry)
2248
+ }));
2249
+ };
2250
+ const handle = {
2251
+ sessionId: context.sessionId,
2252
+ mode: "encrypted",
2253
+ summary: context.summary,
2254
+ send: async (options) => {
2255
+ const recipients = options.recipients ?? context.recipients;
2256
+ return this.client.chat.sendMessage({
2257
+ sessionId: context.sessionId,
2258
+ message: options.message ?? "[ciphertext omitted]",
2259
+ streaming: options.streaming,
2260
+ auth: options.auth,
2261
+ uaid,
2262
+ encryption: {
2263
+ plaintext: options.plaintext,
2264
+ sharedSecret: Buffer.from(sharedSecret),
2265
+ recipients
2266
+ }
2267
+ });
2268
+ },
2269
+ decryptHistoryEntry,
2270
+ fetchHistory
2271
+ };
2272
+ this.registerConversationContext({
2273
+ sessionId: context.sessionId,
2274
+ sharedSecret,
2275
+ identity: context.identity
2276
+ });
2277
+ return handle;
2278
+ }
2279
+ decryptEntry(entry, identity, fallbackSecret) {
2280
+ const envelope = entry.cipherEnvelope;
2281
+ if (!envelope) {
2282
+ return null;
2283
+ }
2284
+ const secret = Buffer.from(fallbackSecret);
2285
+ try {
2286
+ return this.client.encryption.decryptCipherEnvelope({
2287
+ envelope,
2288
+ sharedSecret: secret
2289
+ });
2290
+ } catch (_error) {
2291
+ return null;
2292
+ }
2293
+ }
2294
+ recipientMatches(candidate, target) {
2295
+ if (target.uaid && candidate.uaid?.toLowerCase() === target.uaid.toLowerCase()) {
2296
+ return true;
2297
+ }
2298
+ if (target.ledgerAccountId && candidate.ledgerAccountId?.toLowerCase() === target.ledgerAccountId.toLowerCase()) {
2299
+ return true;
2300
+ }
2301
+ if (target.userId && candidate.userId === target.userId) {
2302
+ return true;
2303
+ }
2304
+ if (target.email && candidate.email?.toLowerCase() === target.email.toLowerCase()) {
2305
+ return true;
2306
+ }
2307
+ return false;
2308
+ }
2309
+ async delay(ms) {
2310
+ if (ms <= 0) {
2311
+ return;
2312
+ }
2313
+ await new Promise((resolve) => setTimeout(resolve, ms));
2314
+ }
2315
+ };
2316
+
2317
+ // ../../src/services/registry-broker/client/chat.ts
2318
+ function createChatApi(client, encryptedManager) {
2319
+ return {
2320
+ start: (options) => client.startChat(options),
2321
+ createSession: (payload) => client.createSession(payload),
2322
+ sendMessage: (payload) => client.sendMessage(payload),
2323
+ endSession: (sessionId) => client.endSession(sessionId),
2324
+ getHistory: (sessionId, options) => client.fetchHistorySnapshot(sessionId, options),
2325
+ compactHistory: (payload) => client.compactHistory(payload),
2326
+ getEncryptionStatus: (sessionId) => client.fetchEncryptionStatus(sessionId),
2327
+ submitEncryptionHandshake: (sessionId, payload) => client.postEncryptionHandshake(sessionId, payload),
2328
+ startConversation: (options) => client.startConversation(options),
2329
+ acceptConversation: (options) => client.acceptConversation(options),
2330
+ createEncryptedSession: (options) => encryptedManager.startSession(options),
2331
+ acceptEncryptedSession: (options) => encryptedManager.acceptSession(options)
2332
+ };
2283
2333
  }
2284
- async function vectorSearch(client, request) {
2334
+ async function createSession(client, payload, allowHistoryAutoTopUp = true) {
2335
+ const body = {};
2336
+ if ("uaid" in payload && payload.uaid) {
2337
+ body.uaid = payload.uaid;
2338
+ }
2339
+ if ("agentUrl" in payload && payload.agentUrl) {
2340
+ body.agentUrl = payload.agentUrl;
2341
+ }
2342
+ if (payload.auth) {
2343
+ body.auth = serialiseAuthConfig(payload.auth);
2344
+ }
2345
+ if (payload.historyTtlSeconds !== void 0) {
2346
+ body.historyTtlSeconds = payload.historyTtlSeconds;
2347
+ }
2348
+ if (payload.encryptionRequested !== void 0) {
2349
+ body.encryptionRequested = payload.encryptionRequested;
2350
+ }
2351
+ if (payload.senderUaid) {
2352
+ body.senderUaid = payload.senderUaid;
2353
+ }
2285
2354
  try {
2286
- const raw = await client.requestJson("/search", {
2355
+ const raw = await client.requestJson("/chat/session", {
2287
2356
  method: "POST",
2288
- body: request,
2357
+ body,
2289
2358
  headers: { "content-type": "application/json" }
2290
2359
  });
2291
2360
  return client.parseWithSchema(
2292
2361
  raw,
2293
- vectorSearchResponseSchema,
2294
- "vector search response"
2362
+ createSessionResponseSchema,
2363
+ "chat session response"
2364
+ );
2365
+ } catch (error) {
2366
+ const maybeError = error instanceof Error ? error : null;
2367
+ if (allowHistoryAutoTopUp && client.shouldAutoTopUpHistory(payload, maybeError)) {
2368
+ await client.executeHistoryAutoTopUp("chat.session");
2369
+ return createSession(client, payload, false);
2370
+ }
2371
+ throw error;
2372
+ }
2373
+ }
2374
+ async function startChat(client, encryptedManager, options) {
2375
+ if ("uaid" in options && options.uaid) {
2376
+ return startConversation(client, encryptedManager, {
2377
+ uaid: options.uaid,
2378
+ senderUaid: options.senderUaid,
2379
+ historyTtlSeconds: options.historyTtlSeconds,
2380
+ auth: options.auth,
2381
+ encryption: options.encryption,
2382
+ onSessionCreated: options.onSessionCreated
2383
+ });
2384
+ }
2385
+ if ("agentUrl" in options && options.agentUrl) {
2386
+ const session = await createSession(client, {
2387
+ agentUrl: options.agentUrl,
2388
+ auth: options.auth,
2389
+ historyTtlSeconds: options.historyTtlSeconds,
2390
+ senderUaid: options.senderUaid
2391
+ });
2392
+ options.onSessionCreated?.(session.sessionId);
2393
+ return createPlaintextConversationHandle(
2394
+ client,
2395
+ session.sessionId,
2396
+ session.encryption ?? null,
2397
+ options.auth,
2398
+ { agentUrl: options.agentUrl, uaid: options.uaid }
2399
+ );
2400
+ }
2401
+ throw new Error("startChat requires either uaid or agentUrl");
2402
+ }
2403
+ async function startConversation(client, encryptedManager, options) {
2404
+ const preference = options.encryption?.preference ?? "preferred";
2405
+ const requestEncryption = preference !== "disabled";
2406
+ if (!requestEncryption) {
2407
+ const session = await createSession(client, {
2408
+ uaid: options.uaid,
2409
+ auth: options.auth,
2410
+ historyTtlSeconds: options.historyTtlSeconds,
2411
+ senderUaid: options.senderUaid,
2412
+ encryptionRequested: false
2413
+ });
2414
+ options.onSessionCreated?.(session.sessionId);
2415
+ return createPlaintextConversationHandle(
2416
+ client,
2417
+ session.sessionId,
2418
+ session.encryption ?? null,
2419
+ options.auth,
2420
+ { uaid: options.uaid }
2295
2421
  );
2422
+ }
2423
+ try {
2424
+ const handle = await encryptedManager.startSession({
2425
+ uaid: options.uaid,
2426
+ senderUaid: options.senderUaid,
2427
+ historyTtlSeconds: options.historyTtlSeconds,
2428
+ handshakeTimeoutMs: options.encryption?.handshakeTimeoutMs,
2429
+ pollIntervalMs: options.encryption?.pollIntervalMs,
2430
+ onSessionCreated: (sessionId) => {
2431
+ options.onSessionCreated?.(sessionId);
2432
+ },
2433
+ auth: options.auth
2434
+ });
2435
+ return handle;
2436
+ } catch (error) {
2437
+ if (error instanceof EncryptionUnavailableError) {
2438
+ if (preference === "required") {
2439
+ throw error;
2440
+ }
2441
+ return createPlaintextConversationHandle(
2442
+ client,
2443
+ error.sessionId,
2444
+ error.summary ?? null,
2445
+ options.auth,
2446
+ { uaid: options.uaid }
2447
+ );
2448
+ }
2449
+ throw error;
2450
+ }
2451
+ }
2452
+ async function acceptConversation(client, encryptedManager, options) {
2453
+ const preference = options.encryption?.preference ?? "preferred";
2454
+ if (preference === "disabled") {
2455
+ return createPlaintextConversationHandle(client, options.sessionId, null);
2456
+ }
2457
+ try {
2458
+ const handle = await encryptedManager.acceptSession({
2459
+ sessionId: options.sessionId,
2460
+ responderUaid: options.responderUaid,
2461
+ handshakeTimeoutMs: options.encryption?.handshakeTimeoutMs,
2462
+ pollIntervalMs: options.encryption?.pollIntervalMs
2463
+ });
2464
+ return handle;
2296
2465
  } catch (error) {
2297
- if (error instanceof RegistryBrokerError && error.status === 501) {
2298
- const fallback = await search(
2466
+ if (error instanceof EncryptionUnavailableError && preference !== "required") {
2467
+ return createPlaintextConversationHandle(
2299
2468
  client,
2300
- buildVectorFallbackSearchParams(request)
2469
+ options.sessionId,
2470
+ null,
2471
+ void 0,
2472
+ { uaid: options.responderUaid }
2301
2473
  );
2302
- return convertSearchResultToVectorResponse(fallback);
2303
2474
  }
2304
2475
  throw error;
2305
2476
  }
2306
2477
  }
2307
- async function searchStatus(client) {
2308
- const raw = await client.requestJson("/search/status", {
2309
- method: "GET"
2310
- });
2311
- return client.parseWithSchema(
2312
- raw,
2313
- searchStatusResponseSchema,
2314
- "search status response"
2315
- );
2478
+ function createPlaintextConversationHandle(client, sessionId, summary, defaultAuth, context) {
2479
+ const uaid = context?.uaid?.trim();
2480
+ const agentUrl = context?.agentUrl?.trim();
2481
+ const fetchHistory = async (options) => {
2482
+ const snapshot = await client.fetchHistorySnapshot(sessionId, options);
2483
+ if (snapshot.decryptedHistory) {
2484
+ return snapshot.decryptedHistory;
2485
+ }
2486
+ return snapshot.history.map((entry) => ({
2487
+ entry,
2488
+ plaintext: entry.content
2489
+ }));
2490
+ };
2491
+ return {
2492
+ sessionId,
2493
+ mode: "plaintext",
2494
+ summary: summary ?? null,
2495
+ send: async (options) => {
2496
+ const plaintext = options.plaintext;
2497
+ if (!plaintext || plaintext.trim().length === 0) {
2498
+ throw new Error("plaintext is required for chat messages");
2499
+ }
2500
+ const message = options.message ?? plaintext;
2501
+ return sendMessage(client, {
2502
+ sessionId,
2503
+ message,
2504
+ streaming: options.streaming,
2505
+ auth: options.auth ?? defaultAuth,
2506
+ uaid,
2507
+ agentUrl
2508
+ });
2509
+ },
2510
+ decryptHistoryEntry: (entry) => entry.content,
2511
+ fetchHistory
2512
+ };
2316
2513
  }
2317
- async function websocketStats(client) {
2318
- const raw = await client.requestJson("/websocket/stats", {
2319
- method: "GET"
2320
- });
2321
- return client.parseWithSchema(
2322
- raw,
2323
- websocketStatsResponseSchema,
2324
- "websocket stats response"
2514
+ async function compactHistory(client, payload) {
2515
+ if (!payload.sessionId || payload.sessionId.trim().length === 0) {
2516
+ throw new Error("sessionId is required to compact chat history");
2517
+ }
2518
+ const body = {};
2519
+ if (typeof payload.preserveEntries === "number" && Number.isFinite(payload.preserveEntries) && payload.preserveEntries >= 0) {
2520
+ body.preserveEntries = Math.floor(payload.preserveEntries);
2521
+ }
2522
+ const raw = await client.requestJson(
2523
+ `/chat/session/${encodeURIComponent(payload.sessionId)}/compact`,
2524
+ {
2525
+ method: "POST",
2526
+ headers: { "content-type": "application/json" },
2527
+ body
2528
+ }
2325
2529
  );
2326
- }
2327
- async function metricsSummary(client) {
2328
- const raw = await client.requestJson("/metrics", {
2329
- method: "GET"
2330
- });
2331
2530
  return client.parseWithSchema(
2332
2531
  raw,
2333
- metricsSummaryResponseSchema,
2334
- "metrics summary response"
2532
+ chatHistoryCompactionResponseSchema,
2533
+ "chat history compaction response"
2335
2534
  );
2336
2535
  }
2337
- async function facets(client, adapter) {
2338
- const params = new URLSearchParams();
2339
- if (adapter) {
2340
- params.set("adapter", adapter);
2536
+ async function fetchEncryptionStatus(client, sessionId) {
2537
+ if (!sessionId || sessionId.trim().length === 0) {
2538
+ throw new Error("sessionId is required for encryption status");
2341
2539
  }
2342
- const suffix = params.size > 0 ? `?${params.toString()}` : "";
2343
- const raw = await client.requestJson(`/search/facets${suffix}`, {
2344
- method: "GET"
2345
- });
2346
- return client.parseWithSchema(
2347
- raw,
2348
- searchFacetsResponseSchema,
2349
- "search facets response"
2350
- );
2351
- }
2352
-
2353
- // ../../src/services/registry-broker/client/adapters.ts
2354
- async function adapters(client) {
2355
- const raw = await client.requestJson("/adapters", {
2356
- method: "GET"
2357
- });
2358
- return client.parseWithSchema(
2359
- raw,
2360
- adaptersResponseSchema,
2361
- "adapters response"
2540
+ const raw = await client.requestJson(
2541
+ `/chat/session/${encodeURIComponent(sessionId)}/encryption`,
2542
+ {
2543
+ method: "GET"
2544
+ }
2362
2545
  );
2363
- }
2364
- async function adaptersDetailed(client) {
2365
- const raw = await client.requestJson("/adapters/details", {
2366
- method: "GET"
2367
- });
2368
2546
  return client.parseWithSchema(
2369
2547
  raw,
2370
- adapterDetailsResponseSchema,
2371
- "adapter details response"
2548
+ sessionEncryptionStatusResponseSchema,
2549
+ "session encryption status response"
2372
2550
  );
2373
2551
  }
2374
- async function adapterRegistryCategories(client) {
2552
+ async function postEncryptionHandshake(client, sessionId, payload) {
2553
+ if (!sessionId || sessionId.trim().length === 0) {
2554
+ throw new Error("sessionId is required for encryption handshake");
2555
+ }
2375
2556
  const raw = await client.requestJson(
2376
- "/adapters/registry/categories",
2557
+ `/chat/session/${encodeURIComponent(sessionId)}/encryption-handshake`,
2377
2558
  {
2378
- method: "GET"
2559
+ method: "POST",
2560
+ headers: { "content-type": "application/json" },
2561
+ body: {
2562
+ role: payload.role,
2563
+ keyType: payload.keyType,
2564
+ ephemeralPublicKey: payload.ephemeralPublicKey,
2565
+ longTermPublicKey: payload.longTermPublicKey,
2566
+ signature: payload.signature,
2567
+ uaid: payload.uaid,
2568
+ userId: payload.userId,
2569
+ ledgerAccountId: payload.ledgerAccountId,
2570
+ metadata: payload.metadata
2571
+ }
2379
2572
  }
2380
2573
  );
2381
- return client.parseWithSchema(
2574
+ const response = client.parseWithSchema(
2382
2575
  raw,
2383
- adapterRegistryCategoriesResponseSchema,
2384
- "adapter registry categories response"
2576
+ encryptionHandshakeResponseSchema,
2577
+ "encryption handshake response"
2385
2578
  );
2579
+ return response.handshake;
2386
2580
  }
2387
- async function adapterRegistryAdapters(client, filters = {}) {
2388
- const params = new URLSearchParams();
2389
- if (filters.category) {
2390
- params.set("category", filters.category);
2391
- }
2392
- if (filters.entity) {
2393
- params.set("entity", filters.entity);
2581
+ async function sendMessage(client, payload) {
2582
+ const body = {
2583
+ message: payload.message
2584
+ };
2585
+ if (payload.streaming !== void 0) {
2586
+ body.streaming = payload.streaming;
2394
2587
  }
2395
- if (filters.keywords?.length) {
2396
- params.set("keywords", filters.keywords.join(","));
2588
+ if (payload.auth) {
2589
+ body.auth = serialiseAuthConfig(payload.auth);
2397
2590
  }
2398
- if (filters.query) {
2399
- params.set("query", filters.query);
2591
+ if ("uaid" in payload) {
2592
+ body.uaid = payload.uaid;
2400
2593
  }
2401
- if (typeof filters.limit === "number") {
2402
- params.set("limit", String(filters.limit));
2594
+ if ("sessionId" in payload && payload.sessionId) {
2595
+ body.sessionId = payload.sessionId;
2403
2596
  }
2404
- if (typeof filters.offset === "number") {
2405
- params.set("offset", String(filters.offset));
2597
+ if ("agentUrl" in payload && payload.agentUrl) {
2598
+ body.agentUrl = payload.agentUrl;
2406
2599
  }
2407
- const suffix = params.size > 0 ? `?${params.toString()}` : "";
2408
- const raw = await client.requestJson(
2409
- `/adapters/registry/adapters${suffix}`,
2410
- {
2411
- method: "GET"
2600
+ let cipherEnvelope = payload.cipherEnvelope ?? null;
2601
+ if (payload.encryption) {
2602
+ const sessionIdForEncryption = payload.encryption.sessionId ?? (typeof body.sessionId === "string" ? body.sessionId : void 0);
2603
+ if (!sessionIdForEncryption) {
2604
+ throw new Error(
2605
+ "sessionId is required when using encrypted chat payloads"
2606
+ );
2412
2607
  }
2413
- );
2608
+ if (!payload.encryption.recipients?.length) {
2609
+ throw new Error("recipients are required for encrypted chat payloads");
2610
+ }
2611
+ cipherEnvelope = client.encryption.encryptCipherEnvelope({
2612
+ ...payload.encryption,
2613
+ sessionId: sessionIdForEncryption
2614
+ });
2615
+ }
2616
+ if (cipherEnvelope) {
2617
+ body.cipherEnvelope = toJsonObject(cipherEnvelope);
2618
+ }
2619
+ const raw = await client.requestJson("/chat/message", {
2620
+ method: "POST",
2621
+ body,
2622
+ headers: { "content-type": "application/json" }
2623
+ });
2414
2624
  return client.parseWithSchema(
2415
2625
  raw,
2416
- adapterRegistryAdaptersResponseSchema,
2417
- "adapter registry adapters response"
2626
+ sendMessageResponseSchema,
2627
+ "chat message response"
2418
2628
  );
2419
2629
  }
2420
- async function createAdapterRegistryCategory(client, payload) {
2421
- const raw = await client.requestJson(
2422
- "/adapters/registry/categories",
2423
- {
2424
- method: "POST",
2425
- headers: { "content-type": "application/json" },
2426
- body: toJsonObject(payload)
2427
- }
2428
- );
2429
- const parsed = client.parseWithSchema(
2430
- raw,
2431
- adapterRegistryCreateCategoryResponseSchema,
2432
- "adapter registry create category response"
2433
- );
2434
- return parsed.category;
2630
+ async function endSession(client, sessionId) {
2631
+ await client.request(`/chat/session/${encodeURIComponent(sessionId)}`, {
2632
+ method: "DELETE"
2633
+ });
2435
2634
  }
2436
- async function submitAdapterRegistryAdapter(client, payload) {
2437
- const raw = await client.requestJson(
2438
- "/adapters/registry/adapters",
2439
- {
2440
- method: "POST",
2441
- headers: { "content-type": "application/json" },
2442
- body: toJsonObject(payload)
2635
+
2636
+ // ../../src/services/registry-broker/client/encryption.ts
2637
+ var import_buffer2 = require("buffer");
2638
+ var import_secp256k1 = require("@noble/curves/secp256k1.js");
2639
+
2640
+ // ../../src/utils/is-browser.ts
2641
+ var isBrowser = typeof window !== "undefined" && typeof window.document !== "undefined";
2642
+
2643
+ // ../../src/utils/dynamic-import.ts
2644
+ var import_meta = {};
2645
+ var nodeRequire;
2646
+ var isNodeRuntime = () => typeof process !== "undefined" && Boolean(process.versions?.node);
2647
+ function getNodeRequireSync() {
2648
+ try {
2649
+ const moduleNamespace = process.getBuiltinModule?.("module");
2650
+ if (typeof moduleNamespace?.createRequire === "function") {
2651
+ const requireFromModule = moduleNamespace.createRequire(import_meta.url);
2652
+ if (typeof requireFromModule.resolve === "function") {
2653
+ return requireFromModule;
2654
+ }
2443
2655
  }
2444
- );
2445
- return client.parseWithSchema(
2446
- raw,
2447
- adapterRegistrySubmitAdapterAcceptedResponseSchema,
2448
- "adapter registry submit adapter response"
2449
- );
2656
+ const globalObject = typeof global !== "undefined" ? global : globalThis;
2657
+ const runtimeRequire = globalObject.process?.mainModule?.require ?? globalObject.require ?? Function('return typeof require === "function" ? require : undefined;')();
2658
+ if (typeof runtimeRequire === "function" && typeof runtimeRequire.resolve === "function") {
2659
+ return runtimeRequire;
2660
+ }
2661
+ } catch {
2662
+ return null;
2663
+ }
2664
+ return null;
2450
2665
  }
2451
- async function adapterRegistrySubmissionStatus(client, submissionId) {
2452
- const raw = await client.requestJson(
2453
- `/adapters/registry/submissions/${encodeURIComponent(submissionId)}`,
2454
- {
2455
- method: "GET"
2666
+ function isModuleNotFound(specifier, error) {
2667
+ if (!error || typeof error !== "object") {
2668
+ return false;
2669
+ }
2670
+ const code = Reflect.get(error, "code");
2671
+ const message = Reflect.get(error, "message");
2672
+ const messageText = typeof message === "string" ? message : "";
2673
+ if (typeof code === "string" && code.includes("MODULE_NOT_FOUND")) {
2674
+ return messageText.includes(specifier);
2675
+ }
2676
+ if (messageText) {
2677
+ const lowered = messageText.toLowerCase();
2678
+ if (lowered.includes("cannot find module") || lowered.includes("module not found") || lowered.includes("cannot find package")) {
2679
+ return lowered.includes(specifier.toLowerCase());
2456
2680
  }
2457
- );
2458
- return client.parseWithSchema(
2459
- raw,
2460
- adapterRegistrySubmissionStatusResponseSchema,
2461
- "adapter registry submission status response"
2462
- );
2681
+ }
2682
+ return false;
2463
2683
  }
2464
-
2465
- // ../../src/services/registry-broker/client/credits.ts
2466
- async function loadX402Dependencies(client) {
2467
- const [{ default: axios }, x402Axios, x402Types] = await Promise.all([
2468
- import("axios"),
2469
- optionalImport("x402-axios"),
2470
- optionalImport("x402/types")
2471
- ]);
2472
- if (!x402Axios || !x402Types) {
2473
- throw new Error(
2474
- "x402-axios and x402/types are required for X402 flows. Install them to enable ledger payments."
2684
+ async function resolveNodeRequire() {
2685
+ if (nodeRequire !== void 0) {
2686
+ return nodeRequire;
2687
+ }
2688
+ if (isBrowser && !isNodeRuntime()) {
2689
+ nodeRequire = null;
2690
+ return nodeRequire;
2691
+ }
2692
+ try {
2693
+ nodeRequire = getNodeRequireSync();
2694
+ } catch {
2695
+ nodeRequire = null;
2696
+ }
2697
+ return nodeRequire;
2698
+ }
2699
+ async function dynamicImport(specifier) {
2700
+ try {
2701
+ return await import(
2702
+ /* webpackIgnore: true */
2703
+ specifier
2475
2704
  );
2705
+ } catch (error) {
2706
+ if (isModuleNotFound(specifier, error)) {
2707
+ return null;
2708
+ }
2709
+ throw error;
2476
2710
  }
2477
- const withPaymentInterceptor = x402Axios.withPaymentInterceptor;
2478
- const decodePaymentResponse = x402Axios.decodeXPaymentResponse;
2479
- const createX402Signer = x402Types.createSigner;
2480
- const createPaymentClient = (walletClient) => {
2481
- const axiosClient = axios.create({
2482
- baseURL: client.baseUrl,
2483
- headers: {
2484
- ...client.getDefaultHeaders(),
2485
- "content-type": "application/json"
2711
+ }
2712
+ async function optionalImport(specifier, options = {}) {
2713
+ if (isBrowser && !isNodeRuntime()) {
2714
+ return dynamicImport(specifier);
2715
+ }
2716
+ if (!options.preferImport) {
2717
+ const requireFn = await resolveNodeRequire();
2718
+ if (requireFn) {
2719
+ try {
2720
+ return requireFn(specifier);
2721
+ } catch (error) {
2722
+ if (!isModuleNotFound(specifier, error)) {
2723
+ throw error;
2724
+ }
2486
2725
  }
2487
- });
2488
- const paymentClient = withPaymentInterceptor(axiosClient, walletClient);
2489
- return paymentClient;
2490
- };
2491
- return { createPaymentClient, decodePaymentResponse, createX402Signer };
2726
+ }
2727
+ }
2728
+ return dynamicImport(specifier);
2492
2729
  }
2493
- function calculateHbarAmountParam(hbarAmount) {
2494
- const tinybars = Math.ceil(hbarAmount * 1e8);
2495
- if (tinybars <= 0) {
2496
- throw new Error("Calculated purchase amount must be positive");
2730
+ function optionalImportSync(specifier) {
2731
+ if (isBrowser && !isNodeRuntime()) {
2732
+ return null;
2497
2733
  }
2498
- return tinybars / 1e8;
2734
+ try {
2735
+ const requireFn = getNodeRequireSync();
2736
+ if (requireFn) {
2737
+ return requireFn(specifier);
2738
+ }
2739
+ } catch (error) {
2740
+ if (!isModuleNotFound(specifier, error)) {
2741
+ throw error;
2742
+ }
2743
+ }
2744
+ return null;
2499
2745
  }
2500
- async function purchaseCreditsWithHbar(client, params) {
2501
- const body = {
2502
- accountId: params.accountId,
2503
- payerKey: params.privateKey,
2504
- hbarAmount: calculateHbarAmountParam(params.hbarAmount)
2505
- };
2506
- if (params.memo) {
2507
- body.memo = params.memo;
2746
+
2747
+ // ../../src/services/registry-broker/client/encryption.ts
2748
+ var getFs = async () => {
2749
+ const fsModule = await optionalImport("node:fs") ?? await optionalImport("fs");
2750
+ if (fsModule && typeof fsModule.existsSync === "function" && typeof fsModule.readFileSync === "function" && typeof fsModule.writeFileSync === "function" && typeof fsModule.appendFileSync === "function") {
2751
+ return fsModule;
2508
2752
  }
2509
- if (params.metadata) {
2510
- body.metadata = params.metadata;
2753
+ return null;
2754
+ };
2755
+ var getNodePath = async () => {
2756
+ const pathModule = await optionalImport("node:path") ?? await optionalImport("path");
2757
+ if (pathModule && typeof pathModule.resolve === "function") {
2758
+ return pathModule;
2511
2759
  }
2512
- const raw = await client.requestJson("/credits/purchase", {
2760
+ return null;
2761
+ };
2762
+ var getNodeCrypto = async () => {
2763
+ const cryptoModule = await optionalImport("node:crypto") ?? await optionalImport("crypto");
2764
+ if (cryptoModule && typeof cryptoModule.randomBytes === "function") {
2765
+ return cryptoModule;
2766
+ }
2767
+ return null;
2768
+ };
2769
+ async function registerEncryptionKey(client, payload) {
2770
+ const raw = await client.requestJson("/encryption/keys", {
2513
2771
  method: "POST",
2514
2772
  headers: { "content-type": "application/json" },
2515
- body
2773
+ body: payload
2516
2774
  });
2517
2775
  return client.parseWithSchema(
2518
2776
  raw,
2519
- creditPurchaseResponseSchema,
2520
- "credit purchase response"
2521
- );
2522
- }
2523
- async function getX402Minimums(client) {
2524
- const raw = await client.requestJson(
2525
- "/credits/purchase/x402/minimums",
2526
- { method: "GET" }
2527
- );
2528
- return client.parseWithSchema(
2529
- raw,
2530
- x402MinimumsResponseSchema,
2531
- "x402 minimums response"
2777
+ registerEncryptionKeyResponseSchema,
2778
+ "register encryption key response"
2532
2779
  );
2533
2780
  }
2534
- async function purchaseCreditsWithX402(client, params) {
2535
- const { createPaymentClient, decodePaymentResponse } = await loadX402Dependencies(client);
2536
- if (!Number.isFinite(params.credits) || params.credits <= 0) {
2537
- throw new Error("credits must be a positive number");
2781
+ function normalizeAutoRegisterIdentity(config) {
2782
+ const identity = {};
2783
+ if (config.uaid) {
2784
+ identity.uaid = config.uaid;
2538
2785
  }
2539
- if (params.usdAmount !== void 0 && (!Number.isFinite(params.usdAmount) || params.usdAmount <= 0)) {
2540
- throw new Error("usdAmount must be a positive number when provided");
2786
+ if (config.ledgerAccountId) {
2787
+ identity.ledgerAccountId = config.ledgerAccountId;
2788
+ if (config.ledgerNetwork) {
2789
+ identity.ledgerNetwork = config.ledgerNetwork;
2790
+ }
2541
2791
  }
2542
- const body = {
2543
- accountId: params.accountId,
2544
- credits: params.credits
2545
- };
2546
- if (params.usdAmount !== void 0) {
2547
- body.usdAmount = params.usdAmount;
2792
+ if (config.email) {
2793
+ identity.email = config.email;
2548
2794
  }
2549
- if (params.description) {
2550
- body.description = params.description;
2795
+ if (identity.uaid || identity.ledgerAccountId || identity.email) {
2796
+ return identity;
2551
2797
  }
2552
- if (params.metadata) {
2553
- body.metadata = params.metadata;
2798
+ return null;
2799
+ }
2800
+ function derivePublicKeyFromPrivateKey(client, privateKey) {
2801
+ const normalized = client.hexToBuffer(privateKey);
2802
+ const publicKey = import_secp256k1.secp256k1.getPublicKey(normalized, true);
2803
+ return import_buffer2.Buffer.from(publicKey).toString("hex");
2804
+ }
2805
+ async function resolveAutoRegisterKeyMaterial(client, config) {
2806
+ if (config.publicKey?.trim()) {
2807
+ return { publicKey: config.publicKey.trim() };
2554
2808
  }
2555
- const paymentClient = createPaymentClient(params.walletClient);
2556
- const response = await paymentClient.post("/credits/purchase/x402", body);
2557
- const parsed = client.parseWithSchema(
2558
- response.data,
2559
- x402CreditPurchaseResponseSchema,
2560
- "x402 credit purchase response"
2561
- );
2562
- const responseHeaders = response.headers ?? {};
2563
- const paymentHeader = typeof responseHeaders["x-payment-response"] === "string" ? responseHeaders["x-payment-response"] : void 0;
2564
- const decodedPayment = paymentHeader !== void 0 ? decodePaymentResponse(paymentHeader) : void 0;
2565
- return {
2566
- ...parsed,
2567
- paymentResponseHeader: paymentHeader,
2568
- paymentResponse: decodedPayment
2569
- };
2809
+ let privateKey = config.privateKey?.trim();
2810
+ const envVar = config.envVar ?? "RB_ENCRYPTION_PRIVATE_KEY";
2811
+ if (!privateKey && envVar && process?.env?.[envVar]?.trim()) {
2812
+ privateKey = process.env[envVar]?.trim();
2813
+ }
2814
+ if (!privateKey && config.generateIfMissing) {
2815
+ const pair = await client.generateEncryptionKeyPair({
2816
+ keyType: config.keyType ?? "secp256k1",
2817
+ envVar,
2818
+ envPath: config.envPath,
2819
+ overwrite: config.overwriteEnv
2820
+ });
2821
+ return { publicKey: pair.publicKey, privateKey: pair.privateKey };
2822
+ }
2823
+ if (privateKey) {
2824
+ const publicKey = derivePublicKeyFromPrivateKey(client, privateKey);
2825
+ return { publicKey, privateKey };
2826
+ }
2827
+ return null;
2570
2828
  }
2571
- async function buyCreditsWithX402(client, params) {
2572
- const network = params.network ?? "base";
2573
- const { createX402Signer } = await loadX402Dependencies(client);
2574
- const normalizedKey = normalizeHexPrivateKey(params.evmPrivateKey);
2575
- const walletClient = await createX402Signer(network, normalizedKey);
2576
- return purchaseCreditsWithX402(client, {
2577
- accountId: params.accountId,
2578
- credits: params.credits,
2579
- usdAmount: params.usdAmount,
2580
- description: params.description,
2581
- metadata: params.metadata,
2582
- walletClient
2829
+ async function autoRegisterEncryptionKey(client, config) {
2830
+ const identity = normalizeAutoRegisterIdentity(config);
2831
+ if (!identity) {
2832
+ throw new Error(
2833
+ "Auto-registration requires uaid, ledgerAccountId, or email"
2834
+ );
2835
+ }
2836
+ const material = await resolveAutoRegisterKeyMaterial(client, config);
2837
+ if (!material) {
2838
+ throw new Error(
2839
+ "Unable to resolve encryption public key for auto-registration"
2840
+ );
2841
+ }
2842
+ await registerEncryptionKey(client, {
2843
+ keyType: config.keyType ?? "secp256k1",
2844
+ publicKey: material.publicKey,
2845
+ ...identity
2583
2846
  });
2847
+ return material;
2584
2848
  }
2585
-
2586
- // ../../src/services/registry-broker/client/agents.ts
2587
- async function performRegisterAgent(client, payload) {
2588
- const raw = await client.requestJson("/register", {
2589
- method: "POST",
2590
- body: serialiseAgentRegistrationRequest(payload),
2591
- headers: { "content-type": "application/json" }
2849
+ async function ensureAgentEncryptionKey(client, options) {
2850
+ return autoRegisterEncryptionKey(client, {
2851
+ ...options,
2852
+ uaid: options.uaid,
2853
+ enabled: true
2592
2854
  });
2593
- return client.parseWithSchema(
2594
- raw,
2595
- registerAgentResponseSchema,
2596
- "register agent response"
2597
- );
2598
2855
  }
2599
- function calculateHbarAmount(creditsToPurchase, creditsPerHbar) {
2600
- if (creditsPerHbar <= 0) {
2601
- throw new Error("creditsPerHbar must be positive");
2602
- }
2603
- if (creditsToPurchase <= 0) {
2604
- throw new Error("creditsToPurchase must be positive");
2605
- }
2606
- const rawHbar = creditsToPurchase / creditsPerHbar;
2607
- const tinybars = Math.ceil(rawHbar * 1e8);
2608
- return tinybars / 1e8;
2856
+ function createEncryptionApi(client) {
2857
+ return {
2858
+ registerKey: (payload) => registerEncryptionKey(client, payload),
2859
+ generateEphemeralKeyPair: () => client.createEphemeralKeyPair(),
2860
+ deriveSharedSecret: (options) => client.deriveSharedSecret(options),
2861
+ encryptCipherEnvelope: (options) => client.buildCipherEnvelope(options),
2862
+ decryptCipherEnvelope: (options) => client.openCipherEnvelope(options),
2863
+ ensureAgentKey: (options) => ensureAgentEncryptionKey(client, options)
2864
+ };
2609
2865
  }
2610
- function resolveCreditsToPurchase(shortfallCredits) {
2611
- if (!Number.isFinite(shortfallCredits) || shortfallCredits <= 0) {
2612
- return 0;
2866
+ async function bootstrapEncryptionOptions(client, options) {
2867
+ if (!options?.autoRegister || options.autoRegister.enabled === false) {
2868
+ return null;
2613
2869
  }
2614
- return Math.max(
2615
- Math.ceil(shortfallCredits),
2616
- MINIMUM_REGISTRATION_AUTO_TOP_UP_CREDITS
2617
- );
2870
+ return autoRegisterEncryptionKey(client, options.autoRegister);
2618
2871
  }
2619
- async function ensureCreditsForRegistration(client, payload, autoTopUp) {
2620
- const details = autoTopUp ?? null;
2621
- if (!details) {
2622
- return;
2872
+ async function generateEncryptionKeyPair(client, options = {}) {
2873
+ client.assertNodeRuntime("generateEncryptionKeyPair");
2874
+ const keyType = options.keyType ?? "secp256k1";
2875
+ if (keyType !== "secp256k1") {
2876
+ throw new Error("Only secp256k1 key generation is supported currently");
2623
2877
  }
2624
- if (!details.accountId || !details.accountId.trim()) {
2625
- throw new Error("autoTopUp.accountId is required");
2878
+ const cryptoModule = await getNodeCrypto();
2879
+ if (!cryptoModule) {
2880
+ throw new Error(
2881
+ "Node.js crypto module is not available; cannot generate encryption key pair"
2882
+ );
2626
2883
  }
2627
- if (!details.privateKey || !details.privateKey.trim()) {
2628
- throw new Error("autoTopUp.privateKey is required");
2884
+ const privateKeyBytes = cryptoModule.randomBytes(32);
2885
+ const privateKey = import_buffer2.Buffer.from(privateKeyBytes).toString("hex");
2886
+ const publicKeyBytes = import_secp256k1.secp256k1.getPublicKey(privateKeyBytes, true);
2887
+ const publicKey = import_buffer2.Buffer.from(publicKeyBytes).toString("hex");
2888
+ const envVar = options.envVar ?? "RB_ENCRYPTION_PRIVATE_KEY";
2889
+ const pathModule = options.envPath ? await getNodePath() : null;
2890
+ const resolvedPath = options.envPath && pathModule ? pathModule.resolve(options.envPath) : void 0;
2891
+ if (options.envPath && !resolvedPath) {
2892
+ throw new Error(
2893
+ "Node.js path module is not available; cannot resolve encryption key env path"
2894
+ );
2629
2895
  }
2630
- for (let attempt = 0; attempt < 3; attempt += 1) {
2631
- const quote = await getRegistrationQuote(client, payload);
2632
- const shortfall = quote.shortfallCredits ?? 0;
2633
- if (shortfall <= 0) {
2634
- return;
2635
- }
2636
- const creditsToPurchase = resolveCreditsToPurchase(shortfall);
2637
- if (creditsToPurchase <= 0) {
2638
- return;
2639
- }
2640
- const creditsPerHbar = quote.creditsPerHbar ?? null;
2641
- if (!creditsPerHbar || creditsPerHbar <= 0) {
2642
- throw new Error("Unable to determine credits per HBAR for auto top-up");
2896
+ if (resolvedPath) {
2897
+ const fsModule = await getFs();
2898
+ if (!fsModule) {
2899
+ throw new Error(
2900
+ "File system module is not available; cannot write encryption key env file"
2901
+ );
2643
2902
  }
2644
- const hbarAmount = calculateHbarAmount(creditsToPurchase, creditsPerHbar);
2645
- await purchaseCreditsWithHbar(client, {
2646
- accountId: details.accountId.trim(),
2647
- privateKey: details.privateKey.trim(),
2648
- hbarAmount,
2649
- memo: details.memo ?? "Registry Broker auto top-up",
2650
- metadata: {
2651
- shortfallCredits: shortfall,
2652
- requiredCredits: quote.requiredCredits,
2653
- purchasedCredits: creditsToPurchase
2903
+ const envLine = `${envVar}=${privateKey}`;
2904
+ if (fsModule.existsSync(resolvedPath)) {
2905
+ const content = fsModule.readFileSync(resolvedPath, "utf-8");
2906
+ const lineRegex = new RegExp(`^${envVar}=.*$`, "m");
2907
+ if (lineRegex.test(content)) {
2908
+ if (!options.overwrite) {
2909
+ throw new Error(
2910
+ `${envVar} already exists in ${resolvedPath}; set overwrite=true to replace it`
2911
+ );
2912
+ }
2913
+ const updated = content.replace(lineRegex, envLine);
2914
+ fsModule.writeFileSync(resolvedPath, updated);
2915
+ } else {
2916
+ const needsNewline = !content.endsWith("\n");
2917
+ fsModule.appendFileSync(
2918
+ resolvedPath,
2919
+ `${needsNewline ? "\n" : ""}${envLine}
2920
+ `
2921
+ );
2654
2922
  }
2655
- });
2656
- }
2657
- const finalQuote = await getRegistrationQuote(client, payload);
2658
- if ((finalQuote.shortfallCredits ?? 0) > 0) {
2659
- throw new Error("Unable to purchase sufficient credits for registration");
2923
+ } else {
2924
+ fsModule.writeFileSync(resolvedPath, `${envLine}
2925
+ `);
2926
+ }
2660
2927
  }
2928
+ return {
2929
+ privateKey,
2930
+ publicKey,
2931
+ envPath: resolvedPath,
2932
+ envVar
2933
+ };
2661
2934
  }
2662
- async function resolveUaid(client, uaid) {
2663
- const raw = await client.requestJson(
2664
- `/resolve/${encodeURIComponent(uaid)}`,
2665
- {
2666
- method: "GET"
2667
- }
2668
- );
2935
+
2936
+ // ../../src/services/registry-broker/client/adapters.ts
2937
+ async function adapters(client) {
2938
+ const raw = await client.requestJson("/adapters", {
2939
+ method: "GET"
2940
+ });
2669
2941
  return client.parseWithSchema(
2670
2942
  raw,
2671
- resolveResponseSchema,
2672
- "resolve UAID response"
2943
+ adaptersResponseSchema,
2944
+ "adapters response"
2673
2945
  );
2674
2946
  }
2675
- async function registerAgent(client, payload, options) {
2676
- const autoTopUp = options?.autoTopUp ?? client.registrationAutoTopUp;
2677
- if (!autoTopUp) {
2678
- return performRegisterAgent(client, payload);
2679
- }
2680
- await ensureCreditsForRegistration(client, payload, autoTopUp);
2681
- let retried = false;
2682
- while (true) {
2683
- try {
2684
- return await performRegisterAgent(client, payload);
2685
- } catch (error) {
2686
- const shortfall = client.extractInsufficientCreditsDetails(error);
2687
- if (shortfall && !retried) {
2688
- await ensureCreditsForRegistration(client, payload, autoTopUp);
2689
- retried = true;
2690
- continue;
2691
- }
2692
- throw error;
2693
- }
2694
- }
2695
- }
2696
- async function getRegistrationQuote(client, payload) {
2697
- const raw = await client.requestJson("/register/quote", {
2698
- method: "POST",
2699
- body: serialiseAgentRegistrationRequest(payload),
2700
- headers: { "content-type": "application/json" }
2947
+ async function adaptersDetailed(client) {
2948
+ const raw = await client.requestJson("/adapters/details", {
2949
+ method: "GET"
2701
2950
  });
2702
2951
  return client.parseWithSchema(
2703
2952
  raw,
2704
- registrationQuoteResponseSchema,
2705
- "registration quote response"
2953
+ adapterDetailsResponseSchema,
2954
+ "adapter details response"
2706
2955
  );
2707
2956
  }
2708
- async function updateAgent(client, uaid, payload) {
2957
+ async function adapterRegistryCategories(client) {
2709
2958
  const raw = await client.requestJson(
2710
- `/register/${encodeURIComponent(uaid)}`,
2959
+ "/adapters/registry/categories",
2711
2960
  {
2712
- method: "PUT",
2713
- body: serialiseAgentRegistrationRequest(payload),
2714
- headers: { "content-type": "application/json" }
2961
+ method: "GET"
2715
2962
  }
2716
2963
  );
2717
2964
  return client.parseWithSchema(
2718
2965
  raw,
2719
- registerAgentResponseSchema,
2720
- "update agent response"
2721
- );
2722
- }
2723
- async function getRegistrationProgress(client, attemptId) {
2724
- const normalisedAttemptId = attemptId.trim();
2725
- if (!normalisedAttemptId) {
2726
- throw new Error("attemptId is required");
2727
- }
2728
- try {
2729
- const raw = await client.requestJson(
2730
- `/register/progress/${encodeURIComponent(normalisedAttemptId)}`,
2731
- { method: "GET" }
2732
- );
2733
- const parsed = client.parseWithSchema(
2734
- raw,
2735
- registrationProgressResponseSchema,
2736
- "registration progress response"
2737
- );
2738
- return parsed.progress;
2739
- } catch (error) {
2740
- if (error instanceof RegistryBrokerError && error.status === 404) {
2741
- return null;
2742
- }
2743
- throw error;
2744
- }
2745
- }
2746
- async function waitForRegistrationCompletion(client, attemptId, options = {}) {
2747
- const normalisedAttemptId = attemptId.trim();
2748
- if (!normalisedAttemptId) {
2749
- throw new Error("attemptId is required");
2750
- }
2751
- const interval = Math.max(
2752
- 250,
2753
- options.intervalMs ?? DEFAULT_PROGRESS_INTERVAL_MS
2966
+ adapterRegistryCategoriesResponseSchema,
2967
+ "adapter registry categories response"
2754
2968
  );
2755
- const timeoutMs = options.timeoutMs ?? DEFAULT_PROGRESS_TIMEOUT_MS;
2756
- const throwOnFailure = options.throwOnFailure ?? true;
2757
- const signal = options.signal;
2758
- const startedAt = Date.now();
2759
- while (true) {
2760
- if (signal?.aborted) {
2761
- throw createAbortError();
2762
- }
2763
- const progress = await client.getRegistrationProgress(normalisedAttemptId);
2764
- if (progress) {
2765
- options.onProgress?.(progress);
2766
- if (progress.status === "completed") {
2767
- return progress;
2768
- }
2769
- if (progress.status === "partial" || progress.status === "failed") {
2770
- if (throwOnFailure) {
2771
- throw new RegistryBrokerError(
2772
- "Registration did not complete successfully",
2773
- {
2774
- status: 409,
2775
- statusText: progress.status,
2776
- body: progress
2777
- }
2778
- );
2779
- }
2780
- return progress;
2781
- }
2969
+ }
2970
+ async function adapterRegistryAdapters(client, filters = {}) {
2971
+ const params = new URLSearchParams();
2972
+ if (filters.category) {
2973
+ params.set("category", filters.category);
2974
+ }
2975
+ if (filters.entity) {
2976
+ params.set("entity", filters.entity);
2977
+ }
2978
+ if (filters.keywords?.length) {
2979
+ params.set("keywords", filters.keywords.join(","));
2980
+ }
2981
+ if (filters.query) {
2982
+ params.set("query", filters.query);
2983
+ }
2984
+ if (typeof filters.limit === "number") {
2985
+ params.set("limit", String(filters.limit));
2986
+ }
2987
+ if (typeof filters.offset === "number") {
2988
+ params.set("offset", String(filters.offset));
2989
+ }
2990
+ const suffix = params.size > 0 ? `?${params.toString()}` : "";
2991
+ const raw = await client.requestJson(
2992
+ `/adapters/registry/adapters${suffix}`,
2993
+ {
2994
+ method: "GET"
2782
2995
  }
2783
- if (Date.now() - startedAt >= timeoutMs) {
2784
- throw new Error(
2785
- `Registration progress polling timed out after ${timeoutMs}ms`
2786
- );
2996
+ );
2997
+ return client.parseWithSchema(
2998
+ raw,
2999
+ adapterRegistryAdaptersResponseSchema,
3000
+ "adapter registry adapters response"
3001
+ );
3002
+ }
3003
+ async function createAdapterRegistryCategory(client, payload) {
3004
+ const raw = await client.requestJson(
3005
+ "/adapters/registry/categories",
3006
+ {
3007
+ method: "POST",
3008
+ headers: { "content-type": "application/json" },
3009
+ body: toJsonObject(payload)
2787
3010
  }
2788
- await client.delay(interval, signal);
2789
- }
3011
+ );
3012
+ const parsed = client.parseWithSchema(
3013
+ raw,
3014
+ adapterRegistryCreateCategoryResponseSchema,
3015
+ "adapter registry create category response"
3016
+ );
3017
+ return parsed.category;
2790
3018
  }
2791
- async function validateUaid(client, uaid) {
3019
+ async function submitAdapterRegistryAdapter(client, payload) {
2792
3020
  const raw = await client.requestJson(
2793
- `/uaids/validate/${encodeURIComponent(uaid)}`,
3021
+ "/adapters/registry/adapters",
2794
3022
  {
2795
- method: "GET"
3023
+ method: "POST",
3024
+ headers: { "content-type": "application/json" },
3025
+ body: toJsonObject(payload)
2796
3026
  }
2797
3027
  );
2798
3028
  return client.parseWithSchema(
2799
3029
  raw,
2800
- uaidValidationResponseSchema,
2801
- "UAID validation response"
3030
+ adapterRegistrySubmitAdapterAcceptedResponseSchema,
3031
+ "adapter registry submit adapter response"
2802
3032
  );
2803
3033
  }
2804
- async function getUaidConnectionStatus(client, uaid) {
3034
+ async function adapterRegistrySubmissionStatus(client, submissionId) {
2805
3035
  const raw = await client.requestJson(
2806
- `/uaids/connections/${encodeURIComponent(uaid)}/status`,
3036
+ `/adapters/registry/submissions/${encodeURIComponent(submissionId)}`,
2807
3037
  {
2808
3038
  method: "GET"
2809
3039
  }
2810
3040
  );
2811
3041
  return client.parseWithSchema(
2812
3042
  raw,
2813
- uaidConnectionStatusSchema,
2814
- "UAID connection status"
3043
+ adapterRegistrySubmissionStatusResponseSchema,
3044
+ "adapter registry submission status response"
2815
3045
  );
2816
3046
  }
2817
- async function closeUaidConnection(client, uaid) {
2818
- await client.request(`/uaids/connections/${encodeURIComponent(uaid)}`, {
2819
- method: "DELETE"
2820
- });
3047
+
3048
+ // ../../src/services/registry-broker/client/credits.ts
3049
+ async function loadX402Dependencies(client) {
3050
+ const [{ default: axios }, x402Axios, x402Types] = await Promise.all([
3051
+ import("axios"),
3052
+ optionalImport("x402-axios"),
3053
+ optionalImport("x402/types")
3054
+ ]);
3055
+ if (!x402Axios || !x402Types) {
3056
+ throw new Error(
3057
+ "x402-axios and x402/types are required for X402 flows. Install them to enable ledger payments."
3058
+ );
3059
+ }
3060
+ const withPaymentInterceptor = x402Axios.withPaymentInterceptor;
3061
+ const decodePaymentResponse = x402Axios.decodeXPaymentResponse;
3062
+ const createX402Signer = x402Types.createSigner;
3063
+ const createPaymentClient = (walletClient) => {
3064
+ const axiosClient = axios.create({
3065
+ baseURL: client.baseUrl,
3066
+ headers: {
3067
+ ...client.getDefaultHeaders(),
3068
+ "content-type": "application/json"
3069
+ }
3070
+ });
3071
+ const paymentClient = withPaymentInterceptor(axiosClient, walletClient);
3072
+ return paymentClient;
3073
+ };
3074
+ return { createPaymentClient, decodePaymentResponse, createX402Signer };
2821
3075
  }
2822
- async function dashboardStats(client) {
2823
- const raw = await client.requestJson("/dashboard/stats", {
2824
- method: "GET"
3076
+ function calculateHbarAmountParam(hbarAmount) {
3077
+ const tinybars = Math.ceil(hbarAmount * 1e8);
3078
+ if (tinybars <= 0) {
3079
+ throw new Error("Calculated purchase amount must be positive");
3080
+ }
3081
+ return tinybars / 1e8;
3082
+ }
3083
+ async function purchaseCreditsWithHbar(client, params) {
3084
+ const body = {
3085
+ accountId: params.accountId,
3086
+ payerKey: params.privateKey,
3087
+ hbarAmount: calculateHbarAmountParam(params.hbarAmount)
3088
+ };
3089
+ if (params.memo) {
3090
+ body.memo = params.memo;
3091
+ }
3092
+ if (params.metadata) {
3093
+ body.metadata = params.metadata;
3094
+ }
3095
+ const raw = await client.requestJson("/credits/purchase", {
3096
+ method: "POST",
3097
+ headers: { "content-type": "application/json" },
3098
+ body
2825
3099
  });
2826
3100
  return client.parseWithSchema(
2827
3101
  raw,
2828
- dashboardStatsResponseSchema,
2829
- "dashboard stats response"
3102
+ creditPurchaseResponseSchema,
3103
+ "credit purchase response"
2830
3104
  );
2831
3105
  }
2832
-
2833
- // ../../src/services/registry-broker/client/ledger-auth.ts
2834
- var import_buffer2 = require("buffer");
2835
-
2836
- // ../../src/services/registry-broker/ledger-network.ts
2837
- var normalise = (value) => value.trim().toLowerCase();
2838
- var HEDERA_NETWORK_ALIASES = /* @__PURE__ */ new Map([
2839
- ["hedera:mainnet", { canonical: "hedera:mainnet", hederaNetwork: "mainnet" }],
2840
- ["mainnet", { canonical: "hedera:mainnet", hederaNetwork: "mainnet" }],
2841
- ["hedera-mainnet", { canonical: "hedera:mainnet", hederaNetwork: "mainnet" }],
2842
- ["hedera_mainnet", { canonical: "hedera:mainnet", hederaNetwork: "mainnet" }],
2843
- ["hedera:testnet", { canonical: "hedera:testnet", hederaNetwork: "testnet" }],
2844
- ["testnet", { canonical: "hedera:testnet", hederaNetwork: "testnet" }],
2845
- ["hedera-testnet", { canonical: "hedera:testnet", hederaNetwork: "testnet" }],
2846
- ["hedera_testnet", { canonical: "hedera:testnet", hederaNetwork: "testnet" }]
2847
- ]);
2848
- var EVM_NETWORK_CHAIN_IDS = {
2849
- abstract: 2741,
2850
- "abstract-testnet": 11124,
2851
- base: 8453,
2852
- "base-sepolia": 84532,
2853
- avalanche: 43114,
2854
- "avalanche-fuji": 43113,
2855
- iotex: 4689,
2856
- sei: 1329,
2857
- "sei-testnet": 1328,
2858
- polygon: 137,
2859
- "polygon-amoy": 80002,
2860
- peaq: 3338
2861
- };
2862
- var CHAIN_ID_TO_ALIAS = new Map(
2863
- Object.entries(EVM_NETWORK_CHAIN_IDS).map(([alias, id]) => [id, alias])
2864
- );
2865
- var parseChainId = (value) => {
2866
- if (/^eip155:\d+$/i.test(value)) {
2867
- return Number.parseInt(value.split(":")[1], 10);
3106
+ async function getX402Minimums(client) {
3107
+ const raw = await client.requestJson(
3108
+ "/credits/purchase/x402/minimums",
3109
+ { method: "GET" }
3110
+ );
3111
+ return client.parseWithSchema(
3112
+ raw,
3113
+ x402MinimumsResponseSchema,
3114
+ "x402 minimums response"
3115
+ );
3116
+ }
3117
+ async function purchaseCreditsWithX402(client, params) {
3118
+ const { createPaymentClient, decodePaymentResponse } = await loadX402Dependencies(client);
3119
+ if (!Number.isFinite(params.credits) || params.credits <= 0) {
3120
+ throw new Error("credits must be a positive number");
2868
3121
  }
2869
- if (/^\d+$/.test(value)) {
2870
- return Number.parseInt(value, 10);
3122
+ if (params.usdAmount !== void 0 && (!Number.isFinite(params.usdAmount) || params.usdAmount <= 0)) {
3123
+ throw new Error("usdAmount must be a positive number when provided");
2871
3124
  }
2872
- return void 0;
2873
- };
2874
- var normaliseEvmNetwork = (value) => {
2875
- const trimmed = normalise(value);
2876
- let chainId = parseChainId(trimmed);
2877
- let alias;
2878
- if (chainId === void 0) {
2879
- const mapped = EVM_NETWORK_CHAIN_IDS[trimmed];
2880
- if (mapped !== void 0) {
2881
- chainId = mapped;
2882
- alias = trimmed;
2883
- }
2884
- } else if (CHAIN_ID_TO_ALIAS.has(chainId)) {
2885
- alias = CHAIN_ID_TO_ALIAS.get(chainId);
3125
+ const body = {
3126
+ accountId: params.accountId,
3127
+ credits: params.credits
3128
+ };
3129
+ if (params.usdAmount !== void 0) {
3130
+ body.usdAmount = params.usdAmount;
2886
3131
  }
2887
- if (chainId === void 0) {
2888
- throw new Error(
2889
- 'Unsupported EVM ledger network. Provide an alias like "base-sepolia" or a canonical eip155:<chainId> string.'
2890
- );
3132
+ if (params.description) {
3133
+ body.description = params.description;
2891
3134
  }
3135
+ if (params.metadata) {
3136
+ body.metadata = params.metadata;
3137
+ }
3138
+ const paymentClient = createPaymentClient(params.walletClient);
3139
+ const response = await paymentClient.post("/credits/purchase/x402", body);
3140
+ const parsed = client.parseWithSchema(
3141
+ response.data,
3142
+ x402CreditPurchaseResponseSchema,
3143
+ "x402 credit purchase response"
3144
+ );
3145
+ const responseHeaders = response.headers ?? {};
3146
+ const paymentHeader = typeof responseHeaders["x-payment-response"] === "string" ? responseHeaders["x-payment-response"] : void 0;
3147
+ const decodedPayment = paymentHeader !== void 0 ? decodePaymentResponse(paymentHeader) : void 0;
2892
3148
  return {
2893
- canonical: `eip155:${chainId}`,
2894
- kind: "evm",
2895
- chainId,
2896
- legacyName: alias
3149
+ ...parsed,
3150
+ paymentResponseHeader: paymentHeader,
3151
+ paymentResponse: decodedPayment
2897
3152
  };
2898
- };
2899
- var normaliseHederaNetwork = (value) => {
2900
- const trimmed = normalise(value);
2901
- const mapping = HEDERA_NETWORK_ALIASES.get(trimmed);
2902
- if (!mapping) {
2903
- throw new Error(
2904
- 'Unsupported Hedera network. Use hedera:mainnet or hedera:testnet (legacy "mainnet"/"testnet" also accepted).'
2905
- );
3153
+ }
3154
+ async function buyCreditsWithX402(client, params) {
3155
+ const network = params.network ?? "base";
3156
+ const { createX402Signer } = await loadX402Dependencies(client);
3157
+ const normalizedKey = normalizeHexPrivateKey(params.evmPrivateKey);
3158
+ const walletClient = await createX402Signer(network, normalizedKey);
3159
+ return purchaseCreditsWithX402(client, {
3160
+ accountId: params.accountId,
3161
+ credits: params.credits,
3162
+ usdAmount: params.usdAmount,
3163
+ description: params.description,
3164
+ metadata: params.metadata,
3165
+ walletClient
3166
+ });
3167
+ }
3168
+
3169
+ // ../../src/services/registry-broker/client/errors.ts
3170
+ var RegistryBrokerError = class extends Error {
3171
+ constructor(message, details) {
3172
+ super(message);
3173
+ this.status = details.status;
3174
+ this.statusText = details.statusText;
3175
+ this.body = details.body;
2906
3176
  }
2907
- return {
2908
- canonical: mapping.canonical,
2909
- kind: "hedera",
2910
- hederaNetwork: mapping.hederaNetwork
2911
- };
2912
3177
  };
2913
- var canonicalizeLedgerNetwork = (network) => {
2914
- if (typeof network !== "string" || network.trim().length === 0) {
2915
- throw new Error("Ledger network is required.");
2916
- }
2917
- const trimmed = normalise(network);
2918
- if (trimmed.startsWith("hedera:") || trimmed.includes("hedera-") || trimmed.includes("hedera_") || trimmed === "mainnet" || trimmed === "testnet") {
2919
- return normaliseHederaNetwork(trimmed);
3178
+ var RegistryBrokerParseError = class extends Error {
3179
+ constructor(message, cause, rawValue) {
3180
+ super(message);
3181
+ this.cause = cause;
3182
+ this.rawValue = rawValue;
2920
3183
  }
2921
- return normaliseEvmNetwork(trimmed);
2922
3184
  };
2923
3185
 
2924
- // ../../src/services/registry-broker/private-key-signer.ts
2925
- var unsupported = (method) => new Error(`${method} is not supported by the in-memory signer`);
2926
- var cachedSdk = null;
2927
- var loadHashgraphSdk = () => {
2928
- if (cachedSdk) {
2929
- return cachedSdk;
3186
+ // ../../src/services/registry-broker/client/agents.ts
3187
+ async function performRegisterAgent(client, payload) {
3188
+ const raw = await client.requestJson("/register", {
3189
+ method: "POST",
3190
+ body: serialiseAgentRegistrationRequest(payload),
3191
+ headers: { "content-type": "application/json" }
3192
+ });
3193
+ return client.parseWithSchema(
3194
+ raw,
3195
+ registerAgentResponseSchema,
3196
+ "register agent response"
3197
+ );
3198
+ }
3199
+ function calculateHbarAmount(creditsToPurchase, creditsPerHbar) {
3200
+ if (creditsPerHbar <= 0) {
3201
+ throw new Error("creditsPerHbar must be positive");
2930
3202
  }
2931
- const resolved = optionalImportSync("@hashgraph/sdk");
2932
- if (resolved) {
2933
- cachedSdk = resolved;
2934
- return resolved;
3203
+ if (creditsToPurchase <= 0) {
3204
+ throw new Error("creditsToPurchase must be positive");
2935
3205
  }
2936
- const message = "@hashgraph/sdk is required for ledger signing. Install it as a dependency to enable createPrivateKeySigner.";
2937
- throw new Error(message);
2938
- };
2939
- var loadHashgraphSdkAsync = async () => {
2940
- if (cachedSdk) {
2941
- return cachedSdk;
3206
+ const rawHbar = creditsToPurchase / creditsPerHbar;
3207
+ const tinybars = Math.ceil(rawHbar * 1e8);
3208
+ return tinybars / 1e8;
3209
+ }
3210
+ function resolveCreditsToPurchase(shortfallCredits) {
3211
+ if (!Number.isFinite(shortfallCredits) || shortfallCredits <= 0) {
3212
+ return 0;
2942
3213
  }
2943
- const resolved = await optionalImport("@hashgraph/sdk");
2944
- if (resolved) {
2945
- cachedSdk = resolved;
2946
- return resolved;
3214
+ return Math.max(
3215
+ Math.ceil(shortfallCredits),
3216
+ MINIMUM_REGISTRATION_AUTO_TOP_UP_CREDITS
3217
+ );
3218
+ }
3219
+ async function ensureCreditsForRegistration(client, payload, autoTopUp) {
3220
+ const details = autoTopUp ?? null;
3221
+ if (!details) {
3222
+ return;
2947
3223
  }
2948
- const message = "@hashgraph/sdk is required for ledger signing. Install it as a dependency to enable createPrivateKeySigner.";
2949
- throw new Error(message);
2950
- };
2951
- var buildSigner = (sdk, options) => {
2952
- const { AccountId, LedgerId, PrivateKey, SignerSignature } = sdk;
2953
- if (!options.privateKey) {
2954
- throw new Error("privateKey is required to create a ledger signer.");
3224
+ if (!details.accountId || !details.accountId.trim()) {
3225
+ throw new Error("autoTopUp.accountId is required");
2955
3226
  }
2956
- if (!options.accountId) {
2957
- throw new Error("accountId is required to create a ledger signer.");
3227
+ if (!details.privateKey || !details.privateKey.trim()) {
3228
+ throw new Error("autoTopUp.privateKey is required");
2958
3229
  }
2959
- const accountId = AccountId.fromString(options.accountId);
2960
- const privateKey = PrivateKey.fromString(options.privateKey);
2961
- const ledgerId = LedgerId.fromString(options.network);
2962
- return {
2963
- getLedgerId: () => ledgerId,
2964
- getAccountId: () => accountId,
2965
- getAccountKey: () => privateKey.publicKey,
2966
- getNetwork: () => ({}),
2967
- getMirrorNetwork: () => [],
2968
- sign: async (messages) => Promise.all(
2969
- messages.map(async (message) => {
2970
- const signature = await privateKey.sign(message);
2971
- return new SignerSignature({
2972
- publicKey: privateKey.publicKey,
2973
- signature,
2974
- accountId
2975
- });
2976
- })
2977
- ),
2978
- getAccountBalance: async () => {
2979
- throw unsupported("getAccountBalance");
2980
- },
2981
- getAccountInfo: async () => {
2982
- throw unsupported("getAccountInfo");
2983
- },
2984
- getAccountRecords: async () => {
2985
- throw unsupported("getAccountRecords");
2986
- },
2987
- signTransaction: async (_) => {
2988
- throw unsupported("signTransaction");
2989
- },
2990
- checkTransaction: async (_) => {
2991
- throw unsupported("checkTransaction");
2992
- },
2993
- populateTransaction: async (_) => {
2994
- throw unsupported("populateTransaction");
2995
- },
2996
- call: async (_request) => {
2997
- throw unsupported("call");
3230
+ for (let attempt = 0; attempt < 3; attempt += 1) {
3231
+ const quote = await getRegistrationQuote(client, payload);
3232
+ const shortfall = quote.shortfallCredits ?? 0;
3233
+ if (shortfall <= 0) {
3234
+ return;
2998
3235
  }
2999
- };
3000
- };
3001
- var createPrivateKeySigner = (options) => buildSigner(loadHashgraphSdk(), options);
3002
- var createPrivateKeySignerAsync = async (options) => buildSigner(await loadHashgraphSdkAsync(), options);
3003
-
3004
- // ../../src/services/registry-broker/client/ledger-auth.ts
3005
- async function loadViemAccount(privateKey) {
3006
- try {
3007
- const viem = await import("viem/accounts");
3008
- return viem.privateKeyToAccount(privateKey);
3009
- } catch (error) {
3010
- const err = new Error(
3011
- 'EVM ledger authentication requires the optional dependency "viem". Install it to use evmPrivateKey flows.'
3012
- );
3013
- err.cause = error;
3014
- throw err;
3015
- }
3016
- }
3017
- async function resolveLedgerAuthSignature(message, options) {
3018
- if (typeof options.sign === "function") {
3019
- const result = await options.sign(message);
3020
- if (!result || typeof result.signature !== "string" || result.signature.length === 0) {
3021
- throw new Error("Custom ledger signer failed to produce a signature.");
3236
+ const creditsToPurchase = resolveCreditsToPurchase(shortfall);
3237
+ if (creditsToPurchase <= 0) {
3238
+ return;
3022
3239
  }
3023
- return result;
3240
+ const creditsPerHbar = quote.creditsPerHbar ?? null;
3241
+ if (!creditsPerHbar || creditsPerHbar <= 0) {
3242
+ throw new Error("Unable to determine credits per HBAR for auto top-up");
3243
+ }
3244
+ const hbarAmount = calculateHbarAmount(creditsToPurchase, creditsPerHbar);
3245
+ await purchaseCreditsWithHbar(client, {
3246
+ accountId: details.accountId.trim(),
3247
+ privateKey: details.privateKey.trim(),
3248
+ hbarAmount,
3249
+ memo: details.memo ?? "Registry Broker auto top-up",
3250
+ metadata: {
3251
+ shortfallCredits: shortfall,
3252
+ requiredCredits: quote.requiredCredits,
3253
+ purchasedCredits: creditsToPurchase
3254
+ }
3255
+ });
3024
3256
  }
3025
- if (!options.signer || typeof options.signer.sign !== "function") {
3026
- throw new Error(
3027
- "Ledger authentication requires a Hedera Signer or custom sign function."
3028
- );
3257
+ const finalQuote = await getRegistrationQuote(client, payload);
3258
+ if ((finalQuote.shortfallCredits ?? 0) > 0) {
3259
+ throw new Error("Unable to purchase sufficient credits for registration");
3029
3260
  }
3030
- const payload = import_buffer2.Buffer.from(message, "utf8");
3031
- const signatures = await options.signer.sign([payload]);
3032
- const signatureEntry = signatures?.[0];
3033
- if (!signatureEntry) {
3034
- throw new Error("Signer did not return any signatures.");
3261
+ }
3262
+ async function resolveUaid(client, uaid) {
3263
+ const raw = await client.requestJson(
3264
+ `/resolve/${encodeURIComponent(uaid)}`,
3265
+ {
3266
+ method: "GET"
3267
+ }
3268
+ );
3269
+ return client.parseWithSchema(
3270
+ raw,
3271
+ resolveResponseSchema,
3272
+ "resolve UAID response"
3273
+ );
3274
+ }
3275
+ async function registerAgent(client, payload, options) {
3276
+ const autoTopUp = options?.autoTopUp ?? client.registrationAutoTopUp;
3277
+ if (!autoTopUp) {
3278
+ return performRegisterAgent(client, payload);
3035
3279
  }
3036
- let derivedPublicKey;
3037
- if (signatureEntry.publicKey) {
3038
- derivedPublicKey = signatureEntry.publicKey.toString();
3039
- } else if (typeof options.signer.getAccountKey === "function") {
3040
- const accountKey = await options.signer.getAccountKey();
3041
- if (accountKey && typeof accountKey.toString === "function") {
3042
- derivedPublicKey = accountKey.toString();
3280
+ await ensureCreditsForRegistration(client, payload, autoTopUp);
3281
+ let retried = false;
3282
+ while (true) {
3283
+ try {
3284
+ return await performRegisterAgent(client, payload);
3285
+ } catch (error) {
3286
+ const shortfall = client.extractInsufficientCreditsDetails(error);
3287
+ if (shortfall && !retried) {
3288
+ await ensureCreditsForRegistration(client, payload, autoTopUp);
3289
+ retried = true;
3290
+ continue;
3291
+ }
3292
+ throw error;
3043
3293
  }
3044
3294
  }
3045
- return {
3046
- signature: import_buffer2.Buffer.from(signatureEntry.signature).toString("base64"),
3047
- signatureKind: "raw",
3048
- publicKey: derivedPublicKey
3049
- };
3050
3295
  }
3051
- async function createLedgerChallenge(client, payload) {
3052
- const resolvedNetwork = canonicalizeLedgerNetwork(payload.network);
3053
- const network = resolvedNetwork.kind === "hedera" ? resolvedNetwork.hederaNetwork ?? resolvedNetwork.canonical : resolvedNetwork.canonical;
3054
- const raw = await client.requestJson("/auth/ledger/challenge", {
3296
+ async function getRegistrationQuote(client, payload) {
3297
+ const raw = await client.requestJson("/register/quote", {
3055
3298
  method: "POST",
3056
- headers: { "content-type": "application/json" },
3057
- body: {
3058
- accountId: payload.accountId,
3059
- network
3299
+ body: serialiseAgentRegistrationRequest(payload),
3300
+ headers: { "content-type": "application/json" }
3301
+ });
3302
+ return client.parseWithSchema(
3303
+ raw,
3304
+ registrationQuoteResponseSchema,
3305
+ "registration quote response"
3306
+ );
3307
+ }
3308
+ async function updateAgent(client, uaid, payload) {
3309
+ const raw = await client.requestJson(
3310
+ `/register/${encodeURIComponent(uaid)}`,
3311
+ {
3312
+ method: "PUT",
3313
+ body: serialiseAgentRegistrationRequest(payload),
3314
+ headers: { "content-type": "application/json" }
3060
3315
  }
3061
- });
3316
+ );
3062
3317
  return client.parseWithSchema(
3063
3318
  raw,
3064
- ledgerChallengeResponseSchema,
3065
- "ledger challenge response"
3319
+ registerAgentResponseSchema,
3320
+ "update agent response"
3066
3321
  );
3067
3322
  }
3068
- async function verifyLedgerChallenge(client, payload) {
3069
- const resolvedNetwork = canonicalizeLedgerNetwork(payload.network);
3070
- const network = resolvedNetwork.kind === "hedera" ? resolvedNetwork.hederaNetwork ?? resolvedNetwork.canonical : resolvedNetwork.canonical;
3071
- const body = {
3072
- challengeId: payload.challengeId,
3073
- accountId: payload.accountId,
3074
- network,
3075
- signature: payload.signature
3076
- };
3077
- if (payload.signatureKind) {
3078
- body.signatureKind = payload.signatureKind;
3323
+ async function getRegistrationProgress(client, attemptId) {
3324
+ const normalisedAttemptId = attemptId.trim();
3325
+ if (!normalisedAttemptId) {
3326
+ throw new Error("attemptId is required");
3079
3327
  }
3080
- if (payload.publicKey) {
3081
- body.publicKey = payload.publicKey;
3328
+ try {
3329
+ const raw = await client.requestJson(
3330
+ `/register/progress/${encodeURIComponent(normalisedAttemptId)}`,
3331
+ { method: "GET" }
3332
+ );
3333
+ const parsed = client.parseWithSchema(
3334
+ raw,
3335
+ registrationProgressResponseSchema,
3336
+ "registration progress response"
3337
+ );
3338
+ return parsed.progress;
3339
+ } catch (error) {
3340
+ if (error instanceof RegistryBrokerError && error.status === 404) {
3341
+ return null;
3342
+ }
3343
+ throw error;
3082
3344
  }
3083
- if (typeof payload.expiresInMinutes === "number") {
3084
- body.expiresInMinutes = payload.expiresInMinutes;
3345
+ }
3346
+ async function waitForRegistrationCompletion(client, attemptId, options = {}) {
3347
+ const normalisedAttemptId = attemptId.trim();
3348
+ if (!normalisedAttemptId) {
3349
+ throw new Error("attemptId is required");
3085
3350
  }
3086
- const raw = await client.requestJson("/auth/ledger/verify", {
3087
- method: "POST",
3088
- headers: { "content-type": "application/json" },
3089
- body
3090
- });
3091
- const result = client.parseWithSchema(
3092
- raw,
3093
- ledgerVerifyResponseSchema,
3094
- "ledger verification response"
3351
+ const interval = Math.max(
3352
+ 250,
3353
+ options.intervalMs ?? DEFAULT_PROGRESS_INTERVAL_MS
3095
3354
  );
3096
- client.setLedgerApiKey(result.key);
3097
- return result;
3098
- }
3099
- async function authenticateWithLedger(client, options) {
3100
- const challenge = await client.createLedgerChallenge({
3101
- accountId: options.accountId,
3102
- network: options.network
3103
- });
3104
- const signed = await resolveLedgerAuthSignature(challenge.message, options);
3105
- const verification = await client.verifyLedgerChallenge({
3106
- challengeId: challenge.challengeId,
3107
- accountId: options.accountId,
3108
- network: options.network,
3109
- signature: signed.signature,
3110
- signatureKind: signed.signatureKind,
3111
- publicKey: signed.publicKey,
3112
- expiresInMinutes: options.expiresInMinutes
3113
- });
3114
- return verification;
3115
- }
3116
- async function authenticateWithLedgerCredentials(client, options) {
3117
- const {
3118
- accountId,
3119
- network,
3120
- signer,
3121
- sign,
3122
- hederaPrivateKey,
3123
- evmPrivateKey,
3124
- expiresInMinutes,
3125
- setAccountHeader = true,
3126
- label,
3127
- logger
3128
- } = options;
3129
- const resolvedNetwork = canonicalizeLedgerNetwork(network);
3130
- const labelSuffix = label ? ` for ${label}` : "";
3131
- const networkPayload = resolvedNetwork.canonical;
3132
- const authOptions = {
3133
- accountId,
3134
- network: networkPayload,
3135
- expiresInMinutes
3136
- };
3137
- if (sign) {
3138
- authOptions.sign = sign;
3139
- } else if (signer) {
3140
- authOptions.signer = signer;
3141
- } else if (hederaPrivateKey) {
3142
- if (resolvedNetwork.kind !== "hedera" || !resolvedNetwork.hederaNetwork) {
3143
- throw new Error(
3144
- "hederaPrivateKey can only be used with hedera:mainnet or hedera:testnet networks."
3145
- );
3355
+ const timeoutMs = options.timeoutMs ?? DEFAULT_PROGRESS_TIMEOUT_MS;
3356
+ const throwOnFailure = options.throwOnFailure ?? true;
3357
+ const signal = options.signal;
3358
+ const startedAt = Date.now();
3359
+ while (true) {
3360
+ if (signal?.aborted) {
3361
+ throw createAbortError();
3146
3362
  }
3147
- authOptions.signer = await createPrivateKeySignerAsync({
3148
- accountId,
3149
- privateKey: hederaPrivateKey,
3150
- network: resolvedNetwork.hederaNetwork
3151
- });
3152
- } else if (evmPrivateKey) {
3153
- if (resolvedNetwork.kind !== "evm") {
3363
+ const progress = await client.getRegistrationProgress(normalisedAttemptId);
3364
+ if (progress) {
3365
+ options.onProgress?.(progress);
3366
+ if (progress.status === "completed") {
3367
+ return progress;
3368
+ }
3369
+ if (progress.status === "partial" || progress.status === "failed") {
3370
+ if (throwOnFailure) {
3371
+ throw new RegistryBrokerError(
3372
+ "Registration did not complete successfully",
3373
+ {
3374
+ status: 409,
3375
+ statusText: progress.status,
3376
+ body: progress
3377
+ }
3378
+ );
3379
+ }
3380
+ return progress;
3381
+ }
3382
+ }
3383
+ if (Date.now() - startedAt >= timeoutMs) {
3154
3384
  throw new Error(
3155
- "evmPrivateKey can only be used with CAIP-2 EVM networks (eip155:<chainId>)."
3385
+ `Registration progress polling timed out after ${timeoutMs}ms`
3156
3386
  );
3157
3387
  }
3158
- const formattedKey = evmPrivateKey.startsWith("0x") ? evmPrivateKey : `0x${evmPrivateKey}`;
3159
- const account = await loadViemAccount(formattedKey);
3160
- authOptions.sign = async (message) => ({
3161
- signature: await account.signMessage({ message }),
3162
- signatureKind: "evm",
3163
- publicKey: account.publicKey
3164
- });
3165
- } else {
3166
- throw new Error(
3167
- "Provide a signer, sign function, hederaPrivateKey, or evmPrivateKey to authenticate with the ledger."
3168
- );
3388
+ await client.delay(interval, signal);
3169
3389
  }
3170
- logger?.info?.(
3171
- `Authenticating ledger account ${accountId} (${resolvedNetwork.canonical})${labelSuffix}...`
3390
+ }
3391
+ async function validateUaid(client, uaid) {
3392
+ const raw = await client.requestJson(
3393
+ `/uaids/validate/${encodeURIComponent(uaid)}`,
3394
+ {
3395
+ method: "GET"
3396
+ }
3172
3397
  );
3173
- const verification = await client.authenticateWithLedger(authOptions);
3174
- if (setAccountHeader) {
3175
- client.setDefaultHeader("x-account-id", verification.accountId);
3176
- }
3177
- logger?.info?.(
3178
- `Ledger authentication complete${labelSuffix}. Issued key prefix: ${verification.apiKey.prefix}\u2026${verification.apiKey.lastFour}`
3398
+ return client.parseWithSchema(
3399
+ raw,
3400
+ uaidValidationResponseSchema,
3401
+ "UAID validation response"
3179
3402
  );
3180
- return verification;
3181
- }
3182
-
3183
- // ../../src/services/registry-broker/client/chat-history.ts
3184
- var import_buffer3 = require("buffer");
3185
- function identitiesMatch(a, b) {
3186
- if (!a && !b) {
3187
- return true;
3188
- }
3189
- if (!a || !b) {
3190
- return false;
3191
- }
3192
- if (a.uaid && b.uaid && a.uaid.toLowerCase() === b.uaid.toLowerCase()) {
3193
- return true;
3194
- }
3195
- if (a.ledgerAccountId && b.ledgerAccountId && a.ledgerAccountId.toLowerCase() === b.ledgerAccountId.toLowerCase()) {
3196
- return true;
3197
- }
3198
- if (a.userId && b.userId && a.userId === b.userId) {
3199
- return true;
3200
- }
3201
- if (a.email && b.email && a.email.toLowerCase() === b.email.toLowerCase()) {
3202
- return true;
3203
- }
3204
- return false;
3205
3403
  }
3206
- async function fetchHistorySnapshot(conversationContexts, client, sessionId, options) {
3207
- if (!sessionId || sessionId.trim().length === 0) {
3208
- throw new Error("sessionId is required to fetch chat history");
3209
- }
3404
+ async function getUaidConnectionStatus(client, uaid) {
3210
3405
  const raw = await client.requestJson(
3211
- `/chat/session/${encodeURIComponent(sessionId)}/history`,
3406
+ `/uaids/connections/${encodeURIComponent(uaid)}/status`,
3212
3407
  {
3213
3408
  method: "GET"
3214
3409
  }
3215
3410
  );
3216
- const snapshot = client.parseWithSchema(
3411
+ return client.parseWithSchema(
3217
3412
  raw,
3218
- chatHistorySnapshotResponseSchema,
3219
- "chat history snapshot response"
3413
+ uaidConnectionStatusSchema,
3414
+ "UAID connection status"
3220
3415
  );
3221
- return attachDecryptedHistory(
3222
- conversationContexts,
3223
- client,
3224
- sessionId,
3225
- snapshot,
3226
- options
3416
+ }
3417
+ async function closeUaidConnection(client, uaid) {
3418
+ await client.request(`/uaids/connections/${encodeURIComponent(uaid)}`, {
3419
+ method: "DELETE"
3420
+ });
3421
+ }
3422
+ async function dashboardStats(client) {
3423
+ const raw = await client.requestJson("/dashboard/stats", {
3424
+ method: "GET"
3425
+ });
3426
+ return client.parseWithSchema(
3427
+ raw,
3428
+ dashboardStatsResponseSchema,
3429
+ "dashboard stats response"
3227
3430
  );
3228
3431
  }
3229
- function attachDecryptedHistory(conversationContexts, client, sessionId, snapshot, options) {
3230
- const shouldDecrypt = options?.decrypt !== void 0 ? options.decrypt : client.encryptionOptions?.autoDecryptHistory === true;
3231
- if (!shouldDecrypt) {
3232
- return snapshot;
3233
- }
3234
- const requiresContext = snapshot.history.some(
3235
- (entry) => Boolean(entry.cipherEnvelope)
3432
+
3433
+ // ../../src/services/registry-broker/client/verification.ts
3434
+ async function getVerificationStatus(client, uaid) {
3435
+ const raw = await client.requestJson(
3436
+ `/verification/status/${encodeURIComponent(uaid)}`,
3437
+ { method: "GET" }
3438
+ );
3439
+ return client.parseWithSchema(
3440
+ raw,
3441
+ verificationStatusResponseSchema,
3442
+ "verification status response"
3236
3443
  );
3237
- if (!requiresContext) {
3238
- return {
3239
- ...snapshot,
3240
- decryptedHistory: snapshot.history.map((entry) => ({
3241
- entry,
3242
- plaintext: entry.content
3243
- }))
3244
- };
3245
- }
3246
- const context = resolveDecryptionContext(
3247
- conversationContexts,
3248
- client,
3249
- sessionId,
3250
- options
3444
+ }
3445
+ async function createVerificationChallenge(client, uaid) {
3446
+ const raw = await client.requestJson("/verification/challenge", {
3447
+ method: "POST",
3448
+ headers: { "content-type": "application/json" },
3449
+ body: { uaid }
3450
+ });
3451
+ return client.parseWithSchema(
3452
+ raw,
3453
+ verificationChallengeResponseSchema,
3454
+ "verification challenge response"
3251
3455
  );
3252
- if (!context) {
3253
- throw new Error(
3254
- "Unable to decrypt chat history: encryption context unavailable"
3255
- );
3256
- }
3257
- const decryptedHistory = snapshot.history.map((entry) => ({
3258
- entry,
3259
- plaintext: decryptHistoryEntryFromContext(client, entry, context)
3260
- }));
3261
- return { ...snapshot, decryptedHistory };
3262
3456
  }
3263
- function registerConversationContextForEncryption(conversationContexts, context) {
3264
- const normalized = {
3265
- sessionId: context.sessionId,
3266
- sharedSecret: import_buffer3.Buffer.from(context.sharedSecret),
3267
- identity: context.identity ? { ...context.identity } : void 0
3268
- };
3269
- const entries = conversationContexts.get(context.sessionId) ?? [];
3270
- const existingIndex = entries.findIndex(
3271
- (existing) => identitiesMatch(existing.identity, normalized.identity)
3457
+ async function getVerificationChallenge(client, challengeId) {
3458
+ const raw = await client.requestJson(
3459
+ `/verification/challenge/${encodeURIComponent(challengeId)}`,
3460
+ { method: "GET" }
3461
+ );
3462
+ return client.parseWithSchema(
3463
+ raw,
3464
+ verificationChallengeDetailsResponseSchema,
3465
+ "verification challenge details response"
3272
3466
  );
3273
- if (existingIndex >= 0) {
3274
- entries[existingIndex] = normalized;
3275
- } else {
3276
- entries.push(normalized);
3277
- }
3278
- conversationContexts.set(context.sessionId, entries);
3279
3467
  }
3280
- function resolveDecryptionContext(conversationContexts, client, sessionId, options) {
3281
- if (options?.sharedSecret) {
3282
- return {
3283
- sessionId,
3284
- sharedSecret: client.normalizeSharedSecret(options.sharedSecret),
3285
- identity: options.identity
3286
- };
3287
- }
3288
- const contexts = conversationContexts.get(sessionId);
3289
- if (!contexts || contexts.length === 0) {
3290
- return null;
3291
- }
3292
- if (options?.identity) {
3293
- const match = contexts.find(
3294
- (context) => identitiesMatch(context.identity, options.identity)
3295
- );
3296
- if (match) {
3297
- return match;
3468
+ async function verifyVerificationChallenge(client, params) {
3469
+ const raw = await client.requestJson("/verification/verify", {
3470
+ method: "POST",
3471
+ headers: { "content-type": "application/json" },
3472
+ body: {
3473
+ challengeId: params.challengeId,
3474
+ method: params.method ?? "moltbook-post"
3298
3475
  }
3299
- }
3300
- return contexts[0];
3476
+ });
3477
+ return client.parseWithSchema(
3478
+ raw,
3479
+ verificationVerifyResponseSchema,
3480
+ "verification verify response"
3481
+ );
3301
3482
  }
3302
- function decryptHistoryEntryFromContext(client, entry, context) {
3303
- const envelope = entry.cipherEnvelope;
3304
- if (!envelope) {
3305
- return entry.content;
3306
- }
3307
- const secret = import_buffer3.Buffer.from(context.sharedSecret);
3308
- try {
3309
- return client.encryption.decryptCipherEnvelope({
3310
- envelope,
3311
- sharedSecret: secret
3312
- });
3313
- } catch (_error) {
3314
- return null;
3315
- }
3483
+ async function getVerificationOwnership(client, uaid) {
3484
+ const raw = await client.requestJson(
3485
+ `/verification/ownership/${encodeURIComponent(uaid)}`,
3486
+ { method: "GET" }
3487
+ );
3488
+ return client.parseWithSchema(
3489
+ raw,
3490
+ verificationOwnershipResponseSchema,
3491
+ "verification ownership response"
3492
+ );
3316
3493
  }
3317
-
3318
- // ../../src/services/registry-broker/client/encrypted-chat-manager.ts
3319
- var EncryptionUnavailableError = class extends Error {
3320
- constructor(sessionId, summary) {
3321
- super("Encryption is not enabled for this session");
3322
- this.sessionId = sessionId;
3323
- this.summary = summary;
3324
- }
3325
- };
3326
- var EncryptedChatManager = class {
3327
- constructor(client) {
3328
- this.client = client;
3329
- }
3330
- registerConversationContext(context) {
3331
- this.client.registerConversationContextForEncryption(context);
3332
- }
3333
- async startSession(options) {
3334
- await this.client.encryptionReady();
3335
- const session = await this.client.chat.createSession({
3336
- uaid: options.uaid,
3337
- senderUaid: options.senderUaid,
3338
- encryptionRequested: true,
3339
- historyTtlSeconds: options.historyTtlSeconds,
3340
- auth: options.auth
3341
- });
3342
- options.onSessionCreated?.(session.sessionId);
3343
- const summary = session.encryption;
3344
- if (!summary?.enabled) {
3345
- throw new EncryptionUnavailableError(
3346
- session.sessionId,
3347
- session.encryption ?? null
3348
- );
3349
- }
3350
- const handle = await this.establishRequesterContext({
3351
- sessionId: session.sessionId,
3352
- summary,
3353
- senderUaid: options.senderUaid,
3354
- handshakeTimeoutMs: options.handshakeTimeoutMs,
3355
- pollIntervalMs: options.pollIntervalMs
3356
- });
3357
- return handle;
3358
- }
3359
- async acceptSession(options) {
3360
- await this.client.encryptionReady();
3361
- const summary = await this.waitForEncryptionSummary(
3362
- options.sessionId,
3363
- options.handshakeTimeoutMs,
3364
- options.pollIntervalMs
3365
- );
3366
- const handle = await this.establishResponderContext({
3367
- sessionId: options.sessionId,
3368
- summary,
3369
- responderUaid: options.responderUaid,
3370
- handshakeTimeoutMs: options.handshakeTimeoutMs,
3371
- pollIntervalMs: options.pollIntervalMs
3372
- });
3373
- return handle;
3374
- }
3375
- async establishRequesterContext(params) {
3376
- const keyPair = this.client.encryption.generateEphemeralKeyPair();
3377
- await this.client.chat.submitEncryptionHandshake(params.sessionId, {
3378
- role: "requester",
3379
- keyType: "secp256k1",
3380
- ephemeralPublicKey: keyPair.publicKey,
3381
- uaid: params.senderUaid ?? params.summary.requester?.uaid ?? void 0
3382
- });
3383
- const { summary, record } = await this.waitForHandshakeCompletion(
3384
- params.sessionId,
3385
- params.handshakeTimeoutMs,
3386
- params.pollIntervalMs
3387
- );
3388
- const responderKey = record.responder?.ephemeralPublicKey;
3389
- if (!responderKey) {
3390
- throw new Error("Responder handshake was not completed in time");
3391
- }
3392
- const sharedSecret = this.client.encryption.deriveSharedSecret({
3393
- privateKey: keyPair.privateKey,
3394
- peerPublicKey: responderKey
3395
- }).subarray();
3396
- const recipients = this.buildRecipients(summary);
3397
- return this.createHandle({
3398
- sessionId: params.sessionId,
3399
- sharedSecret,
3400
- summary,
3401
- recipients,
3402
- identity: summary.requester ?? void 0
3403
- });
3404
- }
3405
- async establishResponderContext(params) {
3406
- const keyPair = this.client.encryption.generateEphemeralKeyPair();
3407
- await this.client.chat.submitEncryptionHandshake(params.sessionId, {
3408
- role: "responder",
3409
- keyType: "secp256k1",
3410
- ephemeralPublicKey: keyPair.publicKey,
3411
- uaid: params.responderUaid ?? params.summary.responder?.uaid ?? void 0
3412
- });
3413
- const { summary, record } = await this.waitForHandshakeCompletion(
3414
- params.sessionId,
3415
- params.handshakeTimeoutMs,
3416
- params.pollIntervalMs
3417
- );
3418
- const requesterKey = record.requester?.ephemeralPublicKey;
3419
- if (!requesterKey) {
3420
- throw new Error("Requester handshake was not detected in time");
3494
+ async function verifySenderOwnership(client, uaid) {
3495
+ const raw = await client.requestJson(
3496
+ "/verification/verify-sender",
3497
+ {
3498
+ method: "POST",
3499
+ headers: { "content-type": "application/json" },
3500
+ body: { uaid }
3421
3501
  }
3422
- const sharedSecret = this.client.encryption.deriveSharedSecret({
3423
- privateKey: keyPair.privateKey,
3424
- peerPublicKey: requesterKey
3425
- }).subarray();
3426
- const recipients = this.buildRecipients(summary);
3427
- return this.createHandle({
3428
- sessionId: params.sessionId,
3429
- sharedSecret,
3430
- summary,
3431
- recipients,
3432
- identity: summary.responder ?? void 0
3433
- });
3434
- }
3435
- async waitForHandshakeCompletion(sessionId, timeoutMs = 3e4, pollIntervalMs = 1e3) {
3436
- const deadline = Date.now() + timeoutMs;
3437
- while (true) {
3438
- const status = await this.client.chat.getEncryptionStatus(sessionId);
3439
- const summary = status.encryption;
3440
- const record = summary?.handshake;
3441
- if (summary && record && record.status === "complete") {
3442
- return { summary, record };
3443
- }
3444
- if (Date.now() >= deadline) {
3445
- throw new Error("Timed out waiting for encrypted handshake completion");
3446
- }
3447
- await this.delay(pollIntervalMs);
3502
+ );
3503
+ return client.parseWithSchema(
3504
+ raw,
3505
+ verificationVerifySenderResponseSchema,
3506
+ "verification sender response"
3507
+ );
3508
+ }
3509
+ async function verifyUaidDnsTxt(client, payload) {
3510
+ const raw = await client.requestJson("/verification/dns/verify", {
3511
+ method: "POST",
3512
+ headers: { "content-type": "application/json" },
3513
+ body: {
3514
+ uaid: payload.uaid,
3515
+ ...payload.persist !== void 0 ? { persist: payload.persist } : {}
3448
3516
  }
3517
+ });
3518
+ return client.parseWithSchema(
3519
+ raw,
3520
+ verificationDnsStatusResponseSchema,
3521
+ "verification dns verify response"
3522
+ );
3523
+ }
3524
+ async function getVerificationDnsStatus(client, uaid, query) {
3525
+ const params = new URLSearchParams();
3526
+ if (query?.refresh !== void 0) {
3527
+ params.set("refresh", String(query.refresh));
3449
3528
  }
3450
- async waitForEncryptionSummary(sessionId, _timeoutMs = 3e4, _pollIntervalMs = 1e3) {
3451
- const status = await this.client.chat.getEncryptionStatus(sessionId);
3452
- if (!status.encryption?.enabled) {
3453
- throw new EncryptionUnavailableError(
3454
- sessionId,
3455
- status.encryption ?? null
3456
- );
3457
- }
3458
- return status.encryption;
3529
+ if (query?.persist !== void 0) {
3530
+ params.set("persist", String(query.persist));
3459
3531
  }
3460
- buildRecipients(summary) {
3461
- const candidates = [summary.requester, summary.responder].filter(Boolean);
3462
- const normalized = candidates.map((candidate) => {
3463
- if (!candidate) {
3464
- return null;
3465
- }
3466
- const recipient = {};
3467
- if (candidate.uaid) {
3468
- recipient.uaid = candidate.uaid;
3469
- }
3470
- if (candidate.ledgerAccountId) {
3471
- recipient.ledgerAccountId = candidate.ledgerAccountId;
3472
- }
3473
- if (candidate.userId) {
3474
- recipient.userId = candidate.userId;
3475
- }
3476
- if (candidate.email) {
3477
- recipient.email = candidate.email;
3532
+ const queryString = params.toString();
3533
+ const path = `/verification/dns/status/${encodeURIComponent(uaid)}${queryString ? `?${queryString}` : ""}`;
3534
+ const raw = await client.requestJson(path, {
3535
+ method: "GET"
3536
+ });
3537
+ return client.parseWithSchema(
3538
+ raw,
3539
+ verificationDnsStatusResponseSchema,
3540
+ "verification dns status response"
3541
+ );
3542
+ }
3543
+ async function getRegisterStatus(client, uaid) {
3544
+ const raw = await client.requestJson(
3545
+ `/register/status/${encodeURIComponent(uaid)}`,
3546
+ { method: "GET" }
3547
+ );
3548
+ return client.parseWithSchema(
3549
+ raw,
3550
+ registerStatusResponseSchema,
3551
+ "register status response"
3552
+ );
3553
+ }
3554
+ async function registerOwnedMoltbookAgent(client, uaid, request) {
3555
+ const raw = await client.requestJson(
3556
+ `/register/${encodeURIComponent(uaid)}`,
3557
+ {
3558
+ method: "PUT",
3559
+ headers: { "content-type": "application/json" },
3560
+ body: {
3561
+ registered: request.registered ?? true,
3562
+ ...request.name ? { name: request.name } : {},
3563
+ ...request.description ? { description: request.description } : {},
3564
+ ...request.endpoint ? { endpoint: request.endpoint } : {},
3565
+ ...request.metadata ? { metadata: request.metadata } : {}
3478
3566
  }
3479
- return recipient;
3480
- }).filter(
3481
- (entry) => Boolean(
3482
- entry?.uaid || entry?.ledgerAccountId || entry?.userId || entry?.email
3483
- )
3484
- );
3485
- if (normalized.length > 0) {
3486
- return normalized;
3487
- }
3488
- if (summary.responder?.uaid) {
3489
- return [{ uaid: summary.responder.uaid }];
3490
3567
  }
3491
- return [];
3568
+ );
3569
+ return client.parseWithSchema(
3570
+ raw,
3571
+ moltbookOwnerRegistrationUpdateResponseSchema,
3572
+ "moltbook owner registration update response"
3573
+ );
3574
+ }
3575
+
3576
+ // ../../src/services/registry-broker/client/ledger-auth.ts
3577
+ var import_buffer3 = require("buffer");
3578
+
3579
+ // ../../src/services/registry-broker/ledger-network.ts
3580
+ var normalise = (value) => value.trim().toLowerCase();
3581
+ var HEDERA_NETWORK_ALIASES = /* @__PURE__ */ new Map([
3582
+ ["hedera:mainnet", { canonical: "hedera:mainnet", hederaNetwork: "mainnet" }],
3583
+ ["mainnet", { canonical: "hedera:mainnet", hederaNetwork: "mainnet" }],
3584
+ ["hedera-mainnet", { canonical: "hedera:mainnet", hederaNetwork: "mainnet" }],
3585
+ ["hedera_mainnet", { canonical: "hedera:mainnet", hederaNetwork: "mainnet" }],
3586
+ ["hedera:testnet", { canonical: "hedera:testnet", hederaNetwork: "testnet" }],
3587
+ ["testnet", { canonical: "hedera:testnet", hederaNetwork: "testnet" }],
3588
+ ["hedera-testnet", { canonical: "hedera:testnet", hederaNetwork: "testnet" }],
3589
+ ["hedera_testnet", { canonical: "hedera:testnet", hederaNetwork: "testnet" }]
3590
+ ]);
3591
+ var EVM_NETWORK_CHAIN_IDS = {
3592
+ abstract: 2741,
3593
+ "abstract-testnet": 11124,
3594
+ base: 8453,
3595
+ "base-sepolia": 84532,
3596
+ avalanche: 43114,
3597
+ "avalanche-fuji": 43113,
3598
+ iotex: 4689,
3599
+ sei: 1329,
3600
+ "sei-testnet": 1328,
3601
+ polygon: 137,
3602
+ "polygon-amoy": 80002,
3603
+ peaq: 3338
3604
+ };
3605
+ var CHAIN_ID_TO_ALIAS = new Map(
3606
+ Object.entries(EVM_NETWORK_CHAIN_IDS).map(([alias, id]) => [id, alias])
3607
+ );
3608
+ var parseChainId = (value) => {
3609
+ if (/^eip155:\d+$/i.test(value)) {
3610
+ return Number.parseInt(value.split(":")[1], 10);
3492
3611
  }
3493
- createHandle(context) {
3494
- const sharedSecret = context.sharedSecret;
3495
- const uaid = context.summary.requester?.uaid ?? context.summary.responder?.uaid ?? context.identity?.uaid;
3496
- const decryptHistoryEntry = (entry) => this.decryptEntry(entry, context.identity, sharedSecret);
3497
- const fetchHistory = async (options) => {
3498
- const snapshot = await this.client.fetchHistorySnapshot(
3499
- context.sessionId,
3500
- options
3501
- );
3502
- if (snapshot.decryptedHistory) {
3503
- return snapshot.decryptedHistory;
3504
- }
3505
- return snapshot.history.map((entry) => ({
3506
- entry,
3507
- plaintext: decryptHistoryEntry(entry)
3508
- }));
3509
- };
3510
- const handle = {
3511
- sessionId: context.sessionId,
3512
- mode: "encrypted",
3513
- summary: context.summary,
3514
- send: async (options) => {
3515
- const recipients = options.recipients ?? context.recipients;
3516
- return this.client.chat.sendMessage({
3517
- sessionId: context.sessionId,
3518
- message: options.message ?? "[ciphertext omitted]",
3519
- streaming: options.streaming,
3520
- auth: options.auth,
3521
- uaid,
3522
- encryption: {
3523
- plaintext: options.plaintext,
3524
- sharedSecret: Buffer.from(sharedSecret),
3525
- recipients
3526
- }
3527
- });
3528
- },
3529
- decryptHistoryEntry,
3530
- fetchHistory
3531
- };
3532
- this.registerConversationContext({
3533
- sessionId: context.sessionId,
3534
- sharedSecret,
3535
- identity: context.identity
3536
- });
3537
- return handle;
3612
+ if (/^\d+$/.test(value)) {
3613
+ return Number.parseInt(value, 10);
3538
3614
  }
3539
- decryptEntry(entry, identity, fallbackSecret) {
3540
- const envelope = entry.cipherEnvelope;
3541
- if (!envelope) {
3542
- return null;
3543
- }
3544
- const secret = Buffer.from(fallbackSecret);
3545
- try {
3546
- return this.client.encryption.decryptCipherEnvelope({
3547
- envelope,
3548
- sharedSecret: secret
3549
- });
3550
- } catch (_error) {
3551
- return null;
3615
+ return void 0;
3616
+ };
3617
+ var normaliseEvmNetwork = (value) => {
3618
+ const trimmed = normalise(value);
3619
+ let chainId = parseChainId(trimmed);
3620
+ let alias;
3621
+ if (chainId === void 0) {
3622
+ const mapped = EVM_NETWORK_CHAIN_IDS[trimmed];
3623
+ if (mapped !== void 0) {
3624
+ chainId = mapped;
3625
+ alias = trimmed;
3552
3626
  }
3627
+ } else if (CHAIN_ID_TO_ALIAS.has(chainId)) {
3628
+ alias = CHAIN_ID_TO_ALIAS.get(chainId);
3553
3629
  }
3554
- recipientMatches(candidate, target) {
3555
- if (target.uaid && candidate.uaid?.toLowerCase() === target.uaid.toLowerCase()) {
3556
- return true;
3557
- }
3558
- if (target.ledgerAccountId && candidate.ledgerAccountId?.toLowerCase() === target.ledgerAccountId.toLowerCase()) {
3559
- return true;
3560
- }
3561
- if (target.userId && candidate.userId === target.userId) {
3562
- return true;
3563
- }
3564
- if (target.email && candidate.email?.toLowerCase() === target.email.toLowerCase()) {
3565
- return true;
3566
- }
3567
- return false;
3630
+ if (chainId === void 0) {
3631
+ throw new Error(
3632
+ 'Unsupported EVM ledger network. Provide an alias like "base-sepolia" or a canonical eip155:<chainId> string.'
3633
+ );
3568
3634
  }
3569
- async delay(ms) {
3570
- if (ms <= 0) {
3571
- return;
3572
- }
3573
- await new Promise((resolve2) => setTimeout(resolve2, ms));
3635
+ return {
3636
+ canonical: `eip155:${chainId}`,
3637
+ kind: "evm",
3638
+ chainId,
3639
+ legacyName: alias
3640
+ };
3641
+ };
3642
+ var normaliseHederaNetwork = (value) => {
3643
+ const trimmed = normalise(value);
3644
+ const mapping = HEDERA_NETWORK_ALIASES.get(trimmed);
3645
+ if (!mapping) {
3646
+ throw new Error(
3647
+ 'Unsupported Hedera network. Use hedera:mainnet or hedera:testnet (legacy "mainnet"/"testnet" also accepted).'
3648
+ );
3649
+ }
3650
+ return {
3651
+ canonical: mapping.canonical,
3652
+ kind: "hedera",
3653
+ hederaNetwork: mapping.hederaNetwork
3654
+ };
3655
+ };
3656
+ var canonicalizeLedgerNetwork = (network) => {
3657
+ if (typeof network !== "string" || network.trim().length === 0) {
3658
+ throw new Error("Ledger network is required.");
3659
+ }
3660
+ const trimmed = normalise(network);
3661
+ if (trimmed.startsWith("hedera:") || trimmed.includes("hedera-") || trimmed.includes("hedera_") || trimmed === "mainnet" || trimmed === "testnet") {
3662
+ return normaliseHederaNetwork(trimmed);
3574
3663
  }
3664
+ return normaliseEvmNetwork(trimmed);
3575
3665
  };
3576
3666
 
3577
- // ../../src/services/registry-broker/client/chat.ts
3578
- function createChatApi(client, encryptedManager) {
3579
- return {
3580
- start: (options) => client.startChat(options),
3581
- createSession: (payload) => client.createSession(payload),
3582
- sendMessage: (payload) => client.sendMessage(payload),
3583
- endSession: (sessionId) => client.endSession(sessionId),
3584
- getHistory: (sessionId, options) => client.fetchHistorySnapshot(sessionId, options),
3585
- compactHistory: (payload) => client.compactHistory(payload),
3586
- getEncryptionStatus: (sessionId) => client.fetchEncryptionStatus(sessionId),
3587
- submitEncryptionHandshake: (sessionId, payload) => client.postEncryptionHandshake(sessionId, payload),
3588
- startConversation: (options) => client.startConversation(options),
3589
- acceptConversation: (options) => client.acceptConversation(options),
3590
- createEncryptedSession: (options) => encryptedManager.startSession(options),
3591
- acceptEncryptedSession: (options) => encryptedManager.acceptSession(options)
3592
- };
3593
- }
3594
- async function createSession(client, payload, allowHistoryAutoTopUp = true) {
3595
- const body = {};
3596
- if ("uaid" in payload && payload.uaid) {
3597
- body.uaid = payload.uaid;
3667
+ // ../../src/services/registry-broker/private-key-signer.ts
3668
+ var unsupported = (method) => new Error(`${method} is not supported by the in-memory signer`);
3669
+ var cachedSdk = null;
3670
+ var loadHashgraphSdk = () => {
3671
+ if (cachedSdk) {
3672
+ return cachedSdk;
3598
3673
  }
3599
- if ("agentUrl" in payload && payload.agentUrl) {
3600
- body.agentUrl = payload.agentUrl;
3674
+ const resolved = optionalImportSync("@hashgraph/sdk");
3675
+ if (resolved) {
3676
+ cachedSdk = resolved;
3677
+ return resolved;
3601
3678
  }
3602
- if (payload.auth) {
3603
- body.auth = serialiseAuthConfig(payload.auth);
3679
+ const message = "@hashgraph/sdk is required for ledger signing. Install it as a dependency to enable createPrivateKeySigner.";
3680
+ throw new Error(message);
3681
+ };
3682
+ var loadHashgraphSdkAsync = async () => {
3683
+ if (cachedSdk) {
3684
+ return cachedSdk;
3604
3685
  }
3605
- if (payload.historyTtlSeconds !== void 0) {
3606
- body.historyTtlSeconds = payload.historyTtlSeconds;
3686
+ const resolved = await optionalImport("@hashgraph/sdk");
3687
+ if (resolved) {
3688
+ cachedSdk = resolved;
3689
+ return resolved;
3607
3690
  }
3608
- if (payload.encryptionRequested !== void 0) {
3609
- body.encryptionRequested = payload.encryptionRequested;
3691
+ const message = "@hashgraph/sdk is required for ledger signing. Install it as a dependency to enable createPrivateKeySigner.";
3692
+ throw new Error(message);
3693
+ };
3694
+ var buildSigner = (sdk, options) => {
3695
+ const { AccountId, LedgerId, PrivateKey, SignerSignature } = sdk;
3696
+ if (!options.privateKey) {
3697
+ throw new Error("privateKey is required to create a ledger signer.");
3610
3698
  }
3611
- if (payload.senderUaid) {
3612
- body.senderUaid = payload.senderUaid;
3699
+ if (!options.accountId) {
3700
+ throw new Error("accountId is required to create a ledger signer.");
3613
3701
  }
3702
+ const accountId = AccountId.fromString(options.accountId);
3703
+ const privateKey = PrivateKey.fromString(options.privateKey);
3704
+ const ledgerId = LedgerId.fromString(options.network);
3705
+ return {
3706
+ getLedgerId: () => ledgerId,
3707
+ getAccountId: () => accountId,
3708
+ getAccountKey: () => privateKey.publicKey,
3709
+ getNetwork: () => ({}),
3710
+ getMirrorNetwork: () => [],
3711
+ sign: async (messages) => Promise.all(
3712
+ messages.map(async (message) => {
3713
+ const signature = await privateKey.sign(message);
3714
+ return new SignerSignature({
3715
+ publicKey: privateKey.publicKey,
3716
+ signature,
3717
+ accountId
3718
+ });
3719
+ })
3720
+ ),
3721
+ getAccountBalance: async () => {
3722
+ throw unsupported("getAccountBalance");
3723
+ },
3724
+ getAccountInfo: async () => {
3725
+ throw unsupported("getAccountInfo");
3726
+ },
3727
+ getAccountRecords: async () => {
3728
+ throw unsupported("getAccountRecords");
3729
+ },
3730
+ signTransaction: async (_) => {
3731
+ throw unsupported("signTransaction");
3732
+ },
3733
+ checkTransaction: async (_) => {
3734
+ throw unsupported("checkTransaction");
3735
+ },
3736
+ populateTransaction: async (_) => {
3737
+ throw unsupported("populateTransaction");
3738
+ },
3739
+ call: async (_request) => {
3740
+ throw unsupported("call");
3741
+ }
3742
+ };
3743
+ };
3744
+ var createPrivateKeySigner = (options) => buildSigner(loadHashgraphSdk(), options);
3745
+ var createPrivateKeySignerAsync = async (options) => buildSigner(await loadHashgraphSdkAsync(), options);
3746
+
3747
+ // ../../src/services/registry-broker/client/ledger-auth.ts
3748
+ async function loadViemAccount(privateKey) {
3614
3749
  try {
3615
- const raw = await client.requestJson("/chat/session", {
3616
- method: "POST",
3617
- body,
3618
- headers: { "content-type": "application/json" }
3619
- });
3620
- return client.parseWithSchema(
3621
- raw,
3622
- createSessionResponseSchema,
3623
- "chat session response"
3624
- );
3750
+ const viem = await import("viem/accounts");
3751
+ return viem.privateKeyToAccount(privateKey);
3625
3752
  } catch (error) {
3626
- const maybeError = error instanceof Error ? error : null;
3627
- if (allowHistoryAutoTopUp && client.shouldAutoTopUpHistory(payload, maybeError)) {
3628
- await client.executeHistoryAutoTopUp("chat.session");
3629
- return createSession(client, payload, false);
3630
- }
3631
- throw error;
3632
- }
3633
- }
3634
- async function startChat(client, encryptedManager, options) {
3635
- if ("uaid" in options && options.uaid) {
3636
- return startConversation(client, encryptedManager, {
3637
- uaid: options.uaid,
3638
- senderUaid: options.senderUaid,
3639
- historyTtlSeconds: options.historyTtlSeconds,
3640
- auth: options.auth,
3641
- encryption: options.encryption,
3642
- onSessionCreated: options.onSessionCreated
3643
- });
3644
- }
3645
- if ("agentUrl" in options && options.agentUrl) {
3646
- const session = await createSession(client, {
3647
- agentUrl: options.agentUrl,
3648
- auth: options.auth,
3649
- historyTtlSeconds: options.historyTtlSeconds,
3650
- senderUaid: options.senderUaid
3651
- });
3652
- options.onSessionCreated?.(session.sessionId);
3653
- return createPlaintextConversationHandle(
3654
- client,
3655
- session.sessionId,
3656
- session.encryption ?? null,
3657
- options.auth,
3658
- { agentUrl: options.agentUrl, uaid: options.uaid }
3753
+ const err = new Error(
3754
+ 'EVM ledger authentication requires the optional dependency "viem". Install it to use evmPrivateKey flows.'
3659
3755
  );
3756
+ err.cause = error;
3757
+ throw err;
3660
3758
  }
3661
- throw new Error("startChat requires either uaid or agentUrl");
3662
3759
  }
3663
- async function startConversation(client, encryptedManager, options) {
3664
- const preference = options.encryption?.preference ?? "preferred";
3665
- const requestEncryption = preference !== "disabled";
3666
- if (!requestEncryption) {
3667
- const session = await createSession(client, {
3668
- uaid: options.uaid,
3669
- auth: options.auth,
3670
- historyTtlSeconds: options.historyTtlSeconds,
3671
- senderUaid: options.senderUaid,
3672
- encryptionRequested: false
3673
- });
3674
- options.onSessionCreated?.(session.sessionId);
3675
- return createPlaintextConversationHandle(
3676
- client,
3677
- session.sessionId,
3678
- session.encryption ?? null,
3679
- options.auth,
3680
- { uaid: options.uaid }
3681
- );
3682
- }
3683
- try {
3684
- const handle = await encryptedManager.startSession({
3685
- uaid: options.uaid,
3686
- senderUaid: options.senderUaid,
3687
- historyTtlSeconds: options.historyTtlSeconds,
3688
- handshakeTimeoutMs: options.encryption?.handshakeTimeoutMs,
3689
- pollIntervalMs: options.encryption?.pollIntervalMs,
3690
- onSessionCreated: (sessionId) => {
3691
- options.onSessionCreated?.(sessionId);
3692
- },
3693
- auth: options.auth
3694
- });
3695
- return handle;
3696
- } catch (error) {
3697
- if (error instanceof EncryptionUnavailableError) {
3698
- if (preference === "required") {
3699
- throw error;
3700
- }
3701
- return createPlaintextConversationHandle(
3702
- client,
3703
- error.sessionId,
3704
- error.summary ?? null,
3705
- options.auth,
3706
- { uaid: options.uaid }
3707
- );
3760
+ async function resolveLedgerAuthSignature(message, options) {
3761
+ if (typeof options.sign === "function") {
3762
+ const result = await options.sign(message);
3763
+ if (!result || typeof result.signature !== "string" || result.signature.length === 0) {
3764
+ throw new Error("Custom ledger signer failed to produce a signature.");
3708
3765
  }
3709
- throw error;
3766
+ return result;
3710
3767
  }
3711
- }
3712
- async function acceptConversation(client, encryptedManager, options) {
3713
- const preference = options.encryption?.preference ?? "preferred";
3714
- if (preference === "disabled") {
3715
- return createPlaintextConversationHandle(client, options.sessionId, null);
3768
+ if (!options.signer || typeof options.signer.sign !== "function") {
3769
+ throw new Error(
3770
+ "Ledger authentication requires a Hedera Signer or custom sign function."
3771
+ );
3716
3772
  }
3717
- try {
3718
- const handle = await encryptedManager.acceptSession({
3719
- sessionId: options.sessionId,
3720
- responderUaid: options.responderUaid,
3721
- handshakeTimeoutMs: options.encryption?.handshakeTimeoutMs,
3722
- pollIntervalMs: options.encryption?.pollIntervalMs
3723
- });
3724
- return handle;
3725
- } catch (error) {
3726
- if (error instanceof EncryptionUnavailableError && preference !== "required") {
3727
- return createPlaintextConversationHandle(
3728
- client,
3729
- options.sessionId,
3730
- null,
3731
- void 0,
3732
- { uaid: options.responderUaid }
3733
- );
3734
- }
3735
- throw error;
3773
+ const payload = import_buffer3.Buffer.from(message, "utf8");
3774
+ const signatures = await options.signer.sign([payload]);
3775
+ const signatureEntry = signatures?.[0];
3776
+ if (!signatureEntry) {
3777
+ throw new Error("Signer did not return any signatures.");
3736
3778
  }
3737
- }
3738
- function createPlaintextConversationHandle(client, sessionId, summary, defaultAuth, context) {
3739
- const uaid = context?.uaid?.trim();
3740
- const agentUrl = context?.agentUrl?.trim();
3741
- const fetchHistory = async (options) => {
3742
- const snapshot = await client.fetchHistorySnapshot(sessionId, options);
3743
- if (snapshot.decryptedHistory) {
3744
- return snapshot.decryptedHistory;
3779
+ let derivedPublicKey;
3780
+ if (signatureEntry.publicKey) {
3781
+ derivedPublicKey = signatureEntry.publicKey.toString();
3782
+ } else if (typeof options.signer.getAccountKey === "function") {
3783
+ const accountKey = await options.signer.getAccountKey();
3784
+ if (accountKey && typeof accountKey.toString === "function") {
3785
+ derivedPublicKey = accountKey.toString();
3745
3786
  }
3746
- return snapshot.history.map((entry) => ({
3747
- entry,
3748
- plaintext: entry.content
3749
- }));
3750
- };
3787
+ }
3751
3788
  return {
3752
- sessionId,
3753
- mode: "plaintext",
3754
- summary: summary ?? null,
3755
- send: async (options) => {
3756
- const plaintext = options.plaintext;
3757
- if (!plaintext || plaintext.trim().length === 0) {
3758
- throw new Error("plaintext is required for chat messages");
3759
- }
3760
- const message = options.message ?? plaintext;
3761
- return sendMessage(client, {
3762
- sessionId,
3763
- message,
3764
- streaming: options.streaming,
3765
- auth: options.auth ?? defaultAuth,
3766
- uaid,
3767
- agentUrl
3768
- });
3769
- },
3770
- decryptHistoryEntry: (entry) => entry.content,
3771
- fetchHistory
3789
+ signature: import_buffer3.Buffer.from(signatureEntry.signature).toString("base64"),
3790
+ signatureKind: "raw",
3791
+ publicKey: derivedPublicKey
3772
3792
  };
3773
3793
  }
3774
- async function compactHistory(client, payload) {
3775
- if (!payload.sessionId || payload.sessionId.trim().length === 0) {
3776
- throw new Error("sessionId is required to compact chat history");
3777
- }
3778
- const body = {};
3779
- if (typeof payload.preserveEntries === "number" && Number.isFinite(payload.preserveEntries) && payload.preserveEntries >= 0) {
3780
- body.preserveEntries = Math.floor(payload.preserveEntries);
3781
- }
3782
- const raw = await client.requestJson(
3783
- `/chat/session/${encodeURIComponent(payload.sessionId)}/compact`,
3784
- {
3785
- method: "POST",
3786
- headers: { "content-type": "application/json" },
3787
- body
3794
+ async function createLedgerChallenge(client, payload) {
3795
+ const resolvedNetwork = canonicalizeLedgerNetwork(payload.network);
3796
+ const network = resolvedNetwork.kind === "hedera" ? resolvedNetwork.hederaNetwork ?? resolvedNetwork.canonical : resolvedNetwork.canonical;
3797
+ const raw = await client.requestJson("/auth/ledger/challenge", {
3798
+ method: "POST",
3799
+ headers: { "content-type": "application/json" },
3800
+ body: {
3801
+ accountId: payload.accountId,
3802
+ network
3788
3803
  }
3789
- );
3804
+ });
3790
3805
  return client.parseWithSchema(
3791
3806
  raw,
3792
- chatHistoryCompactionResponseSchema,
3793
- "chat history compaction response"
3807
+ ledgerChallengeResponseSchema,
3808
+ "ledger challenge response"
3794
3809
  );
3795
3810
  }
3796
- async function fetchEncryptionStatus(client, sessionId) {
3797
- if (!sessionId || sessionId.trim().length === 0) {
3798
- throw new Error("sessionId is required for encryption status");
3811
+ async function verifyLedgerChallenge(client, payload) {
3812
+ const resolvedNetwork = canonicalizeLedgerNetwork(payload.network);
3813
+ const network = resolvedNetwork.kind === "hedera" ? resolvedNetwork.hederaNetwork ?? resolvedNetwork.canonical : resolvedNetwork.canonical;
3814
+ const body = {
3815
+ challengeId: payload.challengeId,
3816
+ accountId: payload.accountId,
3817
+ network,
3818
+ signature: payload.signature
3819
+ };
3820
+ if (payload.signatureKind) {
3821
+ body.signatureKind = payload.signatureKind;
3799
3822
  }
3800
- const raw = await client.requestJson(
3801
- `/chat/session/${encodeURIComponent(sessionId)}/encryption`,
3802
- {
3803
- method: "GET"
3804
- }
3805
- );
3806
- return client.parseWithSchema(
3823
+ if (payload.publicKey) {
3824
+ body.publicKey = payload.publicKey;
3825
+ }
3826
+ if (typeof payload.expiresInMinutes === "number") {
3827
+ body.expiresInMinutes = payload.expiresInMinutes;
3828
+ }
3829
+ const raw = await client.requestJson("/auth/ledger/verify", {
3830
+ method: "POST",
3831
+ headers: { "content-type": "application/json" },
3832
+ body
3833
+ });
3834
+ const result = client.parseWithSchema(
3807
3835
  raw,
3808
- sessionEncryptionStatusResponseSchema,
3809
- "session encryption status response"
3836
+ ledgerVerifyResponseSchema,
3837
+ "ledger verification response"
3810
3838
  );
3839
+ client.setLedgerApiKey(result.key);
3840
+ return result;
3811
3841
  }
3812
- async function postEncryptionHandshake(client, sessionId, payload) {
3813
- if (!sessionId || sessionId.trim().length === 0) {
3814
- throw new Error("sessionId is required for encryption handshake");
3815
- }
3816
- const raw = await client.requestJson(
3817
- `/chat/session/${encodeURIComponent(sessionId)}/encryption-handshake`,
3818
- {
3819
- method: "POST",
3820
- headers: { "content-type": "application/json" },
3821
- body: {
3822
- role: payload.role,
3823
- keyType: payload.keyType,
3824
- ephemeralPublicKey: payload.ephemeralPublicKey,
3825
- longTermPublicKey: payload.longTermPublicKey,
3826
- signature: payload.signature,
3827
- uaid: payload.uaid,
3828
- userId: payload.userId,
3829
- ledgerAccountId: payload.ledgerAccountId,
3830
- metadata: payload.metadata
3831
- }
3842
+ async function authenticateWithLedger(client, options) {
3843
+ const challenge = await client.createLedgerChallenge({
3844
+ accountId: options.accountId,
3845
+ network: options.network
3846
+ });
3847
+ const signed = await resolveLedgerAuthSignature(challenge.message, options);
3848
+ const verification = await client.verifyLedgerChallenge({
3849
+ challengeId: challenge.challengeId,
3850
+ accountId: options.accountId,
3851
+ network: options.network,
3852
+ signature: signed.signature,
3853
+ signatureKind: signed.signatureKind,
3854
+ publicKey: signed.publicKey,
3855
+ expiresInMinutes: options.expiresInMinutes
3856
+ });
3857
+ return verification;
3858
+ }
3859
+ async function authenticateWithLedgerCredentials(client, options) {
3860
+ const {
3861
+ accountId,
3862
+ network,
3863
+ signer,
3864
+ sign,
3865
+ hederaPrivateKey,
3866
+ evmPrivateKey,
3867
+ expiresInMinutes,
3868
+ setAccountHeader = true,
3869
+ label,
3870
+ logger
3871
+ } = options;
3872
+ const resolvedNetwork = canonicalizeLedgerNetwork(network);
3873
+ const labelSuffix = label ? ` for ${label}` : "";
3874
+ const networkPayload = resolvedNetwork.canonical;
3875
+ const authOptions = {
3876
+ accountId,
3877
+ network: networkPayload,
3878
+ expiresInMinutes
3879
+ };
3880
+ if (sign) {
3881
+ authOptions.sign = sign;
3882
+ } else if (signer) {
3883
+ authOptions.signer = signer;
3884
+ } else if (hederaPrivateKey) {
3885
+ if (resolvedNetwork.kind !== "hedera" || !resolvedNetwork.hederaNetwork) {
3886
+ throw new Error(
3887
+ "hederaPrivateKey can only be used with hedera:mainnet or hedera:testnet networks."
3888
+ );
3889
+ }
3890
+ authOptions.signer = await createPrivateKeySignerAsync({
3891
+ accountId,
3892
+ privateKey: hederaPrivateKey,
3893
+ network: resolvedNetwork.hederaNetwork
3894
+ });
3895
+ } else if (evmPrivateKey) {
3896
+ if (resolvedNetwork.kind !== "evm") {
3897
+ throw new Error(
3898
+ "evmPrivateKey can only be used with CAIP-2 EVM networks (eip155:<chainId>)."
3899
+ );
3832
3900
  }
3901
+ const formattedKey = evmPrivateKey.startsWith("0x") ? evmPrivateKey : `0x${evmPrivateKey}`;
3902
+ const account = await loadViemAccount(formattedKey);
3903
+ authOptions.sign = async (message) => ({
3904
+ signature: await account.signMessage({ message }),
3905
+ signatureKind: "evm",
3906
+ publicKey: account.publicKey
3907
+ });
3908
+ } else {
3909
+ throw new Error(
3910
+ "Provide a signer, sign function, hederaPrivateKey, or evmPrivateKey to authenticate with the ledger."
3911
+ );
3912
+ }
3913
+ logger?.info?.(
3914
+ `Authenticating ledger account ${accountId} (${resolvedNetwork.canonical})${labelSuffix}...`
3833
3915
  );
3834
- const response = client.parseWithSchema(
3835
- raw,
3836
- encryptionHandshakeResponseSchema,
3837
- "encryption handshake response"
3916
+ const verification = await client.authenticateWithLedger(authOptions);
3917
+ if (setAccountHeader) {
3918
+ client.setDefaultHeader("x-account-id", verification.accountId);
3919
+ }
3920
+ logger?.info?.(
3921
+ `Ledger authentication complete${labelSuffix}. Issued key prefix: ${verification.apiKey.prefix}\u2026${verification.apiKey.lastFour}`
3838
3922
  );
3839
- return response.handshake;
3923
+ return verification;
3840
3924
  }
3841
- async function sendMessage(client, payload) {
3842
- const body = {
3843
- message: payload.message
3925
+
3926
+ // ../../src/services/registry-broker/client/search.ts
3927
+ function buildVectorFallbackSearchParams(request) {
3928
+ const params = {
3929
+ q: request.query
3844
3930
  };
3845
- if (payload.streaming !== void 0) {
3846
- body.streaming = payload.streaming;
3931
+ let effectiveLimit;
3932
+ if (typeof request.limit === "number" && Number.isFinite(request.limit)) {
3933
+ effectiveLimit = request.limit;
3934
+ params.limit = request.limit;
3847
3935
  }
3848
- if (payload.auth) {
3849
- body.auth = serialiseAuthConfig(payload.auth);
3936
+ if (typeof request.offset === "number" && Number.isFinite(request.offset) && request.offset > 0) {
3937
+ const limit = effectiveLimit && effectiveLimit > 0 ? effectiveLimit : 20;
3938
+ params.limit = limit;
3939
+ params.page = Math.floor(request.offset / limit) + 1;
3850
3940
  }
3851
- if ("uaid" in payload) {
3852
- body.uaid = payload.uaid;
3941
+ if (request.filter?.registry) {
3942
+ params.registry = request.filter.registry;
3853
3943
  }
3854
- if ("sessionId" in payload && payload.sessionId) {
3855
- body.sessionId = payload.sessionId;
3944
+ if (request.filter?.protocols?.length) {
3945
+ params.protocols = [...request.filter.protocols];
3856
3946
  }
3857
- if ("agentUrl" in payload && payload.agentUrl) {
3858
- body.agentUrl = payload.agentUrl;
3947
+ if (request.filter?.adapter?.length) {
3948
+ params.adapters = [...request.filter.adapter];
3859
3949
  }
3860
- let cipherEnvelope = payload.cipherEnvelope ?? null;
3861
- if (payload.encryption) {
3862
- const sessionIdForEncryption = payload.encryption.sessionId ?? (typeof body.sessionId === "string" ? body.sessionId : void 0);
3863
- if (!sessionIdForEncryption) {
3864
- throw new Error(
3865
- "sessionId is required when using encrypted chat payloads"
3866
- );
3867
- }
3868
- if (!payload.encryption.recipients?.length) {
3869
- throw new Error("recipients are required for encrypted chat payloads");
3870
- }
3871
- cipherEnvelope = client.encryption.encryptCipherEnvelope({
3872
- ...payload.encryption,
3873
- sessionId: sessionIdForEncryption
3874
- });
3950
+ if (request.filter?.capabilities?.length) {
3951
+ params.capabilities = request.filter.capabilities.map(
3952
+ (value) => typeof value === "number" ? value.toString(10) : value
3953
+ );
3875
3954
  }
3876
- if (cipherEnvelope) {
3877
- body.cipherEnvelope = toJsonObject(cipherEnvelope);
3955
+ if (request.filter?.type) {
3956
+ params.type = request.filter.type;
3878
3957
  }
3879
- const raw = await client.requestJson("/chat/message", {
3958
+ return params;
3959
+ }
3960
+ function convertSearchResultToVectorResponse(result) {
3961
+ const hits = result.hits.map((agent) => ({
3962
+ agent,
3963
+ score: 0,
3964
+ highlights: {}
3965
+ }));
3966
+ const total = result.total;
3967
+ const limit = result.limit;
3968
+ const page = result.page;
3969
+ const totalVisible = page * limit;
3970
+ const limited = total > totalVisible || page > 1;
3971
+ return {
3972
+ hits,
3973
+ total,
3974
+ took: 0,
3975
+ totalAvailable: total,
3976
+ visible: hits.length,
3977
+ limited,
3978
+ credits_used: 0
3979
+ };
3980
+ }
3981
+ async function search(client, params = {}) {
3982
+ const query = buildSearchQuery(params);
3983
+ const raw = await client.requestJson(`/search${query}`, {
3984
+ method: "GET"
3985
+ });
3986
+ return client.parseWithSchema(raw, searchResponseSchema, "search response");
3987
+ }
3988
+ async function delegate(client, request) {
3989
+ const raw = await client.requestJson("/delegate", {
3880
3990
  method: "POST",
3881
- body,
3991
+ body: request,
3882
3992
  headers: { "content-type": "application/json" }
3883
3993
  });
3884
3994
  return client.parseWithSchema(
3885
3995
  raw,
3886
- sendMessageResponseSchema,
3887
- "chat message response"
3996
+ delegationPlanResponseSchema,
3997
+ "delegate response"
3888
3998
  );
3889
3999
  }
3890
- async function endSession(client, sessionId) {
3891
- await client.request(`/chat/session/${encodeURIComponent(sessionId)}`, {
3892
- method: "DELETE"
4000
+ async function stats(client) {
4001
+ const raw = await client.requestJson("/stats", { method: "GET" });
4002
+ return client.parseWithSchema(raw, statsResponseSchema, "stats response");
4003
+ }
4004
+ async function registries(client) {
4005
+ const raw = await client.requestJson("/registries", {
4006
+ method: "GET"
3893
4007
  });
4008
+ return client.parseWithSchema(
4009
+ raw,
4010
+ registriesResponseSchema,
4011
+ "registries response"
4012
+ );
3894
4013
  }
3895
-
3896
- // ../../src/services/registry-broker/client/verification.ts
3897
- async function getVerificationStatus(client, uaid) {
4014
+ async function getAdditionalRegistries(client) {
3898
4015
  const raw = await client.requestJson(
3899
- `/verification/status/${encodeURIComponent(uaid)}`,
3900
- { method: "GET" }
4016
+ "/register/additional-registries",
4017
+ {
4018
+ method: "GET"
4019
+ }
3901
4020
  );
3902
4021
  return client.parseWithSchema(
3903
4022
  raw,
3904
- verificationStatusResponseSchema,
3905
- "verification status response"
4023
+ additionalRegistryCatalogResponseSchema,
4024
+ "additional registry catalog response"
3906
4025
  );
3907
4026
  }
3908
- async function createVerificationChallenge(client, uaid) {
3909
- const raw = await client.requestJson("/verification/challenge", {
3910
- method: "POST",
3911
- headers: { "content-type": "application/json" },
3912
- body: { uaid }
4027
+ async function popularSearches(client) {
4028
+ const raw = await client.requestJson("/popular", {
4029
+ method: "GET"
3913
4030
  });
3914
4031
  return client.parseWithSchema(
3915
4032
  raw,
3916
- verificationChallengeResponseSchema,
3917
- "verification challenge response"
4033
+ popularResponseSchema,
4034
+ "popular searches response"
3918
4035
  );
3919
4036
  }
3920
- async function getVerificationChallenge(client, challengeId) {
3921
- const raw = await client.requestJson(
3922
- `/verification/challenge/${encodeURIComponent(challengeId)}`,
3923
- { method: "GET" }
3924
- );
4037
+ async function listProtocols(client) {
4038
+ const raw = await client.requestJson("/protocols", {
4039
+ method: "GET"
4040
+ });
3925
4041
  return client.parseWithSchema(
3926
4042
  raw,
3927
- verificationChallengeDetailsResponseSchema,
3928
- "verification challenge details response"
4043
+ protocolsResponseSchema,
4044
+ "protocols response"
3929
4045
  );
3930
4046
  }
3931
- async function verifyVerificationChallenge(client, params) {
3932
- const raw = await client.requestJson("/verification/verify", {
4047
+ async function detectProtocol(client, message) {
4048
+ const raw = await client.requestJson("/detect-protocol", {
3933
4049
  method: "POST",
3934
- headers: { "content-type": "application/json" },
3935
- body: {
3936
- challengeId: params.challengeId,
3937
- method: params.method ?? "moltbook-post"
3938
- }
4050
+ body: { message },
4051
+ headers: { "content-type": "application/json" }
3939
4052
  });
3940
4053
  return client.parseWithSchema(
3941
4054
  raw,
3942
- verificationVerifyResponseSchema,
3943
- "verification verify response"
3944
- );
3945
- }
3946
- async function getVerificationOwnership(client, uaid) {
3947
- const raw = await client.requestJson(
3948
- `/verification/ownership/${encodeURIComponent(uaid)}`,
3949
- { method: "GET" }
3950
- );
3951
- return client.parseWithSchema(
3952
- raw,
3953
- verificationOwnershipResponseSchema,
3954
- "verification ownership response"
4055
+ detectProtocolResponseSchema,
4056
+ "detect protocol response"
3955
4057
  );
3956
4058
  }
3957
- async function verifySenderOwnership(client, uaid) {
4059
+ async function registrySearchByNamespace(client, registry, query) {
4060
+ const params = new URLSearchParams();
4061
+ if (query) {
4062
+ params.set("q", query);
4063
+ }
4064
+ const suffix = params.size > 0 ? `?${params.toString()}` : "";
3958
4065
  const raw = await client.requestJson(
3959
- "/verification/verify-sender",
4066
+ `/registries/${encodeURIComponent(registry)}/search${suffix}`,
3960
4067
  {
3961
- method: "POST",
3962
- headers: { "content-type": "application/json" },
3963
- body: { uaid }
4068
+ method: "GET"
3964
4069
  }
3965
4070
  );
3966
4071
  return client.parseWithSchema(
3967
4072
  raw,
3968
- verificationVerifySenderResponseSchema,
3969
- "verification sender response"
4073
+ registrySearchByNamespaceSchema,
4074
+ "registry search response"
3970
4075
  );
3971
4076
  }
3972
- async function verifyUaidDnsTxt(client, payload) {
3973
- const raw = await client.requestJson("/verification/dns/verify", {
3974
- method: "POST",
3975
- headers: { "content-type": "application/json" },
3976
- body: {
3977
- uaid: payload.uaid,
3978
- ...payload.persist !== void 0 ? { persist: payload.persist } : {}
4077
+ async function vectorSearch(client, request) {
4078
+ try {
4079
+ const raw = await client.requestJson("/search", {
4080
+ method: "POST",
4081
+ body: request,
4082
+ headers: { "content-type": "application/json" }
4083
+ });
4084
+ return client.parseWithSchema(
4085
+ raw,
4086
+ vectorSearchResponseSchema,
4087
+ "vector search response"
4088
+ );
4089
+ } catch (error) {
4090
+ if (error instanceof RegistryBrokerError && error.status === 501) {
4091
+ const fallback = await search(
4092
+ client,
4093
+ buildVectorFallbackSearchParams(request)
4094
+ );
4095
+ return convertSearchResultToVectorResponse(fallback);
3979
4096
  }
4097
+ throw error;
4098
+ }
4099
+ }
4100
+ async function searchStatus(client) {
4101
+ const raw = await client.requestJson("/search/status", {
4102
+ method: "GET"
3980
4103
  });
3981
4104
  return client.parseWithSchema(
3982
4105
  raw,
3983
- verificationDnsStatusResponseSchema,
3984
- "verification dns verify response"
4106
+ searchStatusResponseSchema,
4107
+ "search status response"
3985
4108
  );
3986
4109
  }
3987
- async function getVerificationDnsStatus(client, uaid, query) {
3988
- const params = new URLSearchParams();
3989
- if (query?.refresh !== void 0) {
3990
- params.set("refresh", String(query.refresh));
3991
- }
3992
- if (query?.persist !== void 0) {
3993
- params.set("persist", String(query.persist));
3994
- }
3995
- const queryString = params.toString();
3996
- const path2 = `/verification/dns/status/${encodeURIComponent(uaid)}${queryString ? `?${queryString}` : ""}`;
3997
- const raw = await client.requestJson(path2, {
4110
+ async function websocketStats(client) {
4111
+ const raw = await client.requestJson("/websocket/stats", {
3998
4112
  method: "GET"
3999
4113
  });
4000
4114
  return client.parseWithSchema(
4001
4115
  raw,
4002
- verificationDnsStatusResponseSchema,
4003
- "verification dns status response"
4116
+ websocketStatsResponseSchema,
4117
+ "websocket stats response"
4004
4118
  );
4005
4119
  }
4006
- async function getRegisterStatus(client, uaid) {
4007
- const raw = await client.requestJson(
4008
- `/register/status/${encodeURIComponent(uaid)}`,
4009
- { method: "GET" }
4010
- );
4120
+ async function metricsSummary(client) {
4121
+ const raw = await client.requestJson("/metrics", {
4122
+ method: "GET"
4123
+ });
4011
4124
  return client.parseWithSchema(
4012
4125
  raw,
4013
- registerStatusResponseSchema,
4014
- "register status response"
4126
+ metricsSummaryResponseSchema,
4127
+ "metrics summary response"
4015
4128
  );
4016
4129
  }
4017
- async function registerOwnedMoltbookAgent(client, uaid, request) {
4018
- const raw = await client.requestJson(
4019
- `/register/${encodeURIComponent(uaid)}`,
4020
- {
4021
- method: "PUT",
4022
- headers: { "content-type": "application/json" },
4023
- body: {
4024
- registered: request.registered ?? true,
4025
- ...request.name ? { name: request.name } : {},
4026
- ...request.description ? { description: request.description } : {},
4027
- ...request.endpoint ? { endpoint: request.endpoint } : {},
4028
- ...request.metadata ? { metadata: request.metadata } : {}
4029
- }
4030
- }
4031
- );
4130
+ async function facets(client, adapter) {
4131
+ const params = new URLSearchParams();
4132
+ if (adapter) {
4133
+ params.set("adapter", adapter);
4134
+ }
4135
+ const suffix = params.size > 0 ? `?${params.toString()}` : "";
4136
+ const raw = await client.requestJson(`/search/facets${suffix}`, {
4137
+ method: "GET"
4138
+ });
4032
4139
  return client.parseWithSchema(
4033
4140
  raw,
4034
- moltbookOwnerRegistrationUpdateResponseSchema,
4035
- "moltbook owner registration update response"
4141
+ searchFacetsResponseSchema,
4142
+ "search facets response"
4036
4143
  );
4037
4144
  }
4038
4145
 
@@ -4047,6 +4154,28 @@ async function skillsConfig(client) {
4047
4154
  "skill registry config response"
4048
4155
  );
4049
4156
  }
4157
+ async function getSkillStatus(client, params) {
4158
+ const normalizedName = params.name.trim();
4159
+ if (!normalizedName) {
4160
+ throw new Error("name is required");
4161
+ }
4162
+ const query = new URLSearchParams();
4163
+ query.set("name", normalizedName);
4164
+ if (params.version?.trim()) {
4165
+ query.set("version", params.version.trim());
4166
+ }
4167
+ const raw = await client.requestJson(
4168
+ `/skills/status?${query.toString()}`,
4169
+ {
4170
+ method: "GET"
4171
+ }
4172
+ );
4173
+ return client.parseWithSchema(
4174
+ raw,
4175
+ skillStatusResponseSchema,
4176
+ "skill status response"
4177
+ );
4178
+ }
4050
4179
  async function listSkills(client, params = {}) {
4051
4180
  const query = new URLSearchParams();
4052
4181
  if (params.name) {
@@ -4562,10 +4691,6 @@ async function verifySkillDomainProof(client, payload) {
4562
4691
  }
4563
4692
 
4564
4693
  // ../../src/services/registry-broker/client/base-client.ts
4565
- var import_buffer4 = require("buffer");
4566
- var import_crypto2 = require("crypto");
4567
- var import_secp256k12 = require("@noble/curves/secp256k1.js");
4568
- var import_zod3 = require("zod");
4569
4694
  var RegistryBrokerClient = class _RegistryBrokerClient {
4570
4695
  constructor(options = {}) {
4571
4696
  this.encryptionBootstrapPromise = null;
@@ -4682,11 +4807,11 @@ var RegistryBrokerClient = class _RegistryBrokerClient {
4682
4807
  }
4683
4808
  await this.encryptionBootstrapPromise;
4684
4809
  }
4685
- buildUrl(path2) {
4686
- const normalisedPath = path2.startsWith("/") ? path2 : `/${path2}`;
4810
+ buildUrl(path) {
4811
+ const normalisedPath = path.startsWith("/") ? path : `/${path}`;
4687
4812
  return `${this.baseUrl}${normalisedPath}`;
4688
4813
  }
4689
- async request(path2, config) {
4814
+ async request(path, config) {
4690
4815
  const headers = new Headers();
4691
4816
  Object.entries(this.defaultHeaders).forEach(([key, value]) => {
4692
4817
  headers.set(key, value);
@@ -4712,7 +4837,7 @@ var RegistryBrokerClient = class _RegistryBrokerClient {
4712
4837
  headers.set("content-type", "application/json");
4713
4838
  }
4714
4839
  }
4715
- const response = await this.fetchImpl(this.buildUrl(path2), init);
4840
+ const response = await this.fetchImpl(this.buildUrl(path), init);
4716
4841
  if (response.ok) {
4717
4842
  return response;
4718
4843
  }
@@ -4723,8 +4848,8 @@ var RegistryBrokerClient = class _RegistryBrokerClient {
4723
4848
  body: errorBody
4724
4849
  });
4725
4850
  }
4726
- async requestJson(path2, config) {
4727
- const response = await this.request(path2, config);
4851
+ async requestJson(path, config) {
4852
+ const response = await this.request(path, config);
4728
4853
  const contentType = response.headers?.get("content-type") ?? "";
4729
4854
  if (!JSON_CONTENT_TYPE.test(contentType)) {
4730
4855
  const body = await response.text();
@@ -4903,6 +5028,9 @@ var RegistryBrokerClient = class _RegistryBrokerClient {
4903
5028
  async skillsConfig() {
4904
5029
  return skillsConfig(this);
4905
5030
  }
5031
+ async getSkillStatus(params) {
5032
+ return getSkillStatus(this, params);
5033
+ }
4906
5034
  async listSkills(options) {
4907
5035
  return listSkills(this, options);
4908
5036
  }
@@ -5294,12 +5422,12 @@ var RegistryBrokerClient = class _RegistryBrokerClient {
5294
5422
  }
5295
5423
  return;
5296
5424
  }
5297
- await new Promise((resolve2, reject) => {
5425
+ await new Promise((resolve, reject) => {
5298
5426
  const timer = setTimeout(() => {
5299
5427
  if (signal) {
5300
5428
  signal.removeEventListener("abort", onAbort);
5301
5429
  }
5302
- resolve2();
5430
+ resolve();
5303
5431
  }, ms);
5304
5432
  const onAbort = () => {
5305
5433
  clearTimeout(timer);
@@ -5321,9 +5449,17 @@ var RegistryBrokerClient = class _RegistryBrokerClient {
5321
5449
  throw new Error(`${feature} is only available in Node.js environments`);
5322
5450
  }
5323
5451
  }
5452
+ getNodeCrypto(feature) {
5453
+ this.assertNodeRuntime(feature);
5454
+ const nodeCrypto = optionalImportSync("node:crypto") ?? optionalImportSync("crypto");
5455
+ if (!nodeCrypto) {
5456
+ throw new Error(`${feature} requires the Node.js crypto module`);
5457
+ }
5458
+ return nodeCrypto;
5459
+ }
5324
5460
  createEphemeralKeyPair() {
5325
- this.assertNodeRuntime("generateEphemeralKeyPair");
5326
- const privateKeyBytes = (0, import_crypto2.randomBytes)(32);
5461
+ const { randomBytes } = this.getNodeCrypto("generateEphemeralKeyPair");
5462
+ const privateKeyBytes = randomBytes(32);
5327
5463
  const publicKey = import_secp256k12.secp256k1.getPublicKey(privateKeyBytes, true);
5328
5464
  return {
5329
5465
  privateKey: import_buffer4.Buffer.from(privateKeyBytes).toString("hex"),
@@ -5331,17 +5467,19 @@ var RegistryBrokerClient = class _RegistryBrokerClient {
5331
5467
  };
5332
5468
  }
5333
5469
  deriveSharedSecret(options) {
5334
- this.assertNodeRuntime("deriveSharedSecret");
5470
+ const { createHash } = this.getNodeCrypto("deriveSharedSecret");
5335
5471
  const privateKey = this.hexToBuffer(options.privateKey);
5336
5472
  const peerPublicKey = this.hexToBuffer(options.peerPublicKey);
5337
5473
  const shared = import_secp256k12.secp256k1.getSharedSecret(privateKey, peerPublicKey, true);
5338
- return (0, import_crypto2.createHash)("sha256").update(import_buffer4.Buffer.from(shared)).digest();
5474
+ return createHash("sha256").update(import_buffer4.Buffer.from(shared)).digest();
5339
5475
  }
5340
5476
  buildCipherEnvelope(options) {
5341
- this.assertNodeRuntime("encryptCipherEnvelope");
5477
+ const { createCipheriv, randomBytes } = this.getNodeCrypto(
5478
+ "encryptCipherEnvelope"
5479
+ );
5342
5480
  const sharedSecret = this.normalizeSharedSecret(options.sharedSecret);
5343
- const iv = (0, import_crypto2.randomBytes)(12);
5344
- const cipher = (0, import_crypto2.createCipheriv)("aes-256-gcm", sharedSecret, iv);
5481
+ const iv = randomBytes(12);
5482
+ const cipher = createCipheriv("aes-256-gcm", sharedSecret, iv);
5345
5483
  const aadSource = options.associatedData ?? options.sessionId;
5346
5484
  const associatedDataEncoded = aadSource ? import_buffer4.Buffer.from(aadSource, "utf8").toString("base64") : void 0;
5347
5485
  if (aadSource) {
@@ -5369,13 +5507,13 @@ var RegistryBrokerClient = class _RegistryBrokerClient {
5369
5507
  };
5370
5508
  }
5371
5509
  openCipherEnvelope(options) {
5372
- this.assertNodeRuntime("decryptCipherEnvelope");
5510
+ const { createDecipheriv } = this.getNodeCrypto("decryptCipherEnvelope");
5373
5511
  const sharedSecret = this.normalizeSharedSecret(options.sharedSecret);
5374
5512
  const payload = import_buffer4.Buffer.from(options.envelope.ciphertext, "base64");
5375
5513
  const nonce = import_buffer4.Buffer.from(options.envelope.nonce, "base64");
5376
5514
  const ciphertext = payload.slice(0, payload.length - 16);
5377
5515
  const tag = payload.slice(payload.length - 16);
5378
- const decipher = (0, import_crypto2.createDecipheriv)("aes-256-gcm", sharedSecret, nonce);
5516
+ const decipher = createDecipheriv("aes-256-gcm", sharedSecret, nonce);
5379
5517
  if (options.envelope.associatedData) {
5380
5518
  decipher.setAAD(import_buffer4.Buffer.from(options.envelope.associatedData, "base64"));
5381
5519
  }