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