@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 +2032 -1894
- package/dist/index.d.cts +1262 -67
- package/dist/index.d.ts +1262 -67
- package/dist/index.js +2028 -1896
- package/package.json +3 -2
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/
|
|
61
|
-
var
|
|
62
|
-
var
|
|
63
|
-
var
|
|
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/
|
|
1645
|
-
var
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
if (!
|
|
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
|
-
|
|
1654
|
-
|
|
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 (
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
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
|
|
1668
|
-
if (
|
|
1669
|
-
|
|
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
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
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
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
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
|
-
|
|
1695
|
-
if (
|
|
1696
|
-
return
|
|
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
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
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
|
|
1817
|
+
return contexts[0];
|
|
1711
1818
|
}
|
|
1712
|
-
function
|
|
1713
|
-
|
|
1714
|
-
|
|
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
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
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/
|
|
1731
|
-
var
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
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
|
|
1848
|
+
return end === value.length ? value : value.slice(0, end);
|
|
1737
1849
|
};
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
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 (
|
|
1762
|
-
|
|
1857
|
+
if (value instanceof Date) {
|
|
1858
|
+
return value.toISOString();
|
|
1763
1859
|
}
|
|
1764
|
-
if (
|
|
1765
|
-
return
|
|
1860
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
1861
|
+
return value;
|
|
1766
1862
|
}
|
|
1767
|
-
|
|
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/
|
|
2117
|
-
var
|
|
2118
|
-
constructor(
|
|
2119
|
-
super(
|
|
2120
|
-
this.
|
|
2121
|
-
this.
|
|
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
|
-
|
|
2134
|
-
|
|
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
|
-
|
|
2152
|
-
|
|
2070
|
+
registerConversationContext(context) {
|
|
2071
|
+
this.client.registerConversationContextForEncryption(context);
|
|
2153
2072
|
}
|
|
2154
|
-
|
|
2155
|
-
|
|
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
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
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
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
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
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
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
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
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
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
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
|
|
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("/
|
|
2355
|
+
const raw = await client.requestJson("/chat/session", {
|
|
2287
2356
|
method: "POST",
|
|
2288
|
-
body
|
|
2357
|
+
body,
|
|
2289
2358
|
headers: { "content-type": "application/json" }
|
|
2290
2359
|
});
|
|
2291
2360
|
return client.parseWithSchema(
|
|
2292
2361
|
raw,
|
|
2293
|
-
|
|
2294
|
-
"
|
|
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
|
|
2298
|
-
|
|
2466
|
+
if (error instanceof EncryptionUnavailableError && preference !== "required") {
|
|
2467
|
+
return createPlaintextConversationHandle(
|
|
2299
2468
|
client,
|
|
2300
|
-
|
|
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
|
-
|
|
2308
|
-
const
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
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
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
}
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
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
|
-
|
|
2334
|
-
"
|
|
2532
|
+
chatHistoryCompactionResponseSchema,
|
|
2533
|
+
"chat history compaction response"
|
|
2335
2534
|
);
|
|
2336
2535
|
}
|
|
2337
|
-
async function
|
|
2338
|
-
|
|
2339
|
-
|
|
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
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
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
|
-
|
|
2371
|
-
"
|
|
2548
|
+
sessionEncryptionStatusResponseSchema,
|
|
2549
|
+
"session encryption status response"
|
|
2372
2550
|
);
|
|
2373
2551
|
}
|
|
2374
|
-
async function
|
|
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
|
-
|
|
2557
|
+
`/chat/session/${encodeURIComponent(sessionId)}/encryption-handshake`,
|
|
2377
2558
|
{
|
|
2378
|
-
method: "
|
|
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
|
-
|
|
2574
|
+
const response = client.parseWithSchema(
|
|
2382
2575
|
raw,
|
|
2383
|
-
|
|
2384
|
-
"
|
|
2576
|
+
encryptionHandshakeResponseSchema,
|
|
2577
|
+
"encryption handshake response"
|
|
2385
2578
|
);
|
|
2579
|
+
return response.handshake;
|
|
2386
2580
|
}
|
|
2387
|
-
async function
|
|
2388
|
-
const
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
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 (
|
|
2396
|
-
|
|
2588
|
+
if (payload.auth) {
|
|
2589
|
+
body.auth = serialiseAuthConfig(payload.auth);
|
|
2397
2590
|
}
|
|
2398
|
-
if (
|
|
2399
|
-
|
|
2591
|
+
if ("uaid" in payload) {
|
|
2592
|
+
body.uaid = payload.uaid;
|
|
2400
2593
|
}
|
|
2401
|
-
if (
|
|
2402
|
-
|
|
2594
|
+
if ("sessionId" in payload && payload.sessionId) {
|
|
2595
|
+
body.sessionId = payload.sessionId;
|
|
2403
2596
|
}
|
|
2404
|
-
if (
|
|
2405
|
-
|
|
2597
|
+
if ("agentUrl" in payload && payload.agentUrl) {
|
|
2598
|
+
body.agentUrl = payload.agentUrl;
|
|
2406
2599
|
}
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
{
|
|
2411
|
-
|
|
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
|
-
|
|
2417
|
-
"
|
|
2626
|
+
sendMessageResponseSchema,
|
|
2627
|
+
"chat message response"
|
|
2418
2628
|
);
|
|
2419
2629
|
}
|
|
2420
|
-
async function
|
|
2421
|
-
|
|
2422
|
-
"
|
|
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
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
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
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
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
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
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
|
|
2459
|
-
raw,
|
|
2460
|
-
adapterRegistrySubmissionStatusResponseSchema,
|
|
2461
|
-
"adapter registry submission status response"
|
|
2462
|
-
);
|
|
2681
|
+
}
|
|
2682
|
+
return false;
|
|
2463
2683
|
}
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
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
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
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
|
-
|
|
2489
|
-
|
|
2490
|
-
};
|
|
2491
|
-
return { createPaymentClient, decodePaymentResponse, createX402Signer };
|
|
2726
|
+
}
|
|
2727
|
+
}
|
|
2728
|
+
return dynamicImport(specifier);
|
|
2492
2729
|
}
|
|
2493
|
-
function
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
throw new Error("Calculated purchase amount must be positive");
|
|
2730
|
+
function optionalImportSync(specifier) {
|
|
2731
|
+
if (isBrowser && !isNodeRuntime()) {
|
|
2732
|
+
return null;
|
|
2497
2733
|
}
|
|
2498
|
-
|
|
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
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
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
|
-
|
|
2510
|
-
|
|
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
|
-
|
|
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
|
-
|
|
2520
|
-
"
|
|
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
|
-
|
|
2535
|
-
const
|
|
2536
|
-
if (
|
|
2537
|
-
|
|
2781
|
+
function normalizeAutoRegisterIdentity(config) {
|
|
2782
|
+
const identity = {};
|
|
2783
|
+
if (config.uaid) {
|
|
2784
|
+
identity.uaid = config.uaid;
|
|
2538
2785
|
}
|
|
2539
|
-
if (
|
|
2540
|
-
|
|
2786
|
+
if (config.ledgerAccountId) {
|
|
2787
|
+
identity.ledgerAccountId = config.ledgerAccountId;
|
|
2788
|
+
if (config.ledgerNetwork) {
|
|
2789
|
+
identity.ledgerNetwork = config.ledgerNetwork;
|
|
2790
|
+
}
|
|
2541
2791
|
}
|
|
2542
|
-
|
|
2543
|
-
|
|
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 (
|
|
2550
|
-
|
|
2795
|
+
if (identity.uaid || identity.ledgerAccountId || identity.email) {
|
|
2796
|
+
return identity;
|
|
2551
2797
|
}
|
|
2552
|
-
|
|
2553
|
-
|
|
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
|
-
|
|
2556
|
-
const
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
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
|
|
2572
|
-
const
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
|
|
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
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
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
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
|
|
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
|
|
2611
|
-
if (!
|
|
2612
|
-
return
|
|
2866
|
+
async function bootstrapEncryptionOptions(client, options) {
|
|
2867
|
+
if (!options?.autoRegister || options.autoRegister.enabled === false) {
|
|
2868
|
+
return null;
|
|
2613
2869
|
}
|
|
2614
|
-
return
|
|
2615
|
-
Math.ceil(shortfallCredits),
|
|
2616
|
-
MINIMUM_REGISTRATION_AUTO_TOP_UP_CREDITS
|
|
2617
|
-
);
|
|
2870
|
+
return autoRegisterEncryptionKey(client, options.autoRegister);
|
|
2618
2871
|
}
|
|
2619
|
-
async function
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
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
|
-
|
|
2625
|
-
|
|
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
|
-
|
|
2628
|
-
|
|
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
|
-
|
|
2631
|
-
const
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
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
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
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
|
-
|
|
2658
|
-
|
|
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
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
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
|
-
|
|
2672
|
-
"
|
|
2943
|
+
adaptersResponseSchema,
|
|
2944
|
+
"adapters response"
|
|
2673
2945
|
);
|
|
2674
2946
|
}
|
|
2675
|
-
async function
|
|
2676
|
-
const
|
|
2677
|
-
|
|
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
|
-
|
|
2705
|
-
"
|
|
2953
|
+
adapterDetailsResponseSchema,
|
|
2954
|
+
"adapter details response"
|
|
2706
2955
|
);
|
|
2707
2956
|
}
|
|
2708
|
-
async function
|
|
2957
|
+
async function adapterRegistryCategories(client) {
|
|
2709
2958
|
const raw = await client.requestJson(
|
|
2710
|
-
|
|
2959
|
+
"/adapters/registry/categories",
|
|
2711
2960
|
{
|
|
2712
|
-
method: "
|
|
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
|
-
|
|
2720
|
-
"
|
|
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
|
-
|
|
2756
|
-
|
|
2757
|
-
const
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
|
|
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
|
-
|
|
2784
|
-
|
|
2785
|
-
|
|
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
|
-
|
|
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
|
|
3019
|
+
async function submitAdapterRegistryAdapter(client, payload) {
|
|
2792
3020
|
const raw = await client.requestJson(
|
|
2793
|
-
|
|
3021
|
+
"/adapters/registry/adapters",
|
|
2794
3022
|
{
|
|
2795
|
-
method: "
|
|
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
|
-
|
|
2801
|
-
"
|
|
3030
|
+
adapterRegistrySubmitAdapterAcceptedResponseSchema,
|
|
3031
|
+
"adapter registry submit adapter response"
|
|
2802
3032
|
);
|
|
2803
3033
|
}
|
|
2804
|
-
async function
|
|
3034
|
+
async function adapterRegistrySubmissionStatus(client, submissionId) {
|
|
2805
3035
|
const raw = await client.requestJson(
|
|
2806
|
-
`/
|
|
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
|
-
|
|
2814
|
-
"
|
|
3043
|
+
adapterRegistrySubmissionStatusResponseSchema,
|
|
3044
|
+
"adapter registry submission status response"
|
|
2815
3045
|
);
|
|
2816
3046
|
}
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
|
|
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
|
-
|
|
2823
|
-
const
|
|
2824
|
-
|
|
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
|
-
|
|
2829
|
-
"
|
|
3102
|
+
creditPurchaseResponseSchema,
|
|
3103
|
+
"credit purchase response"
|
|
2830
3104
|
);
|
|
2831
3105
|
}
|
|
2832
|
-
|
|
2833
|
-
|
|
2834
|
-
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
|
|
2838
|
-
|
|
2839
|
-
|
|
2840
|
-
|
|
2841
|
-
|
|
2842
|
-
|
|
2843
|
-
|
|
2844
|
-
|
|
2845
|
-
|
|
2846
|
-
|
|
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 (
|
|
2870
|
-
|
|
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
|
-
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
|
|
2877
|
-
|
|
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 (
|
|
2888
|
-
|
|
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
|
-
|
|
2894
|
-
|
|
2895
|
-
|
|
2896
|
-
legacyName: alias
|
|
3149
|
+
...parsed,
|
|
3150
|
+
paymentResponseHeader: paymentHeader,
|
|
3151
|
+
paymentResponse: decodedPayment
|
|
2897
3152
|
};
|
|
2898
|
-
}
|
|
2899
|
-
|
|
2900
|
-
const
|
|
2901
|
-
const
|
|
2902
|
-
|
|
2903
|
-
|
|
2904
|
-
|
|
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
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
|
|
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/
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
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
|
-
|
|
2932
|
-
|
|
2933
|
-
cachedSdk = resolved;
|
|
2934
|
-
return resolved;
|
|
3203
|
+
if (creditsToPurchase <= 0) {
|
|
3204
|
+
throw new Error("creditsToPurchase must be positive");
|
|
2935
3205
|
}
|
|
2936
|
-
const
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
|
|
2940
|
-
|
|
2941
|
-
|
|
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
|
-
|
|
2944
|
-
|
|
2945
|
-
|
|
2946
|
-
|
|
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
|
-
|
|
2949
|
-
|
|
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 (!
|
|
2957
|
-
throw new Error("
|
|
3227
|
+
if (!details.privateKey || !details.privateKey.trim()) {
|
|
3228
|
+
throw new Error("autoTopUp.privateKey is required");
|
|
2958
3229
|
}
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
|
|
2962
|
-
|
|
2963
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
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
|
-
|
|
3031
|
-
|
|
3032
|
-
const
|
|
3033
|
-
|
|
3034
|
-
|
|
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
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
|
|
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
|
|
3052
|
-
const
|
|
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
|
-
|
|
3057
|
-
|
|
3058
|
-
|
|
3059
|
-
|
|
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
|
-
|
|
3065
|
-
"
|
|
3319
|
+
registerAgentResponseSchema,
|
|
3320
|
+
"update agent response"
|
|
3066
3321
|
);
|
|
3067
3322
|
}
|
|
3068
|
-
async function
|
|
3069
|
-
const
|
|
3070
|
-
|
|
3071
|
-
|
|
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
|
-
|
|
3081
|
-
|
|
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
|
-
|
|
3084
|
-
|
|
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
|
|
3087
|
-
|
|
3088
|
-
|
|
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
|
-
|
|
3097
|
-
|
|
3098
|
-
|
|
3099
|
-
|
|
3100
|
-
|
|
3101
|
-
|
|
3102
|
-
|
|
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
|
-
|
|
3148
|
-
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
|
|
3152
|
-
|
|
3153
|
-
|
|
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
|
-
|
|
3385
|
+
`Registration progress polling timed out after ${timeoutMs}ms`
|
|
3156
3386
|
);
|
|
3157
3387
|
}
|
|
3158
|
-
|
|
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
|
-
|
|
3171
|
-
|
|
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
|
-
|
|
3174
|
-
|
|
3175
|
-
|
|
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
|
|
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
|
-
`/
|
|
3406
|
+
`/uaids/connections/${encodeURIComponent(uaid)}/status`,
|
|
3212
3407
|
{
|
|
3213
3408
|
method: "GET"
|
|
3214
3409
|
}
|
|
3215
3410
|
);
|
|
3216
|
-
|
|
3411
|
+
return client.parseWithSchema(
|
|
3217
3412
|
raw,
|
|
3218
|
-
|
|
3219
|
-
"
|
|
3413
|
+
uaidConnectionStatusSchema,
|
|
3414
|
+
"UAID connection status"
|
|
3220
3415
|
);
|
|
3221
|
-
|
|
3222
|
-
|
|
3223
|
-
|
|
3224
|
-
|
|
3225
|
-
|
|
3226
|
-
|
|
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
|
-
|
|
3230
|
-
|
|
3231
|
-
|
|
3232
|
-
|
|
3233
|
-
|
|
3234
|
-
|
|
3235
|
-
|
|
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
|
-
|
|
3238
|
-
|
|
3239
|
-
|
|
3240
|
-
|
|
3241
|
-
|
|
3242
|
-
|
|
3243
|
-
|
|
3244
|
-
|
|
3245
|
-
|
|
3246
|
-
|
|
3247
|
-
|
|
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
|
|
3264
|
-
const
|
|
3265
|
-
|
|
3266
|
-
|
|
3267
|
-
|
|
3268
|
-
|
|
3269
|
-
|
|
3270
|
-
|
|
3271
|
-
|
|
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
|
|
3281
|
-
|
|
3282
|
-
|
|
3283
|
-
|
|
3284
|
-
|
|
3285
|
-
|
|
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
|
|
3476
|
+
});
|
|
3477
|
+
return client.parseWithSchema(
|
|
3478
|
+
raw,
|
|
3479
|
+
verificationVerifyResponseSchema,
|
|
3480
|
+
"verification verify response"
|
|
3481
|
+
);
|
|
3301
3482
|
}
|
|
3302
|
-
function
|
|
3303
|
-
const
|
|
3304
|
-
|
|
3305
|
-
|
|
3306
|
-
|
|
3307
|
-
|
|
3308
|
-
|
|
3309
|
-
|
|
3310
|
-
|
|
3311
|
-
|
|
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
|
-
|
|
3319
|
-
|
|
3320
|
-
|
|
3321
|
-
|
|
3322
|
-
|
|
3323
|
-
|
|
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
|
-
|
|
3423
|
-
|
|
3424
|
-
|
|
3425
|
-
|
|
3426
|
-
|
|
3427
|
-
|
|
3428
|
-
|
|
3429
|
-
|
|
3430
|
-
|
|
3431
|
-
|
|
3432
|
-
|
|
3433
|
-
|
|
3434
|
-
|
|
3435
|
-
|
|
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
|
-
|
|
3451
|
-
|
|
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
|
-
|
|
3461
|
-
|
|
3462
|
-
|
|
3463
|
-
|
|
3464
|
-
|
|
3465
|
-
|
|
3466
|
-
|
|
3467
|
-
|
|
3468
|
-
|
|
3469
|
-
|
|
3470
|
-
|
|
3471
|
-
|
|
3472
|
-
|
|
3473
|
-
|
|
3474
|
-
|
|
3475
|
-
|
|
3476
|
-
|
|
3477
|
-
|
|
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
|
-
|
|
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
|
-
|
|
3494
|
-
|
|
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
|
-
|
|
3540
|
-
|
|
3541
|
-
|
|
3542
|
-
|
|
3543
|
-
|
|
3544
|
-
|
|
3545
|
-
|
|
3546
|
-
|
|
3547
|
-
|
|
3548
|
-
|
|
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
|
-
|
|
3555
|
-
|
|
3556
|
-
|
|
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
|
-
|
|
3570
|
-
|
|
3571
|
-
|
|
3572
|
-
|
|
3573
|
-
|
|
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/
|
|
3578
|
-
|
|
3579
|
-
|
|
3580
|
-
|
|
3581
|
-
|
|
3582
|
-
|
|
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
|
-
|
|
3600
|
-
|
|
3674
|
+
const resolved = optionalImportSync("@hashgraph/sdk");
|
|
3675
|
+
if (resolved) {
|
|
3676
|
+
cachedSdk = resolved;
|
|
3677
|
+
return resolved;
|
|
3601
3678
|
}
|
|
3602
|
-
|
|
3603
|
-
|
|
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
|
-
|
|
3606
|
-
|
|
3686
|
+
const resolved = await optionalImport("@hashgraph/sdk");
|
|
3687
|
+
if (resolved) {
|
|
3688
|
+
cachedSdk = resolved;
|
|
3689
|
+
return resolved;
|
|
3607
3690
|
}
|
|
3608
|
-
|
|
3609
|
-
|
|
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 (
|
|
3612
|
-
|
|
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
|
|
3616
|
-
|
|
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
|
|
3627
|
-
|
|
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
|
|
3664
|
-
|
|
3665
|
-
|
|
3666
|
-
|
|
3667
|
-
|
|
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
|
-
|
|
3766
|
+
return result;
|
|
3710
3767
|
}
|
|
3711
|
-
|
|
3712
|
-
|
|
3713
|
-
|
|
3714
|
-
|
|
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
|
-
|
|
3718
|
-
|
|
3719
|
-
|
|
3720
|
-
|
|
3721
|
-
|
|
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
|
-
|
|
3739
|
-
|
|
3740
|
-
|
|
3741
|
-
|
|
3742
|
-
|
|
3743
|
-
|
|
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
|
-
|
|
3747
|
-
entry,
|
|
3748
|
-
plaintext: entry.content
|
|
3749
|
-
}));
|
|
3750
|
-
};
|
|
3787
|
+
}
|
|
3751
3788
|
return {
|
|
3752
|
-
|
|
3753
|
-
|
|
3754
|
-
|
|
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
|
|
3775
|
-
|
|
3776
|
-
|
|
3777
|
-
|
|
3778
|
-
|
|
3779
|
-
|
|
3780
|
-
body
|
|
3781
|
-
|
|
3782
|
-
|
|
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
|
-
|
|
3793
|
-
"
|
|
3807
|
+
ledgerChallengeResponseSchema,
|
|
3808
|
+
"ledger challenge response"
|
|
3794
3809
|
);
|
|
3795
3810
|
}
|
|
3796
|
-
async function
|
|
3797
|
-
|
|
3798
|
-
|
|
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
|
-
|
|
3801
|
-
|
|
3802
|
-
|
|
3803
|
-
|
|
3804
|
-
|
|
3805
|
-
|
|
3806
|
-
|
|
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
|
-
|
|
3809
|
-
"
|
|
3836
|
+
ledgerVerifyResponseSchema,
|
|
3837
|
+
"ledger verification response"
|
|
3810
3838
|
);
|
|
3839
|
+
client.setLedgerApiKey(result.key);
|
|
3840
|
+
return result;
|
|
3811
3841
|
}
|
|
3812
|
-
async function
|
|
3813
|
-
|
|
3814
|
-
|
|
3815
|
-
|
|
3816
|
-
|
|
3817
|
-
|
|
3818
|
-
|
|
3819
|
-
|
|
3820
|
-
|
|
3821
|
-
|
|
3822
|
-
|
|
3823
|
-
|
|
3824
|
-
|
|
3825
|
-
|
|
3826
|
-
|
|
3827
|
-
|
|
3828
|
-
|
|
3829
|
-
|
|
3830
|
-
|
|
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
|
|
3835
|
-
|
|
3836
|
-
|
|
3837
|
-
|
|
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
|
|
3923
|
+
return verification;
|
|
3840
3924
|
}
|
|
3841
|
-
|
|
3842
|
-
|
|
3843
|
-
|
|
3925
|
+
|
|
3926
|
+
// ../../src/services/registry-broker/client/search.ts
|
|
3927
|
+
function buildVectorFallbackSearchParams(request) {
|
|
3928
|
+
const params = {
|
|
3929
|
+
q: request.query
|
|
3844
3930
|
};
|
|
3845
|
-
|
|
3846
|
-
|
|
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 (
|
|
3849
|
-
|
|
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 (
|
|
3852
|
-
|
|
3941
|
+
if (request.filter?.registry) {
|
|
3942
|
+
params.registry = request.filter.registry;
|
|
3853
3943
|
}
|
|
3854
|
-
if (
|
|
3855
|
-
|
|
3944
|
+
if (request.filter?.protocols?.length) {
|
|
3945
|
+
params.protocols = [...request.filter.protocols];
|
|
3856
3946
|
}
|
|
3857
|
-
if (
|
|
3858
|
-
|
|
3947
|
+
if (request.filter?.adapter?.length) {
|
|
3948
|
+
params.adapters = [...request.filter.adapter];
|
|
3859
3949
|
}
|
|
3860
|
-
|
|
3861
|
-
|
|
3862
|
-
|
|
3863
|
-
|
|
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 (
|
|
3877
|
-
|
|
3955
|
+
if (request.filter?.type) {
|
|
3956
|
+
params.type = request.filter.type;
|
|
3878
3957
|
}
|
|
3879
|
-
|
|
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
|
-
|
|
3887
|
-
"
|
|
3996
|
+
delegationPlanResponseSchema,
|
|
3997
|
+
"delegate response"
|
|
3888
3998
|
);
|
|
3889
3999
|
}
|
|
3890
|
-
async function
|
|
3891
|
-
await client.
|
|
3892
|
-
|
|
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
|
-
|
|
3900
|
-
{
|
|
4016
|
+
"/register/additional-registries",
|
|
4017
|
+
{
|
|
4018
|
+
method: "GET"
|
|
4019
|
+
}
|
|
3901
4020
|
);
|
|
3902
4021
|
return client.parseWithSchema(
|
|
3903
4022
|
raw,
|
|
3904
|
-
|
|
3905
|
-
"
|
|
4023
|
+
additionalRegistryCatalogResponseSchema,
|
|
4024
|
+
"additional registry catalog response"
|
|
3906
4025
|
);
|
|
3907
4026
|
}
|
|
3908
|
-
async function
|
|
3909
|
-
const raw = await client.requestJson("/
|
|
3910
|
-
method: "
|
|
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
|
-
|
|
3917
|
-
"
|
|
4033
|
+
popularResponseSchema,
|
|
4034
|
+
"popular searches response"
|
|
3918
4035
|
);
|
|
3919
4036
|
}
|
|
3920
|
-
async function
|
|
3921
|
-
const raw = await client.requestJson(
|
|
3922
|
-
|
|
3923
|
-
|
|
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
|
-
|
|
3928
|
-
"
|
|
4043
|
+
protocolsResponseSchema,
|
|
4044
|
+
"protocols response"
|
|
3929
4045
|
);
|
|
3930
4046
|
}
|
|
3931
|
-
async function
|
|
3932
|
-
const raw = await client.requestJson("/
|
|
4047
|
+
async function detectProtocol(client, message) {
|
|
4048
|
+
const raw = await client.requestJson("/detect-protocol", {
|
|
3933
4049
|
method: "POST",
|
|
3934
|
-
|
|
3935
|
-
|
|
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
|
-
|
|
3943
|
-
"
|
|
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
|
|
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
|
-
|
|
4066
|
+
`/registries/${encodeURIComponent(registry)}/search${suffix}`,
|
|
3960
4067
|
{
|
|
3961
|
-
method: "
|
|
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
|
-
|
|
3969
|
-
"
|
|
4073
|
+
registrySearchByNamespaceSchema,
|
|
4074
|
+
"registry search response"
|
|
3970
4075
|
);
|
|
3971
4076
|
}
|
|
3972
|
-
async function
|
|
3973
|
-
|
|
3974
|
-
|
|
3975
|
-
|
|
3976
|
-
|
|
3977
|
-
|
|
3978
|
-
|
|
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
|
-
|
|
3984
|
-
"
|
|
4106
|
+
searchStatusResponseSchema,
|
|
4107
|
+
"search status response"
|
|
3985
4108
|
);
|
|
3986
4109
|
}
|
|
3987
|
-
async function
|
|
3988
|
-
const
|
|
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
|
-
|
|
4003
|
-
"
|
|
4116
|
+
websocketStatsResponseSchema,
|
|
4117
|
+
"websocket stats response"
|
|
4004
4118
|
);
|
|
4005
4119
|
}
|
|
4006
|
-
async function
|
|
4007
|
-
const raw = await client.requestJson(
|
|
4008
|
-
|
|
4009
|
-
|
|
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
|
-
|
|
4014
|
-
"
|
|
4126
|
+
metricsSummaryResponseSchema,
|
|
4127
|
+
"metrics summary response"
|
|
4015
4128
|
);
|
|
4016
4129
|
}
|
|
4017
|
-
async function
|
|
4018
|
-
const
|
|
4019
|
-
|
|
4020
|
-
|
|
4021
|
-
|
|
4022
|
-
|
|
4023
|
-
|
|
4024
|
-
|
|
4025
|
-
|
|
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
|
-
|
|
4035
|
-
"
|
|
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(
|
|
4686
|
-
const normalisedPath =
|
|
4810
|
+
buildUrl(path) {
|
|
4811
|
+
const normalisedPath = path.startsWith("/") ? path : `/${path}`;
|
|
4687
4812
|
return `${this.baseUrl}${normalisedPath}`;
|
|
4688
4813
|
}
|
|
4689
|
-
async request(
|
|
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(
|
|
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(
|
|
4727
|
-
const response = await this.request(
|
|
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((
|
|
5425
|
+
await new Promise((resolve, reject) => {
|
|
5298
5426
|
const timer = setTimeout(() => {
|
|
5299
5427
|
if (signal) {
|
|
5300
5428
|
signal.removeEventListener("abort", onAbort);
|
|
5301
5429
|
}
|
|
5302
|
-
|
|
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.
|
|
5326
|
-
const privateKeyBytes =
|
|
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.
|
|
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
|
|
5474
|
+
return createHash("sha256").update(import_buffer4.Buffer.from(shared)).digest();
|
|
5339
5475
|
}
|
|
5340
5476
|
buildCipherEnvelope(options) {
|
|
5341
|
-
this.
|
|
5477
|
+
const { createCipheriv, randomBytes } = this.getNodeCrypto(
|
|
5478
|
+
"encryptCipherEnvelope"
|
|
5479
|
+
);
|
|
5342
5480
|
const sharedSecret = this.normalizeSharedSecret(options.sharedSecret);
|
|
5343
|
-
const iv =
|
|
5344
|
-
const cipher =
|
|
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.
|
|
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 =
|
|
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
|
}
|