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