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