@hsuite/smart-engines-sdk 3.0.2 → 3.1.0
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/CHANGELOG.md +28 -0
- package/README.md +43 -12
- package/dist/index.d.ts +348 -34
- package/dist/index.js +642 -20
- package/dist/index.js.map +1 -1
- package/dist/nestjs/index.d.ts +292 -33
- package/dist/nestjs/index.js +598 -20
- package/dist/nestjs/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1014,6 +1014,7 @@ zod.z.object({
|
|
|
1014
1014
|
// src/discovery/index.ts
|
|
1015
1015
|
var discovery_exports = {};
|
|
1016
1016
|
__export(discovery_exports, {
|
|
1017
|
+
ClusterDiscoveryClient: () => ClusterDiscoveryClient,
|
|
1017
1018
|
MIRROR_NODE_URLS: () => MIRROR_NODE_URLS,
|
|
1018
1019
|
MirrorNodeClient: () => MirrorNodeClient,
|
|
1019
1020
|
MirrorNodeError: () => MirrorNodeError,
|
|
@@ -1386,6 +1387,185 @@ function normalizeRegistryEntry(raw) {
|
|
|
1386
1387
|
return null;
|
|
1387
1388
|
}
|
|
1388
1389
|
|
|
1390
|
+
// src/discovery/cluster-discovery.ts
|
|
1391
|
+
var ClusterDiscoveryClient = class {
|
|
1392
|
+
bootstrap;
|
|
1393
|
+
cacheTtlMs;
|
|
1394
|
+
fetchTimeoutMs;
|
|
1395
|
+
allowInsecure;
|
|
1396
|
+
trustAnchorClient;
|
|
1397
|
+
cache = null;
|
|
1398
|
+
constructor(config) {
|
|
1399
|
+
if (!config.bootstrap || config.bootstrap.length === 0) {
|
|
1400
|
+
throw new Error("ClusterDiscoveryClient: bootstrap must list at least one seed URL");
|
|
1401
|
+
}
|
|
1402
|
+
if (!config.allowInsecure) {
|
|
1403
|
+
for (const seed of config.bootstrap) {
|
|
1404
|
+
if (!seed.startsWith("https://")) {
|
|
1405
|
+
throw new Error(
|
|
1406
|
+
`ClusterDiscoveryClient: bootstrap seed "${seed}" is not HTTPS. Set allowInsecure=true for local development only.`
|
|
1407
|
+
);
|
|
1408
|
+
}
|
|
1409
|
+
}
|
|
1410
|
+
}
|
|
1411
|
+
this.bootstrap = config.bootstrap;
|
|
1412
|
+
this.cacheTtlMs = config.cacheTtlMs ?? 6e4;
|
|
1413
|
+
this.fetchTimeoutMs = config.fetchTimeoutMs ?? 5e3;
|
|
1414
|
+
this.allowInsecure = config.allowInsecure ?? false;
|
|
1415
|
+
this.trustAnchorClient = config.trustAnchor ? new ValidatorDiscoveryClient(config.trustAnchor) : null;
|
|
1416
|
+
}
|
|
1417
|
+
/**
|
|
1418
|
+
* Fetch the active-cluster set, with caching.
|
|
1419
|
+
*
|
|
1420
|
+
* Tries each bootstrap seed in order until one returns HTTP 200 with a
|
|
1421
|
+
* parseable cluster list. If all seeds fail, throws — callers can
|
|
1422
|
+
* handle by falling back to a previously-cached value if they want,
|
|
1423
|
+
* or by initializing with multiple seeds.
|
|
1424
|
+
*/
|
|
1425
|
+
async getClusters(forceRefresh = false) {
|
|
1426
|
+
if (!forceRefresh && this.cache && this.isCacheValid()) {
|
|
1427
|
+
return this.cache.clusters;
|
|
1428
|
+
}
|
|
1429
|
+
const fetched = await this.fetchFromFirstAvailableSeed();
|
|
1430
|
+
const verified = this.trustAnchorClient ? await this.verifyAgainstTrustAnchor(fetched) : fetched;
|
|
1431
|
+
this.cache = { clusters: verified, lastUpdated: Date.now() };
|
|
1432
|
+
return verified;
|
|
1433
|
+
}
|
|
1434
|
+
/**
|
|
1435
|
+
* Random pick over the active-cluster set. Returns `null` when no
|
|
1436
|
+
* cluster passes verification (empty registry / all-rejected anchor).
|
|
1437
|
+
*
|
|
1438
|
+
* Uses `crypto.getRandomValues` when available (browsers, Deno, modern
|
|
1439
|
+
* Node) for cryptographic-strength randomness; `Math.random` is a
|
|
1440
|
+
* fallback for older runtimes where `globalThis.crypto` is undefined.
|
|
1441
|
+
* Discovery isn't cryptographically sensitive — load distribution is
|
|
1442
|
+
* the goal here.
|
|
1443
|
+
*/
|
|
1444
|
+
async getRandomCluster(forceRefresh = false) {
|
|
1445
|
+
const clusters = await this.getClusters(forceRefresh);
|
|
1446
|
+
if (clusters.length === 0) return null;
|
|
1447
|
+
return clusters[this.pickRandomIndex(clusters.length)];
|
|
1448
|
+
}
|
|
1449
|
+
/**
|
|
1450
|
+
* Convenience wrapper returning just the gateway URL of a random
|
|
1451
|
+
* active cluster. The single most-used SDK entry point — most
|
|
1452
|
+
* downstream callers want `new SmartEngineClient({ baseUrl: ... })`
|
|
1453
|
+
* and don't care about the rest of the metadata.
|
|
1454
|
+
*/
|
|
1455
|
+
async getRandomGatewayUrl(forceRefresh = false) {
|
|
1456
|
+
const cluster = await this.getRandomCluster(forceRefresh);
|
|
1457
|
+
return cluster?.endpoints.gatewayUrl ?? null;
|
|
1458
|
+
}
|
|
1459
|
+
/** Per-clusterId lookup, useful for "stick the SDK to cluster X" flows. */
|
|
1460
|
+
async getClusterById(clusterId, forceRefresh = false) {
|
|
1461
|
+
const clusters = await this.getClusters(forceRefresh);
|
|
1462
|
+
return clusters.find((c) => c.clusterId === clusterId) ?? null;
|
|
1463
|
+
}
|
|
1464
|
+
clearCache() {
|
|
1465
|
+
this.cache = null;
|
|
1466
|
+
}
|
|
1467
|
+
isCacheValid() {
|
|
1468
|
+
if (!this.cache) return false;
|
|
1469
|
+
return Date.now() - this.cache.lastUpdated < this.cacheTtlMs;
|
|
1470
|
+
}
|
|
1471
|
+
async fetchFromFirstAvailableSeed() {
|
|
1472
|
+
const errors = [];
|
|
1473
|
+
for (const seed of this.bootstrap) {
|
|
1474
|
+
try {
|
|
1475
|
+
return await this.fetchClustersFromSeed(seed);
|
|
1476
|
+
} catch (err) {
|
|
1477
|
+
errors.push(`${seed}: ${err.message}`);
|
|
1478
|
+
}
|
|
1479
|
+
}
|
|
1480
|
+
throw new Error(
|
|
1481
|
+
`ClusterDiscoveryClient: no bootstrap seed reachable. Attempts:
|
|
1482
|
+
${errors.join("\n ")}`
|
|
1483
|
+
);
|
|
1484
|
+
}
|
|
1485
|
+
async fetchClustersFromSeed(seed) {
|
|
1486
|
+
const url = `${seed.replace(/\/$/, "")}/api/v3/discovery/clusters`;
|
|
1487
|
+
const ctrl = new AbortController();
|
|
1488
|
+
const timer = setTimeout(() => ctrl.abort(), this.fetchTimeoutMs);
|
|
1489
|
+
try {
|
|
1490
|
+
const res = await fetch(url, { signal: ctrl.signal });
|
|
1491
|
+
if (!res.ok) {
|
|
1492
|
+
throw new Error(`HTTP ${res.status}`);
|
|
1493
|
+
}
|
|
1494
|
+
const body = await res.json();
|
|
1495
|
+
if (!Array.isArray(body.clusters)) {
|
|
1496
|
+
throw new Error("response missing clusters[]");
|
|
1497
|
+
}
|
|
1498
|
+
return body.clusters.map((c) => this.normalizeClusterEntry(c)).filter((c) => c !== null);
|
|
1499
|
+
} finally {
|
|
1500
|
+
clearTimeout(timer);
|
|
1501
|
+
}
|
|
1502
|
+
}
|
|
1503
|
+
normalizeClusterEntry(raw) {
|
|
1504
|
+
if (typeof raw.clusterId !== "string" || !raw.clusterId) return null;
|
|
1505
|
+
if (!raw.endpoints || typeof raw.endpoints !== "object") return null;
|
|
1506
|
+
const ep = raw.endpoints;
|
|
1507
|
+
if (typeof ep.gatewayUrl !== "string" || !ep.gatewayUrl) return null;
|
|
1508
|
+
if (!this.allowInsecure && !ep.gatewayUrl.startsWith("https://")) {
|
|
1509
|
+
return null;
|
|
1510
|
+
}
|
|
1511
|
+
const nodeIds = Array.isArray(raw.nodeIds) ? raw.nodeIds.filter((n) => typeof n === "string") : [];
|
|
1512
|
+
return {
|
|
1513
|
+
clusterId: raw.clusterId,
|
|
1514
|
+
endpoints: {
|
|
1515
|
+
clusterId: raw.clusterId,
|
|
1516
|
+
gatewayUrl: ep.gatewayUrl,
|
|
1517
|
+
harborUrl: typeof ep.harborUrl === "string" ? ep.harborUrl : void 0,
|
|
1518
|
+
natsUrl: typeof ep.natsUrl === "string" ? ep.natsUrl : void 0,
|
|
1519
|
+
publicIp: typeof ep.publicIp === "string" ? ep.publicIp : void 0,
|
|
1520
|
+
region: typeof ep.region === "string" ? ep.region : void 0
|
|
1521
|
+
},
|
|
1522
|
+
nodeIds
|
|
1523
|
+
};
|
|
1524
|
+
}
|
|
1525
|
+
/**
|
|
1526
|
+
* Cross-check the HTTP-fetched cluster set against the HCS validator
|
|
1527
|
+
* registry. Clusters whose nodeIds are not on-chain are dropped.
|
|
1528
|
+
*
|
|
1529
|
+
* Two failure modes are deliberately silent here:
|
|
1530
|
+
* - the HCS read itself throws → original list is returned
|
|
1531
|
+
* un-verified. Trust-anchor is advisory; a network partition
|
|
1532
|
+
* between SDK and Hedera mirror shouldn't strand the SDK.
|
|
1533
|
+
* - the HCS read returns empty (mirror node lag, wrong topicId)
|
|
1534
|
+
* → original list is returned. Better to keep working off
|
|
1535
|
+
* possibly-stale-but-real data than reject every cluster.
|
|
1536
|
+
*
|
|
1537
|
+
* Both behaviors are why this is called "trust *anchor*", not
|
|
1538
|
+
* "trust gate". Crypto-strong gating is a follow-up.
|
|
1539
|
+
*/
|
|
1540
|
+
async verifyAgainstTrustAnchor(clusters) {
|
|
1541
|
+
if (!this.trustAnchorClient || clusters.length === 0) return clusters;
|
|
1542
|
+
let onChainNodeIds;
|
|
1543
|
+
try {
|
|
1544
|
+
const validators = await this.trustAnchorClient.getValidators();
|
|
1545
|
+
if (validators.length === 0) return clusters;
|
|
1546
|
+
onChainNodeIds = new Set(validators.map((v) => v.nodeId));
|
|
1547
|
+
} catch {
|
|
1548
|
+
return clusters;
|
|
1549
|
+
}
|
|
1550
|
+
return clusters.filter((c) => {
|
|
1551
|
+
if (c.nodeIds.length === 0) {
|
|
1552
|
+
return false;
|
|
1553
|
+
}
|
|
1554
|
+
return c.nodeIds.some((id) => onChainNodeIds.has(id));
|
|
1555
|
+
});
|
|
1556
|
+
}
|
|
1557
|
+
pickRandomIndex(n) {
|
|
1558
|
+
if (n <= 1) return 0;
|
|
1559
|
+
const g = globalThis.crypto;
|
|
1560
|
+
if (g?.getRandomValues) {
|
|
1561
|
+
const buf = new Uint32Array(1);
|
|
1562
|
+
g.getRandomValues(buf);
|
|
1563
|
+
return buf[0] % n;
|
|
1564
|
+
}
|
|
1565
|
+
return Math.floor(Math.random() * n);
|
|
1566
|
+
}
|
|
1567
|
+
};
|
|
1568
|
+
|
|
1389
1569
|
// src/auth/index.ts
|
|
1390
1570
|
var auth_exports = {};
|
|
1391
1571
|
__export(auth_exports, {
|
|
@@ -1725,14 +1905,14 @@ function createHttpClient(config) {
|
|
|
1725
1905
|
throw new SdkHttpError(`Network error: ${err.message}`, 0, error);
|
|
1726
1906
|
}
|
|
1727
1907
|
}
|
|
1728
|
-
async function upload(path, file, filename, metadata) {
|
|
1908
|
+
async function upload(path, file, filename, metadata, fieldName = "file") {
|
|
1729
1909
|
const url = `${config.baseUrl}${path}`;
|
|
1730
1910
|
const controller = new AbortController();
|
|
1731
1911
|
const timeoutId = setTimeout(() => controller.abort(), timeout * 2);
|
|
1732
1912
|
try {
|
|
1733
1913
|
const formData = new FormData();
|
|
1734
1914
|
const blob = file instanceof Blob ? file : new Blob([new Uint8Array(file)]);
|
|
1735
|
-
formData.append(
|
|
1915
|
+
formData.append(fieldName, blob, filename);
|
|
1736
1916
|
if (metadata) {
|
|
1737
1917
|
for (const [key, value] of Object.entries(metadata)) {
|
|
1738
1918
|
formData.append(key, value);
|
|
@@ -1776,7 +1956,7 @@ function createHttpClient(config) {
|
|
|
1776
1956
|
get: (path) => request("GET", path),
|
|
1777
1957
|
put: (path, body) => request("PUT", path, body),
|
|
1778
1958
|
delete: (path) => request("DELETE", path),
|
|
1779
|
-
upload,
|
|
1959
|
+
upload: ((path, file, filename, metadata, fieldName) => upload(path, file, filename, metadata, fieldName)),
|
|
1780
1960
|
setAuthToken
|
|
1781
1961
|
};
|
|
1782
1962
|
return client;
|
|
@@ -1784,6 +1964,17 @@ function createHttpClient(config) {
|
|
|
1784
1964
|
function encodePathParam(param) {
|
|
1785
1965
|
return encodeURIComponent(param).replace(/%2F/gi, "");
|
|
1786
1966
|
}
|
|
1967
|
+
function isRuleRejected(err) {
|
|
1968
|
+
if (!(err instanceof SdkHttpError)) return false;
|
|
1969
|
+
if (err.statusCode !== 403) return false;
|
|
1970
|
+
const d = err.details;
|
|
1971
|
+
if (d === null || typeof d !== "object") return false;
|
|
1972
|
+
const obj = d;
|
|
1973
|
+
if (obj.error !== "rule_rejected") return false;
|
|
1974
|
+
if (typeof obj.reason !== "string") return false;
|
|
1975
|
+
if (!Array.isArray(obj.ruleAtoms)) return false;
|
|
1976
|
+
return obj.ruleAtoms.every((a) => typeof a === "string");
|
|
1977
|
+
}
|
|
1787
1978
|
|
|
1788
1979
|
// src/subscription/index.ts
|
|
1789
1980
|
var subscription_exports = {};
|
|
@@ -2207,6 +2398,167 @@ var SnapshotsClient = class {
|
|
|
2207
2398
|
}
|
|
2208
2399
|
};
|
|
2209
2400
|
|
|
2401
|
+
// src/historical-balance/historical-balance-client.ts
|
|
2402
|
+
var DEFAULT_TIMEOUT_MS = 3e4;
|
|
2403
|
+
var ENDPOINT_PATH = "/api/v3/historical-balance/query";
|
|
2404
|
+
var HistoricalBalanceClientError = class extends Error {
|
|
2405
|
+
constructor(message, statusCode, details) {
|
|
2406
|
+
super(message);
|
|
2407
|
+
this.statusCode = statusCode;
|
|
2408
|
+
this.details = details;
|
|
2409
|
+
this.name = "HistoricalBalanceClientError";
|
|
2410
|
+
}
|
|
2411
|
+
statusCode;
|
|
2412
|
+
details;
|
|
2413
|
+
};
|
|
2414
|
+
var HistoricalBalanceClient = class _HistoricalBalanceClient {
|
|
2415
|
+
// Standalone-mode fields (set when the client builds its own fetch).
|
|
2416
|
+
baseUrl;
|
|
2417
|
+
authToken;
|
|
2418
|
+
apiKey;
|
|
2419
|
+
timeoutMs;
|
|
2420
|
+
fetchImpl;
|
|
2421
|
+
// Sub-client-mode field (set when wired via SmartEngineClient).
|
|
2422
|
+
http;
|
|
2423
|
+
constructor(config) {
|
|
2424
|
+
if ("http" in config) {
|
|
2425
|
+
this.http = config.http;
|
|
2426
|
+
this.timeoutMs = DEFAULT_TIMEOUT_MS;
|
|
2427
|
+
return;
|
|
2428
|
+
}
|
|
2429
|
+
if (!config.baseUrl) {
|
|
2430
|
+
throw new HistoricalBalanceClientError(
|
|
2431
|
+
"HistoricalBalanceClient: baseUrl is required for standalone construction",
|
|
2432
|
+
400
|
|
2433
|
+
);
|
|
2434
|
+
}
|
|
2435
|
+
this.baseUrl = config.baseUrl.replace(/\/+$/, "");
|
|
2436
|
+
this.authToken = config.authToken;
|
|
2437
|
+
this.apiKey = config.apiKey;
|
|
2438
|
+
this.timeoutMs = config.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
2439
|
+
this.fetchImpl = config.fetchImpl;
|
|
2440
|
+
}
|
|
2441
|
+
/**
|
|
2442
|
+
* Factory used by `SmartEngineClient` to wire this sub-client onto the
|
|
2443
|
+
* parent's shared `HttpClient` (which already carries auth + baseUrl + a
|
|
2444
|
+
* `/api/v3` prefix). Routes through `/historical-balance/query` since the
|
|
2445
|
+
* parent's HttpClient is rooted at `/api/v3`.
|
|
2446
|
+
*/
|
|
2447
|
+
static fromHttp(http) {
|
|
2448
|
+
return new _HistoricalBalanceClient({ http });
|
|
2449
|
+
}
|
|
2450
|
+
/**
|
|
2451
|
+
* Query a point-in-time balance.
|
|
2452
|
+
*
|
|
2453
|
+
* The validator returns the on-chain bigint as a base-10 decimal string.
|
|
2454
|
+
* Callers needing arithmetic precision should wrap the result:
|
|
2455
|
+
*
|
|
2456
|
+
* ```ts
|
|
2457
|
+
* const { balance } = await client.historicalBalance.getBalance({ ... });
|
|
2458
|
+
* const value = BigInt(balance);
|
|
2459
|
+
* ```
|
|
2460
|
+
*/
|
|
2461
|
+
async getBalance(params) {
|
|
2462
|
+
this.validateParams(params);
|
|
2463
|
+
if (this.http) {
|
|
2464
|
+
return this.http.post("/historical-balance/query", params);
|
|
2465
|
+
}
|
|
2466
|
+
return this.standaloneFetch(params);
|
|
2467
|
+
}
|
|
2468
|
+
validateParams(params) {
|
|
2469
|
+
if (!params || typeof params !== "object") {
|
|
2470
|
+
throw new HistoricalBalanceClientError(
|
|
2471
|
+
"HistoricalBalanceClient.getBalance: params object is required",
|
|
2472
|
+
400
|
|
2473
|
+
);
|
|
2474
|
+
}
|
|
2475
|
+
const { chain, entityId, account, atTimestamp } = params;
|
|
2476
|
+
if (chain !== "hedera" && chain !== "xrpl" && chain !== "polkadot") {
|
|
2477
|
+
throw new HistoricalBalanceClientError(
|
|
2478
|
+
`HistoricalBalanceClient.getBalance: unsupported chain "${String(chain)}" (expected hedera | xrpl | polkadot)`,
|
|
2479
|
+
400
|
|
2480
|
+
);
|
|
2481
|
+
}
|
|
2482
|
+
if (typeof entityId !== "string" || entityId.length === 0) {
|
|
2483
|
+
throw new HistoricalBalanceClientError(
|
|
2484
|
+
"HistoricalBalanceClient.getBalance: entityId must be a non-empty string",
|
|
2485
|
+
400
|
|
2486
|
+
);
|
|
2487
|
+
}
|
|
2488
|
+
if (typeof account !== "string" || account.length === 0) {
|
|
2489
|
+
throw new HistoricalBalanceClientError(
|
|
2490
|
+
"HistoricalBalanceClient.getBalance: account must be a non-empty string",
|
|
2491
|
+
400
|
|
2492
|
+
);
|
|
2493
|
+
}
|
|
2494
|
+
if (typeof atTimestamp !== "number" || !Number.isInteger(atTimestamp) || atTimestamp <= 0) {
|
|
2495
|
+
throw new HistoricalBalanceClientError(
|
|
2496
|
+
"HistoricalBalanceClient.getBalance: atTimestamp must be a positive integer (unix seconds)",
|
|
2497
|
+
400
|
|
2498
|
+
);
|
|
2499
|
+
}
|
|
2500
|
+
}
|
|
2501
|
+
async standaloneFetch(params) {
|
|
2502
|
+
const url = `${this.baseUrl}${ENDPOINT_PATH}`;
|
|
2503
|
+
const headers = {
|
|
2504
|
+
"Content-Type": "application/json",
|
|
2505
|
+
Accept: "application/json"
|
|
2506
|
+
};
|
|
2507
|
+
if (this.authToken) headers.Authorization = `Bearer ${this.authToken}`;
|
|
2508
|
+
if (this.apiKey) headers["X-API-Key"] = this.apiKey;
|
|
2509
|
+
const fetchFn = this.fetchImpl ?? (typeof fetch !== "undefined" ? fetch : void 0);
|
|
2510
|
+
if (!fetchFn) {
|
|
2511
|
+
throw new HistoricalBalanceClientError(
|
|
2512
|
+
"HistoricalBalanceClient: no fetch implementation available (provide fetchImpl)",
|
|
2513
|
+
500
|
|
2514
|
+
);
|
|
2515
|
+
}
|
|
2516
|
+
const controller = new AbortController();
|
|
2517
|
+
const timer = setTimeout(() => controller.abort(), this.timeoutMs);
|
|
2518
|
+
let response;
|
|
2519
|
+
try {
|
|
2520
|
+
response = await fetchFn(url, {
|
|
2521
|
+
method: "POST",
|
|
2522
|
+
headers,
|
|
2523
|
+
body: JSON.stringify(params),
|
|
2524
|
+
signal: controller.signal
|
|
2525
|
+
});
|
|
2526
|
+
} catch (err) {
|
|
2527
|
+
clearTimeout(timer);
|
|
2528
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
2529
|
+
throw new HistoricalBalanceClientError(
|
|
2530
|
+
`HistoricalBalanceClient: transport error: ${message}`,
|
|
2531
|
+
0,
|
|
2532
|
+
err
|
|
2533
|
+
);
|
|
2534
|
+
}
|
|
2535
|
+
clearTimeout(timer);
|
|
2536
|
+
let body;
|
|
2537
|
+
const text = await response.text();
|
|
2538
|
+
if (text.length > 0) {
|
|
2539
|
+
try {
|
|
2540
|
+
body = JSON.parse(text);
|
|
2541
|
+
} catch (err) {
|
|
2542
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
2543
|
+
throw new HistoricalBalanceClientError(
|
|
2544
|
+
`HistoricalBalanceClient: non-JSON response (status=${response.status}): ${message}`,
|
|
2545
|
+
response.status,
|
|
2546
|
+
{ raw: text }
|
|
2547
|
+
);
|
|
2548
|
+
}
|
|
2549
|
+
}
|
|
2550
|
+
if (!response.ok) {
|
|
2551
|
+
const detail = body && typeof body === "object" && "message" in body ? String(body.message) : `HTTP ${response.status}`;
|
|
2552
|
+
throw new HistoricalBalanceClientError(
|
|
2553
|
+
`HistoricalBalanceClient: ${detail}`,
|
|
2554
|
+
response.status,
|
|
2555
|
+
body
|
|
2556
|
+
);
|
|
2557
|
+
}
|
|
2558
|
+
return body;
|
|
2559
|
+
}
|
|
2560
|
+
};
|
|
2561
|
+
|
|
2210
2562
|
// src/settlement/index.ts
|
|
2211
2563
|
var settlement_exports = {};
|
|
2212
2564
|
__export(settlement_exports, {
|
|
@@ -2245,6 +2597,75 @@ var SettlementClient = class {
|
|
|
2245
2597
|
}
|
|
2246
2598
|
};
|
|
2247
2599
|
|
|
2600
|
+
// src/governance/index.ts
|
|
2601
|
+
var governance_exports = {};
|
|
2602
|
+
__export(governance_exports, {
|
|
2603
|
+
GovernanceClient: () => GovernanceClient
|
|
2604
|
+
});
|
|
2605
|
+
|
|
2606
|
+
// src/governance/governance-client.ts
|
|
2607
|
+
var GovernanceClient = class {
|
|
2608
|
+
constructor(http) {
|
|
2609
|
+
this.http = http;
|
|
2610
|
+
}
|
|
2611
|
+
http;
|
|
2612
|
+
/**
|
|
2613
|
+
* Dry-run a governance proposal/vote/etc. against `GovernanceMolecule.validate(...)`.
|
|
2614
|
+
*
|
|
2615
|
+
* Returns whatever `ValidationResult` the molecule produced. A `false`
|
|
2616
|
+
* `isValid` is **not** an error — it is a successful "this proposal is
|
|
2617
|
+
* invalid" outcome and is surfaced via the normal return value.
|
|
2618
|
+
*
|
|
2619
|
+
* HTTP errors (400 malformed body, 500 unexpected) bubble up as
|
|
2620
|
+
* `SdkHttpError` via the shared `HttpClient` layer.
|
|
2621
|
+
*/
|
|
2622
|
+
async simulate(params) {
|
|
2623
|
+
return this.http.post("/governance/simulate", params);
|
|
2624
|
+
}
|
|
2625
|
+
};
|
|
2626
|
+
|
|
2627
|
+
// src/personhood/index.ts
|
|
2628
|
+
var personhood_exports = {};
|
|
2629
|
+
__export(personhood_exports, {
|
|
2630
|
+
PERSONHOOD_VERIFIER_NOT_CONFIGURED: () => PERSONHOOD_VERIFIER_NOT_CONFIGURED,
|
|
2631
|
+
PersonhoodClient: () => PersonhoodClient,
|
|
2632
|
+
isPersonhoodVerifierNotConfigured: () => isPersonhoodVerifierNotConfigured
|
|
2633
|
+
});
|
|
2634
|
+
|
|
2635
|
+
// src/personhood/personhood-client.ts
|
|
2636
|
+
var PERSONHOOD_VERIFIER_NOT_CONFIGURED = "personhood_verifier_not_configured";
|
|
2637
|
+
var PersonhoodClient = class {
|
|
2638
|
+
constructor(http) {
|
|
2639
|
+
this.http = http;
|
|
2640
|
+
}
|
|
2641
|
+
http;
|
|
2642
|
+
/**
|
|
2643
|
+
* Verify a personhood proof for `candidate`.
|
|
2644
|
+
*
|
|
2645
|
+
* Returns the issued cert on accept, `null` on clean rejection. All
|
|
2646
|
+
* other failure modes (validation, transport, 5xx) propagate as
|
|
2647
|
+
* `SdkHttpError`.
|
|
2648
|
+
*/
|
|
2649
|
+
async verify(params) {
|
|
2650
|
+
const result = await this.http.post(
|
|
2651
|
+
"/personhood/verify",
|
|
2652
|
+
{
|
|
2653
|
+
candidate: params.candidate,
|
|
2654
|
+
proof: params.proof
|
|
2655
|
+
}
|
|
2656
|
+
);
|
|
2657
|
+
if (result === void 0) return null;
|
|
2658
|
+
return result;
|
|
2659
|
+
}
|
|
2660
|
+
};
|
|
2661
|
+
function isPersonhoodVerifierNotConfigured(err) {
|
|
2662
|
+
if (!(err instanceof SdkHttpError)) return false;
|
|
2663
|
+
if (err.statusCode !== 503) return false;
|
|
2664
|
+
const d = err.details;
|
|
2665
|
+
if (d === null || typeof d !== "object") return false;
|
|
2666
|
+
return d.error === PERSONHOOD_VERIFIER_NOT_CONFIGURED;
|
|
2667
|
+
}
|
|
2668
|
+
|
|
2248
2669
|
// src/client.ts
|
|
2249
2670
|
var SmartEngineClient = class _SmartEngineClient {
|
|
2250
2671
|
baseUrl;
|
|
@@ -2265,8 +2686,14 @@ var SmartEngineClient = class _SmartEngineClient {
|
|
|
2265
2686
|
transactions;
|
|
2266
2687
|
/** Token holder snapshot generation and retrieval */
|
|
2267
2688
|
snapshots;
|
|
2689
|
+
/** Historical balance archive reads (chain-native bigint, returned as decimal string) */
|
|
2690
|
+
historicalBalance;
|
|
2268
2691
|
/** Cross-chain settlement operations */
|
|
2269
2692
|
settlement;
|
|
2693
|
+
/** Governance proposal dry-run (simulate-only) */
|
|
2694
|
+
governance;
|
|
2695
|
+
/** Personhood verification (HPP one-human-one-member) */
|
|
2696
|
+
personhood;
|
|
2270
2697
|
constructor(config) {
|
|
2271
2698
|
this.allowInsecure = config.allowInsecure ?? false;
|
|
2272
2699
|
this.baseUrl = validateClientUrl(config.baseUrl, this.allowInsecure);
|
|
@@ -2287,7 +2714,10 @@ var SmartEngineClient = class _SmartEngineClient {
|
|
|
2287
2714
|
this.ipfs = new IPFSClient(this.http);
|
|
2288
2715
|
this.transactions = new TransactionsClient(this.txHttp);
|
|
2289
2716
|
this.snapshots = new SnapshotsClient(this.http);
|
|
2717
|
+
this.historicalBalance = HistoricalBalanceClient.fromHttp(this.http);
|
|
2290
2718
|
this.settlement = new SettlementClient(this.http);
|
|
2719
|
+
this.governance = new GovernanceClient(this.http);
|
|
2720
|
+
this.personhood = new PersonhoodClient(this.http);
|
|
2291
2721
|
}
|
|
2292
2722
|
/**
|
|
2293
2723
|
* Connect to the smart-engines network with auto-discovery and authentication
|
|
@@ -2332,6 +2762,67 @@ var SmartEngineClient = class _SmartEngineClient {
|
|
|
2332
2762
|
});
|
|
2333
2763
|
return { client, validator, session };
|
|
2334
2764
|
}
|
|
2765
|
+
/**
|
|
2766
|
+
* Connect to the smart-engines network via the **service-registry**
|
|
2767
|
+
* (PR-1 of the cluster-discovery arc). Preferred over
|
|
2768
|
+
* {@link connectToNetwork} once the validator pods in the target network
|
|
2769
|
+
* have published their cluster endpoints — the SDK auto-balances across
|
|
2770
|
+
* the active cluster set and rides permissionless cluster join/leave
|
|
2771
|
+
* without code edits.
|
|
2772
|
+
*
|
|
2773
|
+
* Fallback ladder (per `docs/ops/HANDOFF-service-registry-distribution-layer.md` §6):
|
|
2774
|
+
* 1. HTTP fetch `/api/v3/discovery/clusters` from each bootstrap seed.
|
|
2775
|
+
* 2. (Optional) HCS trust-anchor membership cross-check.
|
|
2776
|
+
* 3. Random-pick over the verified set.
|
|
2777
|
+
*
|
|
2778
|
+
* @example
|
|
2779
|
+
* ```ts
|
|
2780
|
+
* const { client, cluster, session } = await SmartEngineClient.connectToCluster({
|
|
2781
|
+
* bootstrap: ['https://sn1.testnet.hsuite.network', 'https://sn2.testnet.hsuite.network'],
|
|
2782
|
+
* chain: 'xrpl',
|
|
2783
|
+
* address: '...',
|
|
2784
|
+
* publicKey: '...',
|
|
2785
|
+
* signFn: async (challenge) => sign(challenge),
|
|
2786
|
+
* });
|
|
2787
|
+
* ```
|
|
2788
|
+
*/
|
|
2789
|
+
static async connectToCluster(config) {
|
|
2790
|
+
const allowInsecure = config.allowInsecure ?? false;
|
|
2791
|
+
const discovery = new ClusterDiscoveryClient({
|
|
2792
|
+
bootstrap: config.bootstrap,
|
|
2793
|
+
allowInsecure,
|
|
2794
|
+
trustAnchor: config.trustAnchor ? {
|
|
2795
|
+
network: config.trustAnchor.network,
|
|
2796
|
+
registryTopicId: config.trustAnchor.registryTopicId,
|
|
2797
|
+
mirrorNodeUrl: config.trustAnchor.mirrorNodeUrl,
|
|
2798
|
+
allowInsecure
|
|
2799
|
+
} : void 0
|
|
2800
|
+
});
|
|
2801
|
+
const cluster = await discovery.getRandomCluster();
|
|
2802
|
+
if (!cluster) {
|
|
2803
|
+
throw new SmartEngineError2(
|
|
2804
|
+
"No active clusters available via bootstrap seeds. Check bootstrap URLs and network reachability.",
|
|
2805
|
+
503
|
|
2806
|
+
);
|
|
2807
|
+
}
|
|
2808
|
+
const gatewayUrl = cluster.endpoints.gatewayUrl;
|
|
2809
|
+
validateClientUrl(gatewayUrl, allowInsecure);
|
|
2810
|
+
const auth = new ValidatorAuthClient({ security: { allowInsecure } });
|
|
2811
|
+
const session = await auth.authenticateWithSigner(
|
|
2812
|
+
gatewayUrl,
|
|
2813
|
+
config.chain,
|
|
2814
|
+
config.address,
|
|
2815
|
+
config.publicKey,
|
|
2816
|
+
config.signFn,
|
|
2817
|
+
config.metadata
|
|
2818
|
+
);
|
|
2819
|
+
const client = new _SmartEngineClient({
|
|
2820
|
+
baseUrl: gatewayUrl,
|
|
2821
|
+
authToken: session.token,
|
|
2822
|
+
allowInsecure
|
|
2823
|
+
});
|
|
2824
|
+
return { client, cluster, session };
|
|
2825
|
+
}
|
|
2335
2826
|
/** Get the current validator URL */
|
|
2336
2827
|
getBaseUrl() {
|
|
2337
2828
|
return this.baseUrl;
|
|
@@ -3619,49 +4110,101 @@ var DeploymentClient = class {
|
|
|
3619
4110
|
}
|
|
3620
4111
|
http;
|
|
3621
4112
|
/**
|
|
3622
|
-
*
|
|
4113
|
+
* Step 1 — allocate appId + receive ephemeral push credentials for
|
|
4114
|
+
* the cluster's per-tenant Harbor project.
|
|
4115
|
+
*
|
|
4116
|
+
* Each app gets its own Harbor project (`hsuite-customers-<appId>`)
|
|
4117
|
+
* isolated by Harbor's RBAC. The push robot returned in
|
|
4118
|
+
* `registry.{username, password}` is scoped to that project only —
|
|
4119
|
+
* it cannot read or write any other tenant's images.
|
|
4120
|
+
*
|
|
4121
|
+
* **Single-use secret discipline:** `registry.password` is returned
|
|
4122
|
+
* exactly once and is NOT persisted server-side. Store it locally
|
|
4123
|
+
* for the `docker push` and discard. To rotate, call `init` again
|
|
4124
|
+
* (issues a new robot under the same project).
|
|
4125
|
+
*
|
|
4126
|
+
* Use the credentials to `docker login` + `docker push`, then call
|
|
4127
|
+
* {@link deploy} with the pushed image tag.
|
|
3623
4128
|
*/
|
|
3624
|
-
async
|
|
3625
|
-
return this.http.post("/api/deployment/apps", request);
|
|
4129
|
+
async init(request) {
|
|
4130
|
+
return this.http.post("/api/deployment/apps/init", request);
|
|
3626
4131
|
}
|
|
3627
4132
|
/**
|
|
3628
|
-
*
|
|
4133
|
+
* Step 3 (optional) — upload the SPA tarball.
|
|
4134
|
+
*
|
|
4135
|
+
* The tarball is content-addressed (SHA-256) and mounted read-only
|
|
4136
|
+
* into the customer's pod alongside the backend container. Returns
|
|
4137
|
+
* the hash + size so the caller can verify the upload.
|
|
4138
|
+
*/
|
|
4139
|
+
async uploadFrontend(appId, bundle, filename = "bundle.tar.gz") {
|
|
4140
|
+
return this.http.upload(
|
|
4141
|
+
`/api/deployment/apps/${encodeURIComponent(appId)}/frontend`,
|
|
4142
|
+
bundle,
|
|
4143
|
+
filename,
|
|
4144
|
+
void 0,
|
|
4145
|
+
"bundle"
|
|
4146
|
+
);
|
|
4147
|
+
}
|
|
4148
|
+
/**
|
|
4149
|
+
* Step 4 — reconcile the runtime to k8s.
|
|
4150
|
+
*
|
|
4151
|
+
* Returns immediately with `status: 'deploying'`. Poll {@link status}
|
|
4152
|
+
* until `runtime.runtimeState === 'RUNNING'` for the URL to be live.
|
|
4153
|
+
*/
|
|
4154
|
+
async deploy(appId, request) {
|
|
4155
|
+
return this.http.post(`/api/deployment/apps/${encodeURIComponent(appId)}/deploy`, request);
|
|
4156
|
+
}
|
|
4157
|
+
/**
|
|
4158
|
+
* Roll back to a previously-deployed image tag (must exist in
|
|
4159
|
+
* `runtime.deploymentHistory[]`).
|
|
4160
|
+
*/
|
|
4161
|
+
async rollback(appId, request) {
|
|
4162
|
+
return this.http.post(`/api/deployment/apps/${encodeURIComponent(appId)}/rollback`, request);
|
|
4163
|
+
}
|
|
4164
|
+
/**
|
|
4165
|
+
* Live combined lifecycle + runtime status of an app.
|
|
4166
|
+
*/
|
|
4167
|
+
async status(appId) {
|
|
4168
|
+
return this.http.get(`/api/deployment/apps/${encodeURIComponent(appId)}/status`);
|
|
4169
|
+
}
|
|
4170
|
+
/**
|
|
4171
|
+
* List all deployed apps for the authenticated developer.
|
|
3629
4172
|
*/
|
|
3630
4173
|
async list() {
|
|
3631
4174
|
return this.http.get("/api/deployment/apps");
|
|
3632
4175
|
}
|
|
3633
4176
|
/**
|
|
3634
|
-
* Get app details
|
|
4177
|
+
* Get app details.
|
|
3635
4178
|
*/
|
|
3636
4179
|
async get(appId) {
|
|
3637
4180
|
return this.http.get(`/api/deployment/apps/${encodeURIComponent(appId)}`);
|
|
3638
4181
|
}
|
|
3639
4182
|
/**
|
|
3640
|
-
* Update app configuration
|
|
4183
|
+
* Update app configuration. Runtime effect lands in PR-H.
|
|
3641
4184
|
*/
|
|
3642
4185
|
async update(appId, updates) {
|
|
3643
4186
|
return this.http.put(`/api/deployment/apps/${encodeURIComponent(appId)}`, updates);
|
|
3644
4187
|
}
|
|
3645
4188
|
/**
|
|
3646
|
-
* Delete an app
|
|
4189
|
+
* Delete an app. Runtime effect (namespace teardown) lands in PR-H.
|
|
3647
4190
|
*/
|
|
3648
4191
|
async delete(appId) {
|
|
3649
4192
|
return this.http.delete(`/api/deployment/apps/${encodeURIComponent(appId)}`);
|
|
3650
4193
|
}
|
|
3651
4194
|
/**
|
|
3652
|
-
* Suspend an app
|
|
4195
|
+
* Suspend an app. Runtime effect (scale to zero) lands in PR-H.
|
|
3653
4196
|
*/
|
|
3654
4197
|
async suspend(appId) {
|
|
3655
4198
|
return this.http.post(`/api/deployment/apps/${encodeURIComponent(appId)}/suspend`, {});
|
|
3656
4199
|
}
|
|
3657
4200
|
/**
|
|
3658
|
-
* Resume a suspended app
|
|
4201
|
+
* Resume a suspended app. Runtime effect (scale back up) lands in PR-H.
|
|
3659
4202
|
*/
|
|
3660
4203
|
async resume(appId) {
|
|
3661
4204
|
return this.http.post(`/api/deployment/apps/${encodeURIComponent(appId)}/resume`, {});
|
|
3662
4205
|
}
|
|
3663
4206
|
/**
|
|
3664
|
-
* Get deployment statistics
|
|
4207
|
+
* Get deployment statistics.
|
|
3665
4208
|
*/
|
|
3666
4209
|
async getStats() {
|
|
3667
4210
|
return this.http.get("/api/deployment/stats");
|
|
@@ -3791,6 +4334,78 @@ var AgentsClient = class {
|
|
|
3791
4334
|
}
|
|
3792
4335
|
};
|
|
3793
4336
|
|
|
4337
|
+
// src/baas/customer-session/index.ts
|
|
4338
|
+
var CustomerSessionClient = class {
|
|
4339
|
+
constructor(baseUrl, timeoutMs = 3e4) {
|
|
4340
|
+
this.baseUrl = baseUrl;
|
|
4341
|
+
this.timeoutMs = timeoutMs;
|
|
4342
|
+
}
|
|
4343
|
+
baseUrl;
|
|
4344
|
+
timeoutMs;
|
|
4345
|
+
/**
|
|
4346
|
+
* Step 1: ask the host to issue a fresh challenge for the customer to sign.
|
|
4347
|
+
*/
|
|
4348
|
+
async challenge(input) {
|
|
4349
|
+
return this.fetch("POST", "/api/customer-session/challenge", input);
|
|
4350
|
+
}
|
|
4351
|
+
/**
|
|
4352
|
+
* Step 2: submit the customer's signed challenge. On success returns a
|
|
4353
|
+
* short-lived bearer JWT scoped to {appId, chain, address}.
|
|
4354
|
+
*/
|
|
4355
|
+
async verify(req) {
|
|
4356
|
+
return this.fetch("POST", "/api/customer-session/verify", req);
|
|
4357
|
+
}
|
|
4358
|
+
/**
|
|
4359
|
+
* Validate a customer bearer + return the decoded session info. Used by
|
|
4360
|
+
* smart-app backends to authorise incoming customer requests.
|
|
4361
|
+
*/
|
|
4362
|
+
async validate(bearer) {
|
|
4363
|
+
return this.fetch("GET", "/api/customer-session/validate", void 0, bearer);
|
|
4364
|
+
}
|
|
4365
|
+
/**
|
|
4366
|
+
* Revoke a customer session. Idempotent.
|
|
4367
|
+
*/
|
|
4368
|
+
async end(bearer) {
|
|
4369
|
+
return this.fetch(
|
|
4370
|
+
"POST",
|
|
4371
|
+
"/api/customer-session/end",
|
|
4372
|
+
void 0,
|
|
4373
|
+
bearer
|
|
4374
|
+
);
|
|
4375
|
+
}
|
|
4376
|
+
async fetch(method, path, body, bearer) {
|
|
4377
|
+
const url = `${this.baseUrl}${path}`;
|
|
4378
|
+
const controller = new AbortController();
|
|
4379
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeoutMs);
|
|
4380
|
+
try {
|
|
4381
|
+
const headers = { "Content-Type": "application/json" };
|
|
4382
|
+
if (bearer) headers["Authorization"] = `Bearer ${bearer}`;
|
|
4383
|
+
const init = { method, headers, signal: controller.signal };
|
|
4384
|
+
if (body !== void 0) init.body = JSON.stringify(body);
|
|
4385
|
+
const response = await fetch(url, init);
|
|
4386
|
+
clearTimeout(timeoutId);
|
|
4387
|
+
if (!response.ok) {
|
|
4388
|
+
const errBody = await response.json().catch(() => ({}));
|
|
4389
|
+
const err = new Error(
|
|
4390
|
+
errBody.message ?? `customer-session ${path} failed: ${response.status} ${response.statusText}`
|
|
4391
|
+
);
|
|
4392
|
+
err.status = response.status;
|
|
4393
|
+
throw err;
|
|
4394
|
+
}
|
|
4395
|
+
const text = await response.text();
|
|
4396
|
+
if (!text) return void 0;
|
|
4397
|
+
return JSON.parse(text);
|
|
4398
|
+
} catch (error) {
|
|
4399
|
+
clearTimeout(timeoutId);
|
|
4400
|
+
const e = error;
|
|
4401
|
+
if (e.name === "AbortError") {
|
|
4402
|
+
throw new Error(`customer-session ${path} timeout`);
|
|
4403
|
+
}
|
|
4404
|
+
throw error;
|
|
4405
|
+
}
|
|
4406
|
+
}
|
|
4407
|
+
};
|
|
4408
|
+
|
|
3794
4409
|
// src/baas/client.ts
|
|
3795
4410
|
var BaasClient = class {
|
|
3796
4411
|
hostUrl;
|
|
@@ -3815,6 +4430,8 @@ var BaasClient = class {
|
|
|
3815
4430
|
deployment;
|
|
3816
4431
|
/** Autonomous smart agent management */
|
|
3817
4432
|
agents;
|
|
4433
|
+
/** Customer→smart-app session bridge (TokenGate Face B). */
|
|
4434
|
+
customerSession;
|
|
3818
4435
|
constructor(config) {
|
|
3819
4436
|
this.allowInsecure = config.allowInsecure ?? false;
|
|
3820
4437
|
this.hostUrl = validateUrl2(config.hostUrl, this.allowInsecure);
|
|
@@ -3834,6 +4451,7 @@ var BaasClient = class {
|
|
|
3834
4451
|
this.messaging = new MessagingClient(this.http, getAppId);
|
|
3835
4452
|
this.deployment = new DeploymentClient(this.http);
|
|
3836
4453
|
this.agents = new AgentsClient(this.http);
|
|
4454
|
+
this.customerSession = new CustomerSessionClient(baseUrlWithPrefix, this.timeout);
|
|
3837
4455
|
}
|
|
3838
4456
|
/** Set the app ID (for newly registered apps) */
|
|
3839
4457
|
setAppId(appId) {
|
|
@@ -3860,7 +4478,7 @@ var BaasClient = class {
|
|
|
3860
4478
|
requireAppId() {
|
|
3861
4479
|
if (!this.appId) {
|
|
3862
4480
|
throw new BaasError(
|
|
3863
|
-
"App ID required.
|
|
4481
|
+
"App ID required. Provide appId in config (e.g. from a prior deployment.init() call).",
|
|
3864
4482
|
400
|
|
3865
4483
|
);
|
|
3866
4484
|
}
|
|
@@ -3907,12 +4525,6 @@ var BaasClient = class {
|
|
|
3907
4525
|
}
|
|
3908
4526
|
this.authToken = null;
|
|
3909
4527
|
}
|
|
3910
|
-
// ========== App Registration ==========
|
|
3911
|
-
/** Register a new app on the BaaS host */
|
|
3912
|
-
async register(request) {
|
|
3913
|
-
this.requireAuth();
|
|
3914
|
-
return this.post("/api/deployment/apps", request);
|
|
3915
|
-
}
|
|
3916
4528
|
// ========== HTTP Helpers ==========
|
|
3917
4529
|
requireAuth() {
|
|
3918
4530
|
if (!this.authToken) {
|
|
@@ -4007,6 +4619,7 @@ exports.CapabilityNotEnabledError = CapabilityNotEnabledError;
|
|
|
4007
4619
|
exports.CapabilityValidationError = CapabilityValidationError;
|
|
4008
4620
|
exports.CircuitBreaker = CircuitBreaker;
|
|
4009
4621
|
exports.CircuitBreakerOpenError = CircuitBreakerOpenError;
|
|
4622
|
+
exports.CustomerSessionClient = CustomerSessionClient;
|
|
4010
4623
|
exports.DEFAULT_CIRCUIT_BREAKER_CONFIG = DEFAULT_CIRCUIT_BREAKER_CONFIG;
|
|
4011
4624
|
exports.DEFAULT_RETRY_CONFIG = DEFAULT_RETRY_CONFIG;
|
|
4012
4625
|
exports.DatabaseClient = DatabaseClient;
|
|
@@ -4015,11 +4628,16 @@ exports.DnsClient = DnsClient;
|
|
|
4015
4628
|
exports.DomainsClient = DomainsClient;
|
|
4016
4629
|
exports.ErrorCode = ErrorCode;
|
|
4017
4630
|
exports.FunctionsClient = FunctionsClient;
|
|
4631
|
+
exports.GovernanceClient = GovernanceClient;
|
|
4632
|
+
exports.HistoricalBalanceClient = HistoricalBalanceClient;
|
|
4633
|
+
exports.HistoricalBalanceClientError = HistoricalBalanceClientError;
|
|
4018
4634
|
exports.IPFSClient = IPFSClient;
|
|
4019
4635
|
exports.MIRROR_NODE_URLS = MIRROR_NODE_URLS;
|
|
4020
4636
|
exports.MessagingClient = MessagingClient;
|
|
4021
4637
|
exports.MirrorNodeClient = MirrorNodeClient;
|
|
4022
4638
|
exports.MirrorNodeError = MirrorNodeError;
|
|
4639
|
+
exports.PERSONHOOD_VERIFIER_NOT_CONFIGURED = PERSONHOOD_VERIFIER_NOT_CONFIGURED;
|
|
4640
|
+
exports.PersonhoodClient = PersonhoodClient;
|
|
4023
4641
|
exports.RateLimiter = RateLimiter;
|
|
4024
4642
|
exports.RoutingClient = RoutingClient;
|
|
4025
4643
|
exports.SdkHttpError = SdkHttpError;
|
|
@@ -4043,6 +4661,10 @@ exports.createHttpClient = createHttpClient;
|
|
|
4043
4661
|
exports.createResilientFetchWithBreaker = createResilientFetchWithBreaker;
|
|
4044
4662
|
exports.discovery = discovery_exports;
|
|
4045
4663
|
exports.encodePathParam = encodePathParam;
|
|
4664
|
+
exports.governance = governance_exports;
|
|
4665
|
+
exports.isPersonhoodVerifierNotConfigured = isPersonhoodVerifierNotConfigured;
|
|
4666
|
+
exports.isRuleRejected = isRuleRejected;
|
|
4667
|
+
exports.personhood = personhood_exports;
|
|
4046
4668
|
exports.resilientFetch = resilientFetch;
|
|
4047
4669
|
exports.settlement = settlement_exports;
|
|
4048
4670
|
exports.subscription = subscription_exports;
|