@hsuite/smart-engines-sdk 3.4.1 → 3.6.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 +59 -0
- package/README.md +124 -27
- package/dist/index.d.ts +126 -55
- package/dist/index.js +711 -625
- package/dist/index.js.map +1 -1
- package/dist/ipfs-access-key/index.js.map +1 -1
- package/dist/k8s-secret-reader/index.js.map +1 -1
- package/dist/nestjs/index.d.ts +57 -44
- package/dist/nestjs/index.js +637 -513
- package/dist/nestjs/index.js.map +1 -1
- package/dist/pqc-verify/index.js.map +1 -1
- package/dist/pqc-verify-envelope/index.d.ts +1 -1
- package/dist/pqc-verify-envelope/index.js +2 -37
- package/dist/pqc-verify-envelope/index.js.map +1 -1
- package/package.json +17 -1
package/dist/nestjs/index.js
CHANGED
|
@@ -230,7 +230,7 @@ var CreateAccountRequestSchema = zod.z.object({
|
|
|
230
230
|
* Smart node security mode for the account key structure.
|
|
231
231
|
* - 'partial': threshold(2, [appOwnerKey, tssKeyList]) — co-control
|
|
232
232
|
* - 'full': TSS KeyList only — full validator network control
|
|
233
|
-
*
|
|
233
|
+
* @defaultValue 'full'
|
|
234
234
|
*/
|
|
235
235
|
securityMode: zod.z.enum(["partial", "full"]).default("full"),
|
|
236
236
|
/**
|
|
@@ -1100,6 +1100,187 @@ var ClusterDiscoveryClient = class {
|
|
|
1100
1100
|
}
|
|
1101
1101
|
};
|
|
1102
1102
|
|
|
1103
|
+
// src/http/index.ts
|
|
1104
|
+
var SdkHttpError = class extends Error {
|
|
1105
|
+
constructor(message, statusCode, details) {
|
|
1106
|
+
super(message);
|
|
1107
|
+
this.statusCode = statusCode;
|
|
1108
|
+
this.details = details;
|
|
1109
|
+
this.name = "SdkHttpError";
|
|
1110
|
+
}
|
|
1111
|
+
statusCode;
|
|
1112
|
+
details;
|
|
1113
|
+
};
|
|
1114
|
+
function createHttpClient(config) {
|
|
1115
|
+
const timeout = config.timeout ?? 3e4;
|
|
1116
|
+
function getHeaders(contentType) {
|
|
1117
|
+
const headers = {};
|
|
1118
|
+
if (contentType) {
|
|
1119
|
+
headers["Content-Type"] = contentType;
|
|
1120
|
+
}
|
|
1121
|
+
if (config.authToken) {
|
|
1122
|
+
headers["Authorization"] = `Bearer ${config.authToken}`;
|
|
1123
|
+
}
|
|
1124
|
+
if (config.apiKey) {
|
|
1125
|
+
headers["X-API-Key"] = config.apiKey;
|
|
1126
|
+
}
|
|
1127
|
+
return headers;
|
|
1128
|
+
}
|
|
1129
|
+
function setAuthToken(token) {
|
|
1130
|
+
config.authToken = token;
|
|
1131
|
+
}
|
|
1132
|
+
function getAuthToken() {
|
|
1133
|
+
return config.authToken;
|
|
1134
|
+
}
|
|
1135
|
+
async function request(method, path, body) {
|
|
1136
|
+
const url = `${config.baseUrl}${path}`;
|
|
1137
|
+
const controller = new AbortController();
|
|
1138
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
1139
|
+
try {
|
|
1140
|
+
const init = {
|
|
1141
|
+
method,
|
|
1142
|
+
headers: getHeaders("application/json"),
|
|
1143
|
+
signal: controller.signal
|
|
1144
|
+
};
|
|
1145
|
+
if (body !== void 0) {
|
|
1146
|
+
init.body = JSON.stringify(body);
|
|
1147
|
+
}
|
|
1148
|
+
const response = await fetch(url, init);
|
|
1149
|
+
clearTimeout(timeoutId);
|
|
1150
|
+
if (!response.ok) {
|
|
1151
|
+
const errorData = await response.json().catch(() => ({}));
|
|
1152
|
+
throw new SdkHttpError(
|
|
1153
|
+
errorData.message || `API error: ${response.status} ${response.statusText}`,
|
|
1154
|
+
response.status,
|
|
1155
|
+
errorData
|
|
1156
|
+
);
|
|
1157
|
+
}
|
|
1158
|
+
const text = await response.text();
|
|
1159
|
+
if (!text) return void 0;
|
|
1160
|
+
return JSON.parse(text);
|
|
1161
|
+
} catch (error) {
|
|
1162
|
+
clearTimeout(timeoutId);
|
|
1163
|
+
if (error instanceof SdkHttpError) throw error;
|
|
1164
|
+
const err = error;
|
|
1165
|
+
if (err.name === "AbortError") {
|
|
1166
|
+
throw new SdkHttpError("Request timeout", 408);
|
|
1167
|
+
}
|
|
1168
|
+
throw new SdkHttpError(`Network error: ${err.message}`, 0, error);
|
|
1169
|
+
}
|
|
1170
|
+
}
|
|
1171
|
+
async function getText(path) {
|
|
1172
|
+
const url = `${config.baseUrl}${path}`;
|
|
1173
|
+
const controller = new AbortController();
|
|
1174
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
1175
|
+
try {
|
|
1176
|
+
const response = await fetch(url, {
|
|
1177
|
+
method: "GET",
|
|
1178
|
+
headers: getHeaders(),
|
|
1179
|
+
signal: controller.signal
|
|
1180
|
+
});
|
|
1181
|
+
clearTimeout(timeoutId);
|
|
1182
|
+
if (!response.ok) {
|
|
1183
|
+
const errBody = await response.json().catch(() => ({}));
|
|
1184
|
+
throw new SdkHttpError(
|
|
1185
|
+
errBody.message || `API error: ${response.status} ${response.statusText}`,
|
|
1186
|
+
response.status,
|
|
1187
|
+
errBody
|
|
1188
|
+
);
|
|
1189
|
+
}
|
|
1190
|
+
return await response.text();
|
|
1191
|
+
} catch (error) {
|
|
1192
|
+
clearTimeout(timeoutId);
|
|
1193
|
+
if (error instanceof SdkHttpError) throw error;
|
|
1194
|
+
const err = error;
|
|
1195
|
+
if (err.name === "AbortError") {
|
|
1196
|
+
throw new SdkHttpError("Request timeout", 408);
|
|
1197
|
+
}
|
|
1198
|
+
throw new SdkHttpError(`Network error: ${err.message}`, 0, error);
|
|
1199
|
+
}
|
|
1200
|
+
}
|
|
1201
|
+
async function upload(path, file, filename, metadata, fieldName = "file") {
|
|
1202
|
+
const url = `${config.baseUrl}${path}`;
|
|
1203
|
+
const controller = new AbortController();
|
|
1204
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout * 2);
|
|
1205
|
+
try {
|
|
1206
|
+
const formData = new FormData();
|
|
1207
|
+
const blob = file instanceof Blob ? file : new Blob([new Uint8Array(file)]);
|
|
1208
|
+
formData.append(fieldName, blob, filename);
|
|
1209
|
+
if (metadata) {
|
|
1210
|
+
for (const [key, value] of Object.entries(metadata)) {
|
|
1211
|
+
formData.append(key, value);
|
|
1212
|
+
}
|
|
1213
|
+
}
|
|
1214
|
+
const headers = {};
|
|
1215
|
+
if (config.authToken) {
|
|
1216
|
+
headers["Authorization"] = `Bearer ${config.authToken}`;
|
|
1217
|
+
}
|
|
1218
|
+
if (config.apiKey) {
|
|
1219
|
+
headers["X-API-Key"] = config.apiKey;
|
|
1220
|
+
}
|
|
1221
|
+
const response = await fetch(url, {
|
|
1222
|
+
method: "POST",
|
|
1223
|
+
headers,
|
|
1224
|
+
body: formData,
|
|
1225
|
+
signal: controller.signal
|
|
1226
|
+
});
|
|
1227
|
+
clearTimeout(timeoutId);
|
|
1228
|
+
if (!response.ok) {
|
|
1229
|
+
const errorData = await response.json().catch(() => ({}));
|
|
1230
|
+
throw new SdkHttpError(
|
|
1231
|
+
errorData.message || `Upload error: ${response.status} ${response.statusText}`,
|
|
1232
|
+
response.status,
|
|
1233
|
+
errorData
|
|
1234
|
+
);
|
|
1235
|
+
}
|
|
1236
|
+
return response.json();
|
|
1237
|
+
} catch (error) {
|
|
1238
|
+
clearTimeout(timeoutId);
|
|
1239
|
+
if (error instanceof SdkHttpError) throw error;
|
|
1240
|
+
const err = error;
|
|
1241
|
+
if (err.name === "AbortError") {
|
|
1242
|
+
throw new SdkHttpError("Upload timeout", 408);
|
|
1243
|
+
}
|
|
1244
|
+
throw new SdkHttpError(`Upload error: ${err.message}`, 0, error);
|
|
1245
|
+
}
|
|
1246
|
+
}
|
|
1247
|
+
let reauthInFlight = null;
|
|
1248
|
+
async function withAuthRetry(path, op) {
|
|
1249
|
+
try {
|
|
1250
|
+
return await op();
|
|
1251
|
+
} catch (error) {
|
|
1252
|
+
const refreshable = !!config.onUnauthorized && !path.startsWith("/api/auth/") && error instanceof SdkHttpError && error.statusCode === 401;
|
|
1253
|
+
if (!refreshable) throw error;
|
|
1254
|
+
if (!reauthInFlight) {
|
|
1255
|
+
reauthInFlight = Promise.resolve(config.onUnauthorized()).finally(() => {
|
|
1256
|
+
reauthInFlight = null;
|
|
1257
|
+
});
|
|
1258
|
+
}
|
|
1259
|
+
try {
|
|
1260
|
+
await reauthInFlight;
|
|
1261
|
+
} catch {
|
|
1262
|
+
throw error;
|
|
1263
|
+
}
|
|
1264
|
+
return await op();
|
|
1265
|
+
}
|
|
1266
|
+
}
|
|
1267
|
+
const client = {
|
|
1268
|
+
post: (path, body) => withAuthRetry(path, () => request("POST", path, body)),
|
|
1269
|
+
get: (path) => withAuthRetry(path, () => request("GET", path)),
|
|
1270
|
+
put: (path, body) => withAuthRetry(path, () => request("PUT", path, body)),
|
|
1271
|
+
patch: (path, body) => withAuthRetry(path, () => request("PATCH", path, body)),
|
|
1272
|
+
delete: (path) => withAuthRetry(path, () => request("DELETE", path)),
|
|
1273
|
+
getText: (path) => withAuthRetry(path, () => getText(path)),
|
|
1274
|
+
upload: ((path, file, filename, metadata, fieldName) => withAuthRetry(path, () => upload(path, file, filename, metadata, fieldName))),
|
|
1275
|
+
setAuthToken,
|
|
1276
|
+
getAuthToken
|
|
1277
|
+
};
|
|
1278
|
+
return client;
|
|
1279
|
+
}
|
|
1280
|
+
function encodePathParam(param) {
|
|
1281
|
+
return encodeURIComponent(param).replace(/%2F/gi, "");
|
|
1282
|
+
}
|
|
1283
|
+
|
|
1103
1284
|
// src/discovery/discovery-client.ts
|
|
1104
1285
|
var DiscoveryClient = class {
|
|
1105
1286
|
constructor(http) {
|
|
@@ -1133,7 +1314,7 @@ var DiscoveryClient = class {
|
|
|
1133
1314
|
* try/catch.
|
|
1134
1315
|
*/
|
|
1135
1316
|
async getClusterByNode(nodeId) {
|
|
1136
|
-
return this.http.get(`/discovery/clusters/${
|
|
1317
|
+
return this.http.get(`/discovery/clusters/${encodePathParam(nodeId)}`);
|
|
1137
1318
|
}
|
|
1138
1319
|
};
|
|
1139
1320
|
var PlatformImagesClient = class {
|
|
@@ -1163,7 +1344,7 @@ var PlatformImagesClient = class {
|
|
|
1163
1344
|
* authorized?" queries.
|
|
1164
1345
|
*/
|
|
1165
1346
|
async get(imageName) {
|
|
1166
|
-
return this.http.get(`/discovery/platform-images/${
|
|
1347
|
+
return this.http.get(`/discovery/platform-images/${encodePathParam(imageName)}`);
|
|
1167
1348
|
}
|
|
1168
1349
|
/**
|
|
1169
1350
|
* `GET /api/v3/discovery/platform-images/:imageName/:version` —
|
|
@@ -1172,7 +1353,7 @@ var PlatformImagesClient = class {
|
|
|
1172
1353
|
*/
|
|
1173
1354
|
async getVersion(imageName, version) {
|
|
1174
1355
|
return this.http.get(
|
|
1175
|
-
`/discovery/platform-images/${
|
|
1356
|
+
`/discovery/platform-images/${encodePathParam(imageName)}/${encodePathParam(version)}`
|
|
1176
1357
|
);
|
|
1177
1358
|
}
|
|
1178
1359
|
/**
|
|
@@ -1186,13 +1367,63 @@ var PlatformImagesClient = class {
|
|
|
1186
1367
|
*/
|
|
1187
1368
|
async verify(imageName, version, digest) {
|
|
1188
1369
|
return this.http.get(
|
|
1189
|
-
`/discovery/platform-images/${
|
|
1370
|
+
`/discovery/platform-images/${encodePathParam(imageName)}/${encodePathParam(
|
|
1190
1371
|
version
|
|
1191
1372
|
)}/verify?digest=${encodeURIComponent(digest)}`
|
|
1192
1373
|
);
|
|
1193
1374
|
}
|
|
1194
1375
|
};
|
|
1195
1376
|
|
|
1377
|
+
// src/network-presets.ts
|
|
1378
|
+
var KNOWN_NETWORKS = {
|
|
1379
|
+
testnet: {
|
|
1380
|
+
bootstrap: ["https://gateway.testnet.hsuite.network"]
|
|
1381
|
+
},
|
|
1382
|
+
mainnet: {
|
|
1383
|
+
// Mainnet entrypoint reserved. The SDK still resolves the name so
|
|
1384
|
+
// upgrade-by-flipping-NETWORK works; the bootstrap URL is the
|
|
1385
|
+
// pre-allocated DNS we own. If mainnet isn't deployed yet, the discovery
|
|
1386
|
+
// fetch will fail at runtime with the same "no seed reachable" error
|
|
1387
|
+
// any unreachable URL produces — the caller learns the network is not
|
|
1388
|
+
// live, rather than getting a baffling "unknown network" TypeScript
|
|
1389
|
+
// error at compile time.
|
|
1390
|
+
bootstrap: ["https://gateway.hsuite.network"]
|
|
1391
|
+
}
|
|
1392
|
+
};
|
|
1393
|
+
function resolveNetwork(name) {
|
|
1394
|
+
const preset = KNOWN_NETWORKS[name];
|
|
1395
|
+
if (!preset) {
|
|
1396
|
+
throw new Error(
|
|
1397
|
+
`Unknown network: "${name}". Known networks: ${Object.keys(KNOWN_NETWORKS).join(", ")}`
|
|
1398
|
+
);
|
|
1399
|
+
}
|
|
1400
|
+
return preset;
|
|
1401
|
+
}
|
|
1402
|
+
|
|
1403
|
+
// src/discovery/resolve-cluster.ts
|
|
1404
|
+
async function resolveClusterEndpoint(config) {
|
|
1405
|
+
const allowInsecure = config.allowInsecure ?? false;
|
|
1406
|
+
const bootstrap = config.bootstrap ? [...config.bootstrap] : config.network ? [...resolveNetwork(config.network).bootstrap] : [];
|
|
1407
|
+
if (bootstrap.length === 0) {
|
|
1408
|
+
return { ok: false, reason: "no-seeds" };
|
|
1409
|
+
}
|
|
1410
|
+
const discovery = new ClusterDiscoveryClient({
|
|
1411
|
+
bootstrap,
|
|
1412
|
+
allowInsecure,
|
|
1413
|
+
trustAnchor: config.trustAnchor ? {
|
|
1414
|
+
network: config.trustAnchor.network,
|
|
1415
|
+
registryTopicId: config.trustAnchor.registryTopicId,
|
|
1416
|
+
mirrorNodeUrl: config.trustAnchor.mirrorNodeUrl,
|
|
1417
|
+
allowInsecure
|
|
1418
|
+
} : void 0
|
|
1419
|
+
});
|
|
1420
|
+
const cluster = await discovery.getRandomCluster();
|
|
1421
|
+
if (!cluster) {
|
|
1422
|
+
return { ok: false, reason: "no-clusters" };
|
|
1423
|
+
}
|
|
1424
|
+
return { ok: true, cluster };
|
|
1425
|
+
}
|
|
1426
|
+
|
|
1196
1427
|
// src/auth/validator-auth.ts
|
|
1197
1428
|
var SUPPORTED_AUTH_CHAINS = [
|
|
1198
1429
|
"hedera",
|
|
@@ -1201,6 +1432,10 @@ var SUPPORTED_AUTH_CHAINS = [
|
|
|
1201
1432
|
"stellar",
|
|
1202
1433
|
"solana"
|
|
1203
1434
|
];
|
|
1435
|
+
function toBytes(value) {
|
|
1436
|
+
if (value instanceof Uint8Array) return value;
|
|
1437
|
+
return value.toBytes();
|
|
1438
|
+
}
|
|
1204
1439
|
function validateValidatorUrl(url, allowInsecure = false) {
|
|
1205
1440
|
try {
|
|
1206
1441
|
const parsed = new URL(url);
|
|
@@ -1400,30 +1635,42 @@ var ValidatorAuthClient = class {
|
|
|
1400
1635
|
}
|
|
1401
1636
|
}
|
|
1402
1637
|
/**
|
|
1403
|
-
* Sign challenge with Hedera private key
|
|
1638
|
+
* Sign challenge with Hedera private key.
|
|
1639
|
+
*
|
|
1640
|
+
* Structurally typed against the surface of `@hashgraph/sdk`'s
|
|
1641
|
+
* `PrivateKey`. We don't `import` the SDK directly — pulling it into
|
|
1642
|
+
* the smart-engine SDK's runtime would bloat browser bundles and bring
|
|
1643
|
+
* peer-dep churn — but any object with a compatible `sign(...)` method
|
|
1644
|
+
* works.
|
|
1404
1645
|
*
|
|
1405
1646
|
* @param challenge - Challenge string from validator
|
|
1406
|
-
* @param privateKey - Hedera PrivateKey instance
|
|
1647
|
+
* @param privateKey - Hedera PrivateKey instance (or compatible signer)
|
|
1407
1648
|
* @returns Hex-encoded signature
|
|
1408
1649
|
*/
|
|
1409
1650
|
signChallengeHedera(challenge, privateKey) {
|
|
1410
|
-
const messageBytes = Buffer.from(challenge, "utf-8");
|
|
1651
|
+
const messageBytes = new Uint8Array(Buffer.from(challenge, "utf-8"));
|
|
1411
1652
|
const signature = privateKey.sign(messageBytes);
|
|
1412
|
-
return Buffer.from(signature).toString("hex");
|
|
1653
|
+
return Buffer.from(toBytes(signature)).toString("hex");
|
|
1413
1654
|
}
|
|
1414
1655
|
/**
|
|
1415
|
-
* Sign challenge with XRPL wallet
|
|
1656
|
+
* Sign challenge with XRPL wallet.
|
|
1657
|
+
*
|
|
1658
|
+
* Structurally typed against the surface of xrpl's `Wallet` — see the
|
|
1659
|
+
* comment on {@link HederaSigner} for the "no direct import" rationale.
|
|
1660
|
+
* Accepts both the `{ signedTransaction }` envelope and the bare-string
|
|
1661
|
+
* return shapes that xrpl signer libraries expose.
|
|
1416
1662
|
*
|
|
1417
1663
|
* @param challenge - Challenge string from validator
|
|
1418
|
-
* @param wallet - XRPL Wallet instance
|
|
1664
|
+
* @param wallet - XRPL Wallet instance (or compatible signer)
|
|
1419
1665
|
* @returns Hex-encoded signature
|
|
1420
1666
|
*/
|
|
1421
1667
|
signChallengeXRPL(challenge, wallet) {
|
|
1422
1668
|
const signature = wallet.sign(challenge);
|
|
1423
|
-
if (typeof signature === "string"
|
|
1424
|
-
return signature;
|
|
1669
|
+
if (typeof signature === "string") {
|
|
1670
|
+
if (/^[0-9A-Fa-f]+$/.test(signature)) return signature;
|
|
1671
|
+
return Buffer.from(signature).toString("hex");
|
|
1425
1672
|
}
|
|
1426
|
-
return
|
|
1673
|
+
return signature.signedTransaction;
|
|
1427
1674
|
}
|
|
1428
1675
|
/**
|
|
1429
1676
|
* Complete authentication flow in one call
|
|
@@ -1460,189 +1707,6 @@ var ValidatorAuthError = class extends Error {
|
|
|
1460
1707
|
details;
|
|
1461
1708
|
};
|
|
1462
1709
|
|
|
1463
|
-
// src/http/index.ts
|
|
1464
|
-
var SdkHttpError = class extends Error {
|
|
1465
|
-
constructor(message, statusCode, details) {
|
|
1466
|
-
super(message);
|
|
1467
|
-
this.statusCode = statusCode;
|
|
1468
|
-
this.details = details;
|
|
1469
|
-
this.name = "SdkHttpError";
|
|
1470
|
-
}
|
|
1471
|
-
statusCode;
|
|
1472
|
-
details;
|
|
1473
|
-
};
|
|
1474
|
-
function createHttpClient(config) {
|
|
1475
|
-
const timeout = config.timeout ?? 3e4;
|
|
1476
|
-
function getHeaders(contentType) {
|
|
1477
|
-
const headers = {};
|
|
1478
|
-
if (contentType) {
|
|
1479
|
-
headers["Content-Type"] = contentType;
|
|
1480
|
-
}
|
|
1481
|
-
if (config.authToken) {
|
|
1482
|
-
headers["Authorization"] = `Bearer ${config.authToken}`;
|
|
1483
|
-
}
|
|
1484
|
-
if (config.apiKey) {
|
|
1485
|
-
headers["X-API-Key"] = config.apiKey;
|
|
1486
|
-
}
|
|
1487
|
-
return headers;
|
|
1488
|
-
}
|
|
1489
|
-
function setAuthToken(token) {
|
|
1490
|
-
config.authToken = token;
|
|
1491
|
-
}
|
|
1492
|
-
async function request(method, path, body) {
|
|
1493
|
-
const url = `${config.baseUrl}${path}`;
|
|
1494
|
-
const controller = new AbortController();
|
|
1495
|
-
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
1496
|
-
try {
|
|
1497
|
-
const init = {
|
|
1498
|
-
method,
|
|
1499
|
-
headers: getHeaders("application/json"),
|
|
1500
|
-
signal: controller.signal
|
|
1501
|
-
};
|
|
1502
|
-
if (body !== void 0) {
|
|
1503
|
-
init.body = JSON.stringify(body);
|
|
1504
|
-
}
|
|
1505
|
-
const response = await fetch(url, init);
|
|
1506
|
-
clearTimeout(timeoutId);
|
|
1507
|
-
if (!response.ok) {
|
|
1508
|
-
const errorData = await response.json().catch(() => ({}));
|
|
1509
|
-
throw new SdkHttpError(
|
|
1510
|
-
errorData.message || `API error: ${response.status} ${response.statusText}`,
|
|
1511
|
-
response.status,
|
|
1512
|
-
errorData
|
|
1513
|
-
);
|
|
1514
|
-
}
|
|
1515
|
-
const text = await response.text();
|
|
1516
|
-
if (!text) return void 0;
|
|
1517
|
-
return JSON.parse(text);
|
|
1518
|
-
} catch (error) {
|
|
1519
|
-
clearTimeout(timeoutId);
|
|
1520
|
-
if (error instanceof SdkHttpError) throw error;
|
|
1521
|
-
const err = error;
|
|
1522
|
-
if (err.name === "AbortError") {
|
|
1523
|
-
throw new SdkHttpError("Request timeout", 408);
|
|
1524
|
-
}
|
|
1525
|
-
throw new SdkHttpError(`Network error: ${err.message}`, 0, error);
|
|
1526
|
-
}
|
|
1527
|
-
}
|
|
1528
|
-
async function getText(path) {
|
|
1529
|
-
const url = `${config.baseUrl}${path}`;
|
|
1530
|
-
const controller = new AbortController();
|
|
1531
|
-
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
1532
|
-
try {
|
|
1533
|
-
const response = await fetch(url, {
|
|
1534
|
-
method: "GET",
|
|
1535
|
-
headers: getHeaders(),
|
|
1536
|
-
signal: controller.signal
|
|
1537
|
-
});
|
|
1538
|
-
clearTimeout(timeoutId);
|
|
1539
|
-
if (!response.ok) {
|
|
1540
|
-
const errBody = await response.json().catch(() => ({}));
|
|
1541
|
-
throw new SdkHttpError(
|
|
1542
|
-
errBody.message || `API error: ${response.status} ${response.statusText}`,
|
|
1543
|
-
response.status,
|
|
1544
|
-
errBody
|
|
1545
|
-
);
|
|
1546
|
-
}
|
|
1547
|
-
return await response.text();
|
|
1548
|
-
} catch (error) {
|
|
1549
|
-
clearTimeout(timeoutId);
|
|
1550
|
-
if (error instanceof SdkHttpError) throw error;
|
|
1551
|
-
const err = error;
|
|
1552
|
-
if (err.name === "AbortError") {
|
|
1553
|
-
throw new SdkHttpError("Request timeout", 408);
|
|
1554
|
-
}
|
|
1555
|
-
throw new SdkHttpError(`Network error: ${err.message}`, 0, error);
|
|
1556
|
-
}
|
|
1557
|
-
}
|
|
1558
|
-
async function upload(path, file, filename, metadata, fieldName = "file") {
|
|
1559
|
-
const url = `${config.baseUrl}${path}`;
|
|
1560
|
-
const controller = new AbortController();
|
|
1561
|
-
const timeoutId = setTimeout(() => controller.abort(), timeout * 2);
|
|
1562
|
-
try {
|
|
1563
|
-
const formData = new FormData();
|
|
1564
|
-
const blob = file instanceof Blob ? file : new Blob([new Uint8Array(file)]);
|
|
1565
|
-
formData.append(fieldName, blob, filename);
|
|
1566
|
-
if (metadata) {
|
|
1567
|
-
for (const [key, value] of Object.entries(metadata)) {
|
|
1568
|
-
formData.append(key, value);
|
|
1569
|
-
}
|
|
1570
|
-
}
|
|
1571
|
-
const headers = {};
|
|
1572
|
-
if (config.authToken) {
|
|
1573
|
-
headers["Authorization"] = `Bearer ${config.authToken}`;
|
|
1574
|
-
}
|
|
1575
|
-
if (config.apiKey) {
|
|
1576
|
-
headers["X-API-Key"] = config.apiKey;
|
|
1577
|
-
}
|
|
1578
|
-
const response = await fetch(url, {
|
|
1579
|
-
method: "POST",
|
|
1580
|
-
headers,
|
|
1581
|
-
body: formData,
|
|
1582
|
-
signal: controller.signal
|
|
1583
|
-
});
|
|
1584
|
-
clearTimeout(timeoutId);
|
|
1585
|
-
if (!response.ok) {
|
|
1586
|
-
const errorData = await response.json().catch(() => ({}));
|
|
1587
|
-
throw new SdkHttpError(
|
|
1588
|
-
errorData.message || `Upload error: ${response.status} ${response.statusText}`,
|
|
1589
|
-
response.status,
|
|
1590
|
-
errorData
|
|
1591
|
-
);
|
|
1592
|
-
}
|
|
1593
|
-
return response.json();
|
|
1594
|
-
} catch (error) {
|
|
1595
|
-
clearTimeout(timeoutId);
|
|
1596
|
-
if (error instanceof SdkHttpError) throw error;
|
|
1597
|
-
const err = error;
|
|
1598
|
-
if (err.name === "AbortError") {
|
|
1599
|
-
throw new SdkHttpError("Upload timeout", 408);
|
|
1600
|
-
}
|
|
1601
|
-
throw new SdkHttpError(`Upload error: ${err.message}`, 0, error);
|
|
1602
|
-
}
|
|
1603
|
-
}
|
|
1604
|
-
const client = {
|
|
1605
|
-
post: (path, body) => request("POST", path, body),
|
|
1606
|
-
get: (path) => request("GET", path),
|
|
1607
|
-
put: (path, body) => request("PUT", path, body),
|
|
1608
|
-
patch: (path, body) => request("PATCH", path, body),
|
|
1609
|
-
delete: (path) => request("DELETE", path),
|
|
1610
|
-
getText,
|
|
1611
|
-
upload: ((path, file, filename, metadata, fieldName) => upload(path, file, filename, metadata, fieldName)),
|
|
1612
|
-
setAuthToken
|
|
1613
|
-
};
|
|
1614
|
-
return client;
|
|
1615
|
-
}
|
|
1616
|
-
function encodePathParam(param) {
|
|
1617
|
-
return encodeURIComponent(param).replace(/%2F/gi, "");
|
|
1618
|
-
}
|
|
1619
|
-
|
|
1620
|
-
// src/network-presets.ts
|
|
1621
|
-
var KNOWN_NETWORKS = {
|
|
1622
|
-
testnet: {
|
|
1623
|
-
bootstrap: ["https://gateway.testnet.hsuite.network"]
|
|
1624
|
-
},
|
|
1625
|
-
mainnet: {
|
|
1626
|
-
// Mainnet entrypoint reserved. The SDK still resolves the name so
|
|
1627
|
-
// upgrade-by-flipping-NETWORK works; the bootstrap URL is the
|
|
1628
|
-
// pre-allocated DNS we own. If mainnet isn't deployed yet, the discovery
|
|
1629
|
-
// fetch will fail at runtime with the same "no seed reachable" error
|
|
1630
|
-
// any unreachable URL produces — the caller learns the network is not
|
|
1631
|
-
// live, rather than getting a baffling "unknown network" TypeScript
|
|
1632
|
-
// error at compile time.
|
|
1633
|
-
bootstrap: ["https://gateway.hsuite.network"]
|
|
1634
|
-
}
|
|
1635
|
-
};
|
|
1636
|
-
function resolveNetwork(name) {
|
|
1637
|
-
const preset = KNOWN_NETWORKS[name];
|
|
1638
|
-
if (!preset) {
|
|
1639
|
-
throw new Error(
|
|
1640
|
-
`Unknown network: "${name}". Known networks: ${Object.keys(KNOWN_NETWORKS).join(", ")}`
|
|
1641
|
-
);
|
|
1642
|
-
}
|
|
1643
|
-
return preset;
|
|
1644
|
-
}
|
|
1645
|
-
|
|
1646
1710
|
// src/subscription/index.ts
|
|
1647
1711
|
var SubscriptionClient = class {
|
|
1648
1712
|
constructor(http) {
|
|
@@ -1660,13 +1724,13 @@ var SubscriptionClient = class {
|
|
|
1660
1724
|
* Get subscription status by app ID
|
|
1661
1725
|
*/
|
|
1662
1726
|
async getStatus(appId) {
|
|
1663
|
-
return this.http.get(`/subscription/status/${
|
|
1727
|
+
return this.http.get(`/subscription/status/${encodePathParam(appId)}`);
|
|
1664
1728
|
}
|
|
1665
1729
|
/**
|
|
1666
1730
|
* Mint subscription NFT after deposit is confirmed
|
|
1667
1731
|
*/
|
|
1668
1732
|
async mintNft(appId) {
|
|
1669
|
-
return this.http.post(`/subscription/mint/${
|
|
1733
|
+
return this.http.post(`/subscription/mint/${encodePathParam(appId)}`, {});
|
|
1670
1734
|
}
|
|
1671
1735
|
/**
|
|
1672
1736
|
* Renew subscription by extending period
|
|
@@ -1735,13 +1799,13 @@ var SubscriptionClient = class {
|
|
|
1735
1799
|
* List subscriptions by status
|
|
1736
1800
|
*/
|
|
1737
1801
|
async listByStatus(status) {
|
|
1738
|
-
return this.http.get(`/subscription/list/status/${
|
|
1802
|
+
return this.http.get(`/subscription/list/status/${encodePathParam(status)}`);
|
|
1739
1803
|
}
|
|
1740
1804
|
/**
|
|
1741
1805
|
* Get subscription balance
|
|
1742
1806
|
*/
|
|
1743
1807
|
async getBalance(appId) {
|
|
1744
|
-
return this.http.get(`/subscription/balance/${
|
|
1808
|
+
return this.http.get(`/subscription/balance/${encodePathParam(appId)}`);
|
|
1745
1809
|
}
|
|
1746
1810
|
// ─── Tier-Change Endpoints ────────────────────────────────────────────────
|
|
1747
1811
|
/**
|
|
@@ -1773,19 +1837,19 @@ var SubscriptionClient = class {
|
|
|
1773
1837
|
*/
|
|
1774
1838
|
async getActiveFor(walletAddress) {
|
|
1775
1839
|
return this.http.get(
|
|
1776
|
-
`/subscription/active-for/${
|
|
1840
|
+
`/subscription/active-for/${encodePathParam(walletAddress)}`
|
|
1777
1841
|
);
|
|
1778
1842
|
}
|
|
1779
1843
|
/** Today's consumption breakdown by category for an app. Owner-only. */
|
|
1780
1844
|
async getUsage(appId) {
|
|
1781
|
-
return this.http.get(`/subscription/usage/${
|
|
1845
|
+
return this.http.get(`/subscription/usage/${encodePathParam(appId)}`);
|
|
1782
1846
|
}
|
|
1783
1847
|
/**
|
|
1784
1848
|
* Current usage with overage info: usage percent, grace status,
|
|
1785
1849
|
* upgrade suggestion, projected days until limit. Owner-only.
|
|
1786
1850
|
*/
|
|
1787
1851
|
async getUsageStatus(appId) {
|
|
1788
|
-
return this.http.get(`/subscription/usage/status/${
|
|
1852
|
+
return this.http.get(`/subscription/usage/status/${encodePathParam(appId)}`);
|
|
1789
1853
|
}
|
|
1790
1854
|
/**
|
|
1791
1855
|
* Subscription balance deduction history. Pagination + ISO-8601 range
|
|
@@ -1799,7 +1863,7 @@ var SubscriptionClient = class {
|
|
|
1799
1863
|
if (options?.to) params.append("to", options.to);
|
|
1800
1864
|
const qs = params.toString();
|
|
1801
1865
|
return this.http.get(
|
|
1802
|
-
`/subscription/billing/${
|
|
1866
|
+
`/subscription/billing/${encodePathParam(appId)}${qs ? `?${qs}` : ""}`
|
|
1803
1867
|
);
|
|
1804
1868
|
}
|
|
1805
1869
|
/**
|
|
@@ -1819,6 +1883,40 @@ var SubscriptionClient = class {
|
|
|
1819
1883
|
}
|
|
1820
1884
|
};
|
|
1821
1885
|
|
|
1886
|
+
// src/faucet/index.ts
|
|
1887
|
+
var FaucetClient = class {
|
|
1888
|
+
constructor(http) {
|
|
1889
|
+
this.http = http;
|
|
1890
|
+
}
|
|
1891
|
+
http;
|
|
1892
|
+
/**
|
|
1893
|
+
* Request a signing challenge for a recipient address. The returned
|
|
1894
|
+
* `message` must be signed by the key controlling `recipientAddress`.
|
|
1895
|
+
*/
|
|
1896
|
+
async requestChallenge(chain, recipientAddress) {
|
|
1897
|
+
return this.http.post("/faucet/hsuite/challenge", { chain, recipientAddress });
|
|
1898
|
+
}
|
|
1899
|
+
/**
|
|
1900
|
+
* Submit a signed challenge to dispense HST. The result is a discriminated
|
|
1901
|
+
* union on `status` — branch on `'dispensed' | 'trustline_required' |
|
|
1902
|
+
* 'rate_limited'`. On `'trustline_required'`, set the returned trust line on
|
|
1903
|
+
* the recipient and re-dispense with a fresh challenge.
|
|
1904
|
+
*/
|
|
1905
|
+
async dispense(req) {
|
|
1906
|
+
return this.http.post("/faucet/hsuite", req);
|
|
1907
|
+
}
|
|
1908
|
+
/**
|
|
1909
|
+
* Get today's dispense status for a recipient (e.g. amount already
|
|
1910
|
+
* dispensed today).
|
|
1911
|
+
*/
|
|
1912
|
+
async getStatus(chain, recipientAddress) {
|
|
1913
|
+
const params = new URLSearchParams();
|
|
1914
|
+
params.append("chain", chain);
|
|
1915
|
+
params.append("recipientAddress", recipientAddress);
|
|
1916
|
+
return this.http.get(`/faucet/hsuite/status?${params.toString()}`);
|
|
1917
|
+
}
|
|
1918
|
+
};
|
|
1919
|
+
|
|
1822
1920
|
// src/tss/index.ts
|
|
1823
1921
|
var TSSClient = class {
|
|
1824
1922
|
constructor(http) {
|
|
@@ -1826,80 +1924,105 @@ var TSSClient = class {
|
|
|
1826
1924
|
}
|
|
1827
1925
|
http;
|
|
1828
1926
|
/**
|
|
1829
|
-
* Create a multi-sig entity
|
|
1927
|
+
* Create a multi-sig entity via a synchronous DKG ceremony.
|
|
1928
|
+
*
|
|
1929
|
+
* @param options Entity-creation parameters (chain, threshold, participants).
|
|
1930
|
+
* @returns The created entity's identity (ids + group public keys).
|
|
1830
1931
|
*/
|
|
1831
1932
|
async createEntity(options) {
|
|
1832
1933
|
return this.http.post("/tss/entity/create", options);
|
|
1833
1934
|
}
|
|
1834
1935
|
/**
|
|
1835
|
-
* Reshare keys when cluster membership changes.
|
|
1836
|
-
*
|
|
1936
|
+
* Reshare keys when cluster membership changes. Redistributes secret shares
|
|
1937
|
+
* WITHOUT changing public keys.
|
|
1938
|
+
*
|
|
1939
|
+
* @param request The new membership / threshold to reshare to.
|
|
1940
|
+
* @returns The reshare outcome.
|
|
1837
1941
|
*/
|
|
1838
1942
|
async reshareCluster(request) {
|
|
1839
1943
|
return this.http.post("/tss/cluster/reshare", request);
|
|
1840
1944
|
}
|
|
1841
1945
|
/**
|
|
1842
|
-
* Get entity details by
|
|
1946
|
+
* Get entity details by id.
|
|
1947
|
+
*
|
|
1948
|
+
* @param entityId The entity id to look up.
|
|
1949
|
+
* @returns The entity's details.
|
|
1843
1950
|
*/
|
|
1844
1951
|
async getEntity(entityId) {
|
|
1845
|
-
return this.http.get(`/tss/entity/${
|
|
1952
|
+
return this.http.get(`/tss/entity/${encodePathParam(entityId)}`);
|
|
1846
1953
|
}
|
|
1847
1954
|
/**
|
|
1848
1955
|
* Sign a transaction using MPC.
|
|
1849
1956
|
*
|
|
1850
1957
|
* Routes to `POST /api/v3/tss/hedera/sign-mpc`. Only `'hedera'` is wired
|
|
1851
|
-
* server-side
|
|
1852
|
-
*
|
|
1853
|
-
*
|
|
1854
|
-
*
|
|
1855
|
-
*
|
|
1856
|
-
*
|
|
1958
|
+
* server-side; other chain signing paths run via their own controllers (XRPL
|
|
1959
|
+
* multisig, Polkadot MPC) and are not exposed through this sub-client. The
|
|
1960
|
+
* `chain` field is carried into the request body so the validator can log +
|
|
1961
|
+
* route, but any non-`'hedera'` value will 404.
|
|
1962
|
+
*
|
|
1963
|
+
* @param request The MPC signing request; `chain` is forced to `'hedera'`.
|
|
1964
|
+
* @returns The MPC signing result.
|
|
1857
1965
|
*/
|
|
1858
1966
|
async signMPC(request) {
|
|
1859
1967
|
const chain = "hedera";
|
|
1860
1968
|
return this.http.post(`/tss/${chain}/sign-mpc`, { ...request, chain });
|
|
1861
1969
|
}
|
|
1862
1970
|
/**
|
|
1863
|
-
* Get known validators and their public keys
|
|
1971
|
+
* Get known validators and their public keys.
|
|
1972
|
+
*
|
|
1973
|
+
* @returns The validator list with public keys.
|
|
1864
1974
|
*/
|
|
1865
1975
|
async getValidators() {
|
|
1866
1976
|
return this.http.get("/tss/validators");
|
|
1867
1977
|
}
|
|
1868
1978
|
/**
|
|
1869
|
-
* Force announcement of this node's public key
|
|
1979
|
+
* Force announcement of this node's public key.
|
|
1980
|
+
*
|
|
1981
|
+
* @returns Whether the announcement was accepted, plus a status message.
|
|
1870
1982
|
*/
|
|
1871
1983
|
async announceKey() {
|
|
1872
1984
|
return this.http.post("/tss/announce", {});
|
|
1873
1985
|
}
|
|
1874
1986
|
/**
|
|
1875
|
-
* Get TSS statistics
|
|
1987
|
+
* Get TSS statistics.
|
|
1988
|
+
*
|
|
1989
|
+
* @returns Aggregate TSS statistics.
|
|
1876
1990
|
*/
|
|
1877
1991
|
async getStats() {
|
|
1878
1992
|
return this.http.get("/tss/stats");
|
|
1879
1993
|
}
|
|
1880
1994
|
/**
|
|
1881
|
-
* List all TSS entities
|
|
1995
|
+
* List all TSS entities.
|
|
1996
|
+
*
|
|
1997
|
+
* @returns The full entity list.
|
|
1882
1998
|
*/
|
|
1883
1999
|
async listEntities() {
|
|
1884
2000
|
return this.http.get("/tss/entities");
|
|
1885
2001
|
}
|
|
1886
2002
|
/**
|
|
1887
|
-
* TSS health check
|
|
2003
|
+
* TSS health check.
|
|
2004
|
+
*
|
|
2005
|
+
* @returns The TSS subsystem health report.
|
|
1888
2006
|
*/
|
|
1889
2007
|
async getHealth() {
|
|
1890
2008
|
return this.http.get("/tss/health");
|
|
1891
2009
|
}
|
|
1892
2010
|
/**
|
|
1893
|
-
* List DKG ceremonies and their statistics
|
|
2011
|
+
* List DKG ceremonies and their statistics.
|
|
2012
|
+
*
|
|
2013
|
+
* @returns The ceremony list.
|
|
1894
2014
|
*/
|
|
1895
2015
|
async listCeremonies() {
|
|
1896
2016
|
return this.http.get("/tss/multisig/ceremonies");
|
|
1897
2017
|
}
|
|
1898
2018
|
/**
|
|
1899
|
-
* Get multi-sig transaction status by transaction
|
|
2019
|
+
* Get multi-sig transaction status by transaction id.
|
|
2020
|
+
*
|
|
2021
|
+
* @param txId The multi-sig transaction id.
|
|
2022
|
+
* @returns The current status of that transaction.
|
|
1900
2023
|
*/
|
|
1901
2024
|
async getMultiSigStatus(txId) {
|
|
1902
|
-
return this.http.get(`/tss/multisig/transactions/${
|
|
2025
|
+
return this.http.get(`/tss/multisig/transactions/${encodePathParam(txId)}`);
|
|
1903
2026
|
}
|
|
1904
2027
|
/**
|
|
1905
2028
|
* Async-job variant of {@link createEntity}.
|
|
@@ -1907,6 +2030,9 @@ var TSSClient = class {
|
|
|
1907
2030
|
* Server returns 202 + `{ jobId, statusUrl, status: 'pending' }` immediately;
|
|
1908
2031
|
* the DKG ceremony runs in the background. Poll {@link getJob} until the
|
|
1909
2032
|
* status reaches `'success'` or `'failed'`.
|
|
2033
|
+
*
|
|
2034
|
+
* @param options Entity-creation parameters.
|
|
2035
|
+
* @returns A job descriptor (`jobId`, `statusUrl`, initial status).
|
|
1910
2036
|
*/
|
|
1911
2037
|
async createEntityAsync(options) {
|
|
1912
2038
|
return this.http.post("/tss/entity/create/async", options);
|
|
@@ -1914,6 +2040,9 @@ var TSSClient = class {
|
|
|
1914
2040
|
/**
|
|
1915
2041
|
* Async-job variant of {@link reshareCluster}. Returns 202 + a polling
|
|
1916
2042
|
* descriptor; resharing runs in the background.
|
|
2043
|
+
*
|
|
2044
|
+
* @param request The new membership / threshold to reshare to.
|
|
2045
|
+
* @returns A job descriptor to poll via {@link getJob}.
|
|
1917
2046
|
*/
|
|
1918
2047
|
async reshareClusterAsync(request) {
|
|
1919
2048
|
return this.http.post("/tss/cluster/reshare/async", request);
|
|
@@ -1921,9 +2050,12 @@ var TSSClient = class {
|
|
|
1921
2050
|
/**
|
|
1922
2051
|
* Poll the status of an async TSS-ceremony job kicked off via
|
|
1923
2052
|
* {@link createEntityAsync} or {@link reshareClusterAsync}.
|
|
2053
|
+
*
|
|
2054
|
+
* @param jobId The job id returned by the async kickoff call.
|
|
2055
|
+
* @returns The job's current status (and result once terminal).
|
|
1924
2056
|
*/
|
|
1925
2057
|
async getJob(jobId) {
|
|
1926
|
-
return this.http.get(`/tss/jobs/${
|
|
2058
|
+
return this.http.get(`/tss/jobs/${encodePathParam(jobId)}`);
|
|
1927
2059
|
}
|
|
1928
2060
|
/**
|
|
1929
2061
|
* Sign a hex payload as smart-app entity `appId` via the cluster's TSS
|
|
@@ -1933,9 +2065,13 @@ var TSSClient = class {
|
|
|
1933
2065
|
* Payload constraints (enforced server-side):
|
|
1934
2066
|
* - even-length lowercase hex
|
|
1935
2067
|
* - ≥32 bytes, ≤8KB
|
|
2068
|
+
*
|
|
2069
|
+
* @param appId The smart-app entity id to sign as.
|
|
2070
|
+
* @param request The hex payload to sign.
|
|
2071
|
+
* @returns The aggregate signature over the payload.
|
|
1936
2072
|
*/
|
|
1937
2073
|
async signForApp(appId, request) {
|
|
1938
|
-
return this.http.post(`/tss/entity/${
|
|
2074
|
+
return this.http.post(`/tss/entity/${encodePathParam(appId)}/sign`, request);
|
|
1939
2075
|
}
|
|
1940
2076
|
};
|
|
1941
2077
|
|
|
@@ -1960,31 +2096,31 @@ var IPFSClient = class {
|
|
|
1960
2096
|
* Pin content by CID to ensure it persists
|
|
1961
2097
|
*/
|
|
1962
2098
|
async pin(cid) {
|
|
1963
|
-
return this.http.post(`/ipfs/pin/${
|
|
2099
|
+
return this.http.post(`/ipfs/pin/${encodePathParam(cid)}`, {});
|
|
1964
2100
|
}
|
|
1965
2101
|
/**
|
|
1966
2102
|
* Unpin content by CID
|
|
1967
2103
|
*/
|
|
1968
2104
|
async unpin(cid) {
|
|
1969
|
-
return this.http.delete(`/ipfs/unpin/${
|
|
2105
|
+
return this.http.delete(`/ipfs/unpin/${encodePathParam(cid)}`);
|
|
1970
2106
|
}
|
|
1971
2107
|
/**
|
|
1972
2108
|
* Get a file by CID
|
|
1973
2109
|
*/
|
|
1974
2110
|
async getFile(cid) {
|
|
1975
|
-
return this.http.get(`/ipfs/file/${
|
|
2111
|
+
return this.http.get(`/ipfs/file/${encodePathParam(cid)}`);
|
|
1976
2112
|
}
|
|
1977
2113
|
/**
|
|
1978
2114
|
* Get raw content by CID
|
|
1979
2115
|
*/
|
|
1980
2116
|
async getContent(cid) {
|
|
1981
|
-
return this.http.get(`/ipfs/${
|
|
2117
|
+
return this.http.get(`/ipfs/${encodePathParam(cid)}`);
|
|
1982
2118
|
}
|
|
1983
2119
|
/**
|
|
1984
2120
|
* Get file metadata by CID
|
|
1985
2121
|
*/
|
|
1986
2122
|
async getMetadata(cid) {
|
|
1987
|
-
return this.http.get(`/ipfs/metadata/${
|
|
2123
|
+
return this.http.get(`/ipfs/metadata/${encodePathParam(cid)}`);
|
|
1988
2124
|
}
|
|
1989
2125
|
/**
|
|
1990
2126
|
* List all pinned content
|
|
@@ -2042,7 +2178,7 @@ var HederaTssClient = class {
|
|
|
2042
2178
|
var HederaTransactionsClient = class {
|
|
2043
2179
|
constructor(http, tssHttp) {
|
|
2044
2180
|
this.http = http;
|
|
2045
|
-
this.tss = new HederaTssClient(tssHttp
|
|
2181
|
+
this.tss = new HederaTssClient(tssHttp);
|
|
2046
2182
|
}
|
|
2047
2183
|
http;
|
|
2048
2184
|
/**
|
|
@@ -2053,10 +2189,10 @@ var HederaTransactionsClient = class {
|
|
|
2053
2189
|
* - `client.hedera.tss.createTopic(...)` makes the cluster sign+submit in one call.
|
|
2054
2190
|
*
|
|
2055
2191
|
* `tssHttp` is the validator's `/api/v3`-rooted HTTP client (different from
|
|
2056
|
-
* the `/api/transactions` one this class uses for prepare paths).
|
|
2057
|
-
*
|
|
2058
|
-
*
|
|
2059
|
-
*
|
|
2192
|
+
* the `/api/transactions` one this class uses for prepare paths). Both
|
|
2193
|
+
* clients are required — the previous single-arg fallback to `http` was
|
|
2194
|
+
* unreachable through `SmartEngineClient` (the only call site always
|
|
2195
|
+
* passes both).
|
|
2060
2196
|
*/
|
|
2061
2197
|
tss;
|
|
2062
2198
|
/** Prepare an HCS topic creation transaction. */
|
|
@@ -2237,7 +2373,7 @@ var SnapshotsClient = class {
|
|
|
2237
2373
|
*/
|
|
2238
2374
|
async generate(tokenId, options) {
|
|
2239
2375
|
return this.http.post(
|
|
2240
|
-
`/snapshots/generate/${
|
|
2376
|
+
`/snapshots/generate/${encodePathParam(tokenId)}`,
|
|
2241
2377
|
options || {}
|
|
2242
2378
|
);
|
|
2243
2379
|
}
|
|
@@ -2245,7 +2381,7 @@ var SnapshotsClient = class {
|
|
|
2245
2381
|
* Get snapshot details by ID
|
|
2246
2382
|
*/
|
|
2247
2383
|
async get(snapshotId) {
|
|
2248
|
-
return this.http.get(`/snapshots/${
|
|
2384
|
+
return this.http.get(`/snapshots/${encodePathParam(snapshotId)}`);
|
|
2249
2385
|
}
|
|
2250
2386
|
/**
|
|
2251
2387
|
* List snapshots for a token
|
|
@@ -2256,7 +2392,7 @@ var SnapshotsClient = class {
|
|
|
2256
2392
|
if (pagination?.limit !== void 0) params.set("limit", String(pagination.limit));
|
|
2257
2393
|
const qs = params.toString();
|
|
2258
2394
|
return this.http.get(
|
|
2259
|
-
`/snapshots/token/${
|
|
2395
|
+
`/snapshots/token/${encodePathParam(tokenId)}${qs ? `?${qs}` : ""}`
|
|
2260
2396
|
);
|
|
2261
2397
|
}
|
|
2262
2398
|
/**
|
|
@@ -2268,7 +2404,7 @@ var SnapshotsClient = class {
|
|
|
2268
2404
|
async download(snapshotId, format) {
|
|
2269
2405
|
const params = format ? `?format=${encodeURIComponent(format)}` : "";
|
|
2270
2406
|
return this.http.get(
|
|
2271
|
-
`/snapshots/${
|
|
2407
|
+
`/snapshots/${encodePathParam(snapshotId)}/download${params}`
|
|
2272
2408
|
);
|
|
2273
2409
|
}
|
|
2274
2410
|
};
|
|
@@ -2451,20 +2587,20 @@ var SettlementClient = class {
|
|
|
2451
2587
|
* Get the current status of a settlement by ID.
|
|
2452
2588
|
*/
|
|
2453
2589
|
async getStatus(settlementId) {
|
|
2454
|
-
return this.http.get(`/settlement/${
|
|
2590
|
+
return this.http.get(`/settlement/${encodePathParam(settlementId)}/status`);
|
|
2455
2591
|
}
|
|
2456
2592
|
/**
|
|
2457
2593
|
* Confirm that XRP has landed on the destination address.
|
|
2458
2594
|
* Advances the settlement to the next processing step.
|
|
2459
2595
|
*/
|
|
2460
2596
|
async confirmXrpLanded(settlementId) {
|
|
2461
|
-
return this.http.post(`/settlement/${
|
|
2597
|
+
return this.http.post(`/settlement/${encodePathParam(settlementId)}/confirm-xrp`, {});
|
|
2462
2598
|
}
|
|
2463
2599
|
/**
|
|
2464
2600
|
* Get settlement history for a given entity.
|
|
2465
2601
|
*/
|
|
2466
2602
|
async getHistory(entityId) {
|
|
2467
|
-
return this.http.get(`/settlement/history/${
|
|
2603
|
+
return this.http.get(`/settlement/history/${encodePathParam(entityId)}`);
|
|
2468
2604
|
}
|
|
2469
2605
|
};
|
|
2470
2606
|
|
|
@@ -2507,39 +2643,39 @@ var DaoDashboardClient = class {
|
|
|
2507
2643
|
/** Aggregated dashboard counters for a user's governance home screen. */
|
|
2508
2644
|
async getStats(userAddress) {
|
|
2509
2645
|
return this.http.get(
|
|
2510
|
-
`/dao/dashboard/stats/${
|
|
2646
|
+
`/dao/dashboard/stats/${encodePathParam(userAddress)}`
|
|
2511
2647
|
);
|
|
2512
2648
|
}
|
|
2513
2649
|
/** Active proposals across every DAO the user belongs to, with vote state. */
|
|
2514
2650
|
async getActiveProposals(userAddress) {
|
|
2515
2651
|
return this.http.get(
|
|
2516
|
-
`/dao/dashboard/active-proposals/${
|
|
2652
|
+
`/dao/dashboard/active-proposals/${encodePathParam(userAddress)}`
|
|
2517
2653
|
);
|
|
2518
2654
|
}
|
|
2519
2655
|
/** Paginated vote history across DAOs. */
|
|
2520
2656
|
async getVoteHistory(userAddress, opts = {}) {
|
|
2521
2657
|
const qs = buildQuery({ limit: opts.limit, offset: opts.offset });
|
|
2522
2658
|
return this.http.get(
|
|
2523
|
-
`/dao/dashboard/vote-history/${
|
|
2659
|
+
`/dao/dashboard/vote-history/${encodePathParam(userAddress)}${qs}`
|
|
2524
2660
|
);
|
|
2525
2661
|
}
|
|
2526
2662
|
/** Activity feed (proposal-created/vote-cast/etc.) across user's DAOs. */
|
|
2527
2663
|
async getActivity(userAddress, opts = {}) {
|
|
2528
2664
|
const qs = buildQuery({ limit: opts.limit, daoId: opts.daoId });
|
|
2529
2665
|
return this.http.get(
|
|
2530
|
-
`/dao/dashboard/activity/${
|
|
2666
|
+
`/dao/dashboard/activity/${encodePathParam(userAddress)}${qs}`
|
|
2531
2667
|
);
|
|
2532
2668
|
}
|
|
2533
2669
|
/** Items the user must act on (sign prepared messages, claim NFTs, …). */
|
|
2534
2670
|
async getPendingActions(userAddress) {
|
|
2535
2671
|
return this.http.get(
|
|
2536
|
-
`/dao/dashboard/pending-actions/${
|
|
2672
|
+
`/dao/dashboard/pending-actions/${encodePathParam(userAddress)}`
|
|
2537
2673
|
);
|
|
2538
2674
|
}
|
|
2539
2675
|
/** Governance impact metrics — weight delivered, success rate, streak. */
|
|
2540
2676
|
async getImpact(userAddress) {
|
|
2541
2677
|
return this.http.get(
|
|
2542
|
-
`/dao/dashboard/impact/${
|
|
2678
|
+
`/dao/dashboard/impact/${encodePathParam(userAddress)}`
|
|
2543
2679
|
);
|
|
2544
2680
|
}
|
|
2545
2681
|
};
|
|
@@ -2555,13 +2691,13 @@ function buildQuery2(params) {
|
|
|
2555
2691
|
return qs ? `?${qs}` : "";
|
|
2556
2692
|
}
|
|
2557
2693
|
function encodeDaoId(daoId) {
|
|
2558
|
-
return
|
|
2694
|
+
return encodePathParam(daoId);
|
|
2559
2695
|
}
|
|
2560
2696
|
function encodeProposalId(proposalId) {
|
|
2561
|
-
return
|
|
2697
|
+
return encodePathParam(proposalId);
|
|
2562
2698
|
}
|
|
2563
2699
|
function encodeAddress(address) {
|
|
2564
|
-
return
|
|
2700
|
+
return encodePathParam(address);
|
|
2565
2701
|
}
|
|
2566
2702
|
var DaoClient = class {
|
|
2567
2703
|
constructor(http) {
|
|
@@ -2767,7 +2903,7 @@ var AgentsClient = class {
|
|
|
2767
2903
|
}
|
|
2768
2904
|
/** Get agent details */
|
|
2769
2905
|
async get(agentId) {
|
|
2770
|
-
return this.http.get(`/api/agents/${
|
|
2906
|
+
return this.http.get(`/api/agents/${encodePathParam(agentId)}`);
|
|
2771
2907
|
}
|
|
2772
2908
|
/** List all agents */
|
|
2773
2909
|
async list() {
|
|
@@ -2779,33 +2915,33 @@ var AgentsClient = class {
|
|
|
2779
2915
|
* the caller is expected to sign and submit the prepared bytes.
|
|
2780
2916
|
*/
|
|
2781
2917
|
async fund(agentId, request) {
|
|
2782
|
-
return this.http.post(`/api/agents/${
|
|
2918
|
+
return this.http.post(`/api/agents/${encodePathParam(agentId)}/fund`, request);
|
|
2783
2919
|
}
|
|
2784
2920
|
/**
|
|
2785
2921
|
* Execute a trade (agent-wallet OR owner). Returns a
|
|
2786
2922
|
* `PreparedTransactionResponse` wrapped in a `success: true` envelope.
|
|
2787
2923
|
*/
|
|
2788
2924
|
async trade(agentId, request) {
|
|
2789
|
-
return this.http.post(`/api/agents/${
|
|
2925
|
+
return this.http.post(`/api/agents/${encodePathParam(agentId)}/trade`, request);
|
|
2790
2926
|
}
|
|
2791
2927
|
/**
|
|
2792
2928
|
* Withdraw from agent treasury (owner-only). Returns a
|
|
2793
2929
|
* `PreparedTransactionResponse` wrapped in a `success: true` envelope.
|
|
2794
2930
|
*/
|
|
2795
2931
|
async withdraw(agentId, request) {
|
|
2796
|
-
return this.http.post(`/api/agents/${
|
|
2932
|
+
return this.http.post(`/api/agents/${encodePathParam(agentId)}/withdraw`, request);
|
|
2797
2933
|
}
|
|
2798
2934
|
/** Pause an agent */
|
|
2799
2935
|
async pause(agentId) {
|
|
2800
|
-
return this.http.post(`/api/agents/${
|
|
2936
|
+
return this.http.post(`/api/agents/${encodePathParam(agentId)}/pause`, {});
|
|
2801
2937
|
}
|
|
2802
2938
|
/** Resume a paused agent */
|
|
2803
2939
|
async resume(agentId) {
|
|
2804
|
-
return this.http.post(`/api/agents/${
|
|
2940
|
+
return this.http.post(`/api/agents/${encodePathParam(agentId)}/resume`, {});
|
|
2805
2941
|
}
|
|
2806
2942
|
/** Revoke an agent (permanent) */
|
|
2807
2943
|
async revoke(agentId) {
|
|
2808
|
-
return this.http.post(`/api/agents/${
|
|
2944
|
+
return this.http.post(`/api/agents/${encodePathParam(agentId)}/revoke`, {});
|
|
2809
2945
|
}
|
|
2810
2946
|
/**
|
|
2811
2947
|
* Update agent rules.
|
|
@@ -2816,23 +2952,23 @@ var AgentsClient = class {
|
|
|
2816
2952
|
* the verb mismatch.
|
|
2817
2953
|
*/
|
|
2818
2954
|
async updateRules(agentId, rules) {
|
|
2819
|
-
return this.http.patch(`/api/agents/${
|
|
2955
|
+
return this.http.patch(`/api/agents/${encodePathParam(agentId)}/rules`, rules);
|
|
2820
2956
|
}
|
|
2821
2957
|
/** Get agent events */
|
|
2822
2958
|
async getEvents(agentId) {
|
|
2823
|
-
return this.http.get(`/api/agents/${
|
|
2959
|
+
return this.http.get(`/api/agents/${encodePathParam(agentId)}/events`);
|
|
2824
2960
|
}
|
|
2825
2961
|
/** Get agent balances across chains */
|
|
2826
2962
|
async getBalances(agentId) {
|
|
2827
|
-
return this.http.get(`/api/agents/${
|
|
2963
|
+
return this.http.get(`/api/agents/${encodePathParam(agentId)}/balances`);
|
|
2828
2964
|
}
|
|
2829
2965
|
/** Approve a pending agent operation */
|
|
2830
2966
|
async approve(agentId, operationId) {
|
|
2831
|
-
return this.http.post(`/api/agents/${
|
|
2967
|
+
return this.http.post(`/api/agents/${encodePathParam(agentId)}/approve/${encodePathParam(operationId)}`, {});
|
|
2832
2968
|
}
|
|
2833
2969
|
/** Reject a pending agent operation */
|
|
2834
2970
|
async reject(agentId, operationId) {
|
|
2835
|
-
return this.http.post(`/api/agents/${
|
|
2971
|
+
return this.http.post(`/api/agents/${encodePathParam(agentId)}/reject/${encodePathParam(operationId)}`, {});
|
|
2836
2972
|
}
|
|
2837
2973
|
};
|
|
2838
2974
|
|
|
@@ -2871,7 +3007,7 @@ var DeploymentClient = class {
|
|
|
2871
3007
|
*/
|
|
2872
3008
|
async uploadFrontend(appId, bundle, filename = "bundle.tar.gz") {
|
|
2873
3009
|
return this.http.upload(
|
|
2874
|
-
`/api/deployment/apps/${
|
|
3010
|
+
`/api/deployment/apps/${encodePathParam(appId)}/frontend`,
|
|
2875
3011
|
bundle,
|
|
2876
3012
|
filename,
|
|
2877
3013
|
void 0,
|
|
@@ -2885,20 +3021,20 @@ var DeploymentClient = class {
|
|
|
2885
3021
|
* until `runtime.runtimeState === 'RUNNING'` for the URL to be live.
|
|
2886
3022
|
*/
|
|
2887
3023
|
async deploy(appId, request) {
|
|
2888
|
-
return this.http.post(`/api/deployment/apps/${
|
|
3024
|
+
return this.http.post(`/api/deployment/apps/${encodePathParam(appId)}/deploy`, request);
|
|
2889
3025
|
}
|
|
2890
3026
|
/**
|
|
2891
3027
|
* Roll back to a previously-deployed image tag (must exist in
|
|
2892
3028
|
* `runtime.deploymentHistory[]`).
|
|
2893
3029
|
*/
|
|
2894
3030
|
async rollback(appId, request) {
|
|
2895
|
-
return this.http.post(`/api/deployment/apps/${
|
|
3031
|
+
return this.http.post(`/api/deployment/apps/${encodePathParam(appId)}/rollback`, request);
|
|
2896
3032
|
}
|
|
2897
3033
|
/**
|
|
2898
3034
|
* Live combined lifecycle + runtime status of an app.
|
|
2899
3035
|
*/
|
|
2900
3036
|
async status(appId) {
|
|
2901
|
-
return this.http.get(`/api/deployment/apps/${
|
|
3037
|
+
return this.http.get(`/api/deployment/apps/${encodePathParam(appId)}/status`);
|
|
2902
3038
|
}
|
|
2903
3039
|
/**
|
|
2904
3040
|
* List all deployed apps for the authenticated developer.
|
|
@@ -2910,31 +3046,35 @@ var DeploymentClient = class {
|
|
|
2910
3046
|
* Get app details.
|
|
2911
3047
|
*/
|
|
2912
3048
|
async get(appId) {
|
|
2913
|
-
return this.http.get(`/api/deployment/apps/${
|
|
3049
|
+
return this.http.get(`/api/deployment/apps/${encodePathParam(appId)}`);
|
|
2914
3050
|
}
|
|
2915
3051
|
/**
|
|
2916
|
-
* Update app configuration.
|
|
3052
|
+
* Update app configuration.
|
|
3053
|
+
*
|
|
3054
|
+
* @param appId - The app to update.
|
|
3055
|
+
* @param updates - Partial deploy-request fields to apply.
|
|
3056
|
+
* @returns The updated app info.
|
|
2917
3057
|
*/
|
|
2918
3058
|
async update(appId, updates) {
|
|
2919
|
-
return this.http.put(`/api/deployment/apps/${
|
|
3059
|
+
return this.http.put(`/api/deployment/apps/${encodePathParam(appId)}`, updates);
|
|
2920
3060
|
}
|
|
2921
3061
|
/**
|
|
2922
|
-
* Delete an app
|
|
3062
|
+
* Delete an app (runtime effect: namespace teardown).
|
|
2923
3063
|
*/
|
|
2924
3064
|
async delete(appId) {
|
|
2925
|
-
return this.http.delete(`/api/deployment/apps/${
|
|
3065
|
+
return this.http.delete(`/api/deployment/apps/${encodePathParam(appId)}`);
|
|
2926
3066
|
}
|
|
2927
3067
|
/**
|
|
2928
|
-
* Suspend an app
|
|
3068
|
+
* Suspend an app (runtime effect: scale to zero).
|
|
2929
3069
|
*/
|
|
2930
3070
|
async suspend(appId) {
|
|
2931
|
-
return this.http.post(`/api/deployment/apps/${
|
|
3071
|
+
return this.http.post(`/api/deployment/apps/${encodePathParam(appId)}/suspend`, {});
|
|
2932
3072
|
}
|
|
2933
3073
|
/**
|
|
2934
|
-
* Resume a suspended app
|
|
3074
|
+
* Resume a suspended app (runtime effect: scale back up).
|
|
2935
3075
|
*/
|
|
2936
3076
|
async resume(appId) {
|
|
2937
|
-
return this.http.post(`/api/deployment/apps/${
|
|
3077
|
+
return this.http.post(`/api/deployment/apps/${encodePathParam(appId)}/resume`, {});
|
|
2938
3078
|
}
|
|
2939
3079
|
/**
|
|
2940
3080
|
* Get deployment statistics.
|
|
@@ -2961,7 +3101,7 @@ var DeploymentClient = class {
|
|
|
2961
3101
|
* CGNAT / cloud metadata destinations (SSRF guard).
|
|
2962
3102
|
*/
|
|
2963
3103
|
async setWebhook(appId, webhookUrl) {
|
|
2964
|
-
return this.http.put(`/api/deployment/apps/${
|
|
3104
|
+
return this.http.put(`/api/deployment/apps/${encodePathParam(appId)}/webhook`, {
|
|
2965
3105
|
webhookUrl
|
|
2966
3106
|
});
|
|
2967
3107
|
}
|
|
@@ -2977,10 +3117,10 @@ var DeploymentClient = class {
|
|
|
2977
3117
|
* exposition format.
|
|
2978
3118
|
*/
|
|
2979
3119
|
async getMetrics(appId) {
|
|
2980
|
-
return this.http.getText(`/api/deployment/apps/${
|
|
3120
|
+
return this.http.getText(`/api/deployment/apps/${encodePathParam(appId)}/metrics`);
|
|
2981
3121
|
}
|
|
2982
3122
|
/**
|
|
2983
|
-
* Rotate the smart-app's tenant-secret KEK
|
|
3123
|
+
* Rotate the smart-app's tenant-secret KEK.
|
|
2984
3124
|
*
|
|
2985
3125
|
* Re-encrypts every `runtime.env` envelope at the new KEK version
|
|
2986
3126
|
* transparently. Previous versions remain valid until explicitly
|
|
@@ -2988,12 +3128,12 @@ var DeploymentClient = class {
|
|
|
2988
3128
|
*/
|
|
2989
3129
|
async rotateKek(appId) {
|
|
2990
3130
|
return this.http.post(
|
|
2991
|
-
`/api/deployment/apps/${
|
|
3131
|
+
`/api/deployment/apps/${encodePathParam(appId)}/credentials/rotate-kek`,
|
|
2992
3132
|
{}
|
|
2993
3133
|
);
|
|
2994
3134
|
}
|
|
2995
3135
|
/**
|
|
2996
|
-
* Revoke a tenant-secret KEK version (
|
|
3136
|
+
* Revoke a tenant-secret KEK version (emergency burn).
|
|
2997
3137
|
*
|
|
2998
3138
|
* Envelopes at the revoked version become operationally dead —
|
|
2999
3139
|
* decryption inside the smart-app pod fails. Owner-only and
|
|
@@ -3002,7 +3142,7 @@ var DeploymentClient = class {
|
|
|
3002
3142
|
*/
|
|
3003
3143
|
async revokeKek(appId, version) {
|
|
3004
3144
|
return this.http.post(
|
|
3005
|
-
`/api/deployment/apps/${
|
|
3145
|
+
`/api/deployment/apps/${encodePathParam(appId)}/credentials/revoke-kek`,
|
|
3006
3146
|
{ version }
|
|
3007
3147
|
);
|
|
3008
3148
|
}
|
|
@@ -3182,16 +3322,6 @@ var TokensClient = class {
|
|
|
3182
3322
|
async getMigrationsForToken(tokenId) {
|
|
3183
3323
|
return this.http.get(`/tokens/${encodePathParam(tokenId)}/migrations`);
|
|
3184
3324
|
}
|
|
3185
|
-
/**
|
|
3186
|
-
* Get token details. NOTE: collides with `client.getTokenInfo(...)` —
|
|
3187
|
-
* see the class JSDoc above for the route-order details. Prefer
|
|
3188
|
-
* `client.getTokenInfo(...)` unless you have a reason to call this one.
|
|
3189
|
-
*/
|
|
3190
|
-
async getDetails(chain, tokenId) {
|
|
3191
|
-
return this.http.get(
|
|
3192
|
-
`/tokens/${encodePathParam(chain)}/${encodePathParam(tokenId)}`
|
|
3193
|
-
);
|
|
3194
|
-
}
|
|
3195
3325
|
};
|
|
3196
3326
|
|
|
3197
3327
|
// src/operator/operator-client.ts
|
|
@@ -3226,6 +3356,8 @@ var SmartEngineClient = class _SmartEngineClient {
|
|
|
3226
3356
|
// ========== Sub-Clients ==========
|
|
3227
3357
|
/** Application subscription management */
|
|
3228
3358
|
subscription;
|
|
3359
|
+
/** Testnet HST faucet (challenge -> sign -> dispense) */
|
|
3360
|
+
faucet;
|
|
3229
3361
|
/** Threshold Signature Scheme — chain-agnostic MPC operations */
|
|
3230
3362
|
tss;
|
|
3231
3363
|
/** IPFS decentralized file storage */
|
|
@@ -3284,6 +3416,7 @@ var SmartEngineClient = class _SmartEngineClient {
|
|
|
3284
3416
|
timeout: config.timeout
|
|
3285
3417
|
});
|
|
3286
3418
|
this.subscription = new SubscriptionClient(this.http);
|
|
3419
|
+
this.faucet = new FaucetClient(this.http);
|
|
3287
3420
|
this.tss = new TSSClient(this.http);
|
|
3288
3421
|
this.ipfs = new IPFSClient(this.http);
|
|
3289
3422
|
this.transactions = new TransactionsClient(this.txHttp);
|
|
@@ -3339,13 +3472,17 @@ var SmartEngineClient = class _SmartEngineClient {
|
|
|
3339
3472
|
});
|
|
3340
3473
|
}
|
|
3341
3474
|
/**
|
|
3342
|
-
* Connect to the smart-engines network with auto-discovery and authentication
|
|
3475
|
+
* Connect to the smart-engines network with auto-discovery and authentication.
|
|
3343
3476
|
*
|
|
3344
|
-
*
|
|
3345
|
-
* 1. Discovers validators via HCS registry topic
|
|
3346
|
-
* 2. Selects a random validator with API endpoint
|
|
3347
|
-
* 3. Authenticates with Web3-style challenge-response
|
|
3348
|
-
* 4. Returns a configured client ready to use
|
|
3477
|
+
* Steps:
|
|
3478
|
+
* 1. Discovers validators via the HCS registry topic.
|
|
3479
|
+
* 2. Selects a random validator with an API endpoint.
|
|
3480
|
+
* 3. Authenticates with Web3-style challenge-response.
|
|
3481
|
+
* 4. Returns a configured client ready to use.
|
|
3482
|
+
*
|
|
3483
|
+
* @param config - Network, registry topic, and auth signer config.
|
|
3484
|
+
* @returns The configured client, the chosen validator, and the auth session.
|
|
3485
|
+
* @throws SmartEngineError 503 if no validator with an API endpoint is found.
|
|
3349
3486
|
*/
|
|
3350
3487
|
static async connectToNetwork(config) {
|
|
3351
3488
|
const allowInsecure = config.allowInsecure ?? false;
|
|
@@ -3382,18 +3519,22 @@ var SmartEngineClient = class _SmartEngineClient {
|
|
|
3382
3519
|
return { client, validator, session };
|
|
3383
3520
|
}
|
|
3384
3521
|
/**
|
|
3385
|
-
* Connect to the smart-engines network via the **service-registry
|
|
3386
|
-
*
|
|
3387
|
-
*
|
|
3388
|
-
*
|
|
3389
|
-
*
|
|
3390
|
-
* without code edits.
|
|
3522
|
+
* Connect to the smart-engines network via the **service-registry**.
|
|
3523
|
+
* Preferred over {@link connectToNetwork} once the validator pods in the
|
|
3524
|
+
* target network have published their cluster endpoints — the SDK
|
|
3525
|
+
* auto-balances across the active cluster set and rides permissionless
|
|
3526
|
+
* cluster join/leave without code edits.
|
|
3391
3527
|
*
|
|
3392
|
-
*
|
|
3528
|
+
* Resolution ladder:
|
|
3393
3529
|
* 1. HTTP fetch `/api/v3/discovery/clusters` from each bootstrap seed.
|
|
3394
3530
|
* 2. (Optional) HCS trust-anchor membership cross-check.
|
|
3395
3531
|
* 3. Random-pick over the verified set.
|
|
3396
3532
|
*
|
|
3533
|
+
* @param config - Seed + auth config. See {@link ClusterConnectionConfig}.
|
|
3534
|
+
* @returns The configured client, the selected cluster, and the auth session.
|
|
3535
|
+
* @throws SmartEngineError 400 if neither `bootstrap` nor `network` is given.
|
|
3536
|
+
* @throws SmartEngineError 503 if no active cluster can be reached.
|
|
3537
|
+
*
|
|
3397
3538
|
* @example Zero-config (recommended for smart-app callers)
|
|
3398
3539
|
* ```ts
|
|
3399
3540
|
* const { client, cluster, session } = await SmartEngineClient.connectToCluster({
|
|
@@ -3418,30 +3559,25 @@ var SmartEngineClient = class _SmartEngineClient {
|
|
|
3418
3559
|
*/
|
|
3419
3560
|
static async connectToCluster(config) {
|
|
3420
3561
|
const allowInsecure = config.allowInsecure ?? false;
|
|
3421
|
-
const
|
|
3422
|
-
|
|
3423
|
-
|
|
3424
|
-
"connectToCluster requires either a non-empty `bootstrap` list or a known `network` name.",
|
|
3425
|
-
400
|
|
3426
|
-
);
|
|
3427
|
-
}
|
|
3428
|
-
const discovery = new ClusterDiscoveryClient({
|
|
3429
|
-
bootstrap,
|
|
3562
|
+
const resolved = await resolveClusterEndpoint({
|
|
3563
|
+
bootstrap: config.bootstrap,
|
|
3564
|
+
network: config.network,
|
|
3430
3565
|
allowInsecure,
|
|
3431
|
-
trustAnchor: config.trustAnchor
|
|
3432
|
-
network: config.trustAnchor.network,
|
|
3433
|
-
registryTopicId: config.trustAnchor.registryTopicId,
|
|
3434
|
-
mirrorNodeUrl: config.trustAnchor.mirrorNodeUrl,
|
|
3435
|
-
allowInsecure
|
|
3436
|
-
} : void 0
|
|
3566
|
+
trustAnchor: config.trustAnchor
|
|
3437
3567
|
});
|
|
3438
|
-
|
|
3439
|
-
|
|
3568
|
+
if (!resolved.ok) {
|
|
3569
|
+
if (resolved.reason === "no-seeds") {
|
|
3570
|
+
throw new SmartEngineError(
|
|
3571
|
+
"connectToCluster requires either a non-empty `bootstrap` list or a known `network` name.",
|
|
3572
|
+
400
|
|
3573
|
+
);
|
|
3574
|
+
}
|
|
3440
3575
|
throw new SmartEngineError(
|
|
3441
3576
|
"No active clusters available via bootstrap seeds. Check bootstrap URLs and network reachability.",
|
|
3442
3577
|
503
|
|
3443
3578
|
);
|
|
3444
3579
|
}
|
|
3580
|
+
const cluster = resolved.cluster;
|
|
3445
3581
|
const gatewayUrl = cluster.endpoints.gatewayUrl;
|
|
3446
3582
|
validateClientUrl(gatewayUrl, allowInsecure);
|
|
3447
3583
|
const auth = new ValidatorAuthClient({ security: { allowInsecure } });
|
|
@@ -3466,7 +3602,7 @@ var SmartEngineClient = class _SmartEngineClient {
|
|
|
3466
3602
|
}
|
|
3467
3603
|
/** Check if client has an auth token */
|
|
3468
3604
|
isAuthenticated() {
|
|
3469
|
-
return
|
|
3605
|
+
return this.http.getAuthToken() !== void 0;
|
|
3470
3606
|
}
|
|
3471
3607
|
/**
|
|
3472
3608
|
* Get HTTP resilience health information
|
|
@@ -3527,17 +3663,11 @@ var SmartEngineClient = class _SmartEngineClient {
|
|
|
3527
3663
|
return this.http.post("/tokens/mint", validated);
|
|
3528
3664
|
}
|
|
3529
3665
|
/**
|
|
3530
|
-
* Get token information.
|
|
3666
|
+
* Get token information for a token on the given chain.
|
|
3531
3667
|
*
|
|
3532
|
-
*
|
|
3533
|
-
*
|
|
3534
|
-
*
|
|
3535
|
-
* `TokenMigrationController` at
|
|
3536
|
-
* `apps/smart-validator/src/token-migration/token-migration.controller.ts:173`.
|
|
3537
|
-
* Nest resolves routes in `controllers: [...]` order — `ValidatorController`
|
|
3538
|
-
* is registered first (`apps/smart-validator/src/smart-validator.module.ts:1222`),
|
|
3539
|
-
* so `multiChain.getTokenInfo(chain, tokenId)` wins and the
|
|
3540
|
-
* token-migration handler is unreachable via this path.
|
|
3668
|
+
* @param chain - Chain identifier (e.g. `'hedera'`, `'xrpl'`).
|
|
3669
|
+
* @param tokenId - Chain-native token identifier.
|
|
3670
|
+
* @returns Token metadata and supply information.
|
|
3541
3671
|
*/
|
|
3542
3672
|
async getTokenInfo(chain, tokenId) {
|
|
3543
3673
|
return this.http.get(`/tokens/${encodePathParam(chain)}/${encodePathParam(tokenId)}`);
|
|
@@ -3697,7 +3827,7 @@ var RoutingClient = class {
|
|
|
3697
3827
|
}
|
|
3698
3828
|
/** Unregister a host. */
|
|
3699
3829
|
async unregisterHost(hostId) {
|
|
3700
|
-
return this.http.delete(`/routing/hosts/${
|
|
3830
|
+
return this.http.delete(`/routing/hosts/${encodePathParam(hostId)}`);
|
|
3701
3831
|
}
|
|
3702
3832
|
/** Get all registered hosts. */
|
|
3703
3833
|
async getAllHosts() {
|
|
@@ -3709,19 +3839,19 @@ var RoutingClient = class {
|
|
|
3709
3839
|
}
|
|
3710
3840
|
/** Get a specific host by ID. */
|
|
3711
3841
|
async getHost(hostId) {
|
|
3712
|
-
return this.http.get(`/routing/hosts/${
|
|
3842
|
+
return this.http.get(`/routing/hosts/${encodePathParam(hostId)}`);
|
|
3713
3843
|
}
|
|
3714
3844
|
/** Trigger host re-verification. */
|
|
3715
3845
|
async verifyHost(hostId) {
|
|
3716
|
-
return this.http.post(`/routing/hosts/${
|
|
3846
|
+
return this.http.post(`/routing/hosts/${encodePathParam(hostId)}/verify`, {});
|
|
3717
3847
|
}
|
|
3718
3848
|
/** Set routing configuration for an app. */
|
|
3719
3849
|
async setRoutingConfig(appId, config) {
|
|
3720
|
-
return this.http.put(`/routing/config/${
|
|
3850
|
+
return this.http.put(`/routing/config/${encodePathParam(appId)}`, config);
|
|
3721
3851
|
}
|
|
3722
3852
|
/** Get routing configuration for an app. */
|
|
3723
3853
|
async getRoutingConfig(appId) {
|
|
3724
|
-
return this.http.get(`/routing/config/${
|
|
3854
|
+
return this.http.get(`/routing/config/${encodePathParam(appId)}`);
|
|
3725
3855
|
}
|
|
3726
3856
|
/** Proxy a request through the gateway. */
|
|
3727
3857
|
async proxyRequest(request) {
|
|
@@ -3737,7 +3867,7 @@ var RoutingClient = class {
|
|
|
3737
3867
|
* field; treat `appId` as the success signal.
|
|
3738
3868
|
*/
|
|
3739
3869
|
async mapDomainToApp(domain, appId) {
|
|
3740
|
-
return this.http.post(`/routing/domains/${
|
|
3870
|
+
return this.http.post(`/routing/domains/${encodePathParam(domain)}/map`, { appId });
|
|
3741
3871
|
}
|
|
3742
3872
|
};
|
|
3743
3873
|
|
|
@@ -3753,11 +3883,11 @@ var DomainsClient = class {
|
|
|
3753
3883
|
}
|
|
3754
3884
|
/** Check domain availability */
|
|
3755
3885
|
async checkAvailability(domain) {
|
|
3756
|
-
return this.http.get(`/domains/check/${
|
|
3886
|
+
return this.http.get(`/domains/check/${encodePathParam(domain)}`);
|
|
3757
3887
|
}
|
|
3758
3888
|
/** Get domain information */
|
|
3759
3889
|
async getInfo(domain) {
|
|
3760
|
-
return this.http.get(`/domains/${
|
|
3890
|
+
return this.http.get(`/domains/${encodePathParam(domain)}`);
|
|
3761
3891
|
}
|
|
3762
3892
|
/** List domains, optionally filtered by owner */
|
|
3763
3893
|
async list(owner) {
|
|
@@ -3766,51 +3896,50 @@ var DomainsClient = class {
|
|
|
3766
3896
|
}
|
|
3767
3897
|
/**
|
|
3768
3898
|
* Generate a verification token. Server accepts one of `dns-txt`,
|
|
3769
|
-
* `dns-cname`, `http-file`, `email
|
|
3770
|
-
* `apps/smart-gateway/src/domains/domains.controller.ts:226-234`).
|
|
3899
|
+
* `dns-cname`, `http-file`, `email`.
|
|
3771
3900
|
*/
|
|
3772
3901
|
async generateVerificationToken(domain, method) {
|
|
3773
|
-
return this.http.post(`/domains/${
|
|
3902
|
+
return this.http.post(`/domains/${encodePathParam(domain)}/verification`, { method });
|
|
3774
3903
|
}
|
|
3775
3904
|
/** Verify domain ownership */
|
|
3776
3905
|
async verifyOwnership(domain, token) {
|
|
3777
|
-
return this.http.post(`/domains/${
|
|
3906
|
+
return this.http.post(`/domains/${encodePathParam(domain)}/verify`, { token });
|
|
3778
3907
|
}
|
|
3779
3908
|
/** Configure DNS records for a domain */
|
|
3780
3909
|
async configureDns(domain, records) {
|
|
3781
|
-
return this.http.post(`/domains/${
|
|
3910
|
+
return this.http.post(`/domains/${encodePathParam(domain)}/dns`, { records });
|
|
3782
3911
|
}
|
|
3783
3912
|
/** Enable DNSSEC for a domain */
|
|
3784
3913
|
async enableDnssec(domain) {
|
|
3785
|
-
return this.http.post(`/domains/${
|
|
3914
|
+
return this.http.post(`/domains/${encodePathParam(domain)}/dnssec/enable`, {});
|
|
3786
3915
|
}
|
|
3787
3916
|
/** Disable DNSSEC for a domain */
|
|
3788
3917
|
async disableDnssec(domain) {
|
|
3789
|
-
return this.http.post(`/domains/${
|
|
3918
|
+
return this.http.post(`/domains/${encodePathParam(domain)}/dnssec/disable`, {});
|
|
3790
3919
|
}
|
|
3791
3920
|
/** Renew a domain */
|
|
3792
3921
|
async renew(domain, years) {
|
|
3793
|
-
return this.http.post(`/domains/${
|
|
3922
|
+
return this.http.post(`/domains/${encodePathParam(domain)}/renew`, { years: years ?? 1 });
|
|
3794
3923
|
}
|
|
3795
3924
|
/** Initiate a domain transfer */
|
|
3796
3925
|
async transfer(domain, request) {
|
|
3797
|
-
return this.http.post(`/domains/${
|
|
3926
|
+
return this.http.post(`/domains/${encodePathParam(domain)}/transfer`, request);
|
|
3798
3927
|
}
|
|
3799
3928
|
/** Approve a pending domain transfer */
|
|
3800
3929
|
async approveTransfer(domain) {
|
|
3801
|
-
return this.http.post(`/domains/${
|
|
3930
|
+
return this.http.post(`/domains/${encodePathParam(domain)}/transfer/approve`, {});
|
|
3802
3931
|
}
|
|
3803
3932
|
/** Reject a pending domain transfer */
|
|
3804
3933
|
async rejectTransfer(domain) {
|
|
3805
|
-
return this.http.post(`/domains/${
|
|
3934
|
+
return this.http.post(`/domains/${encodePathParam(domain)}/transfer/reject`, {});
|
|
3806
3935
|
}
|
|
3807
3936
|
/** Suspend a domain */
|
|
3808
3937
|
async suspend(domain, reason) {
|
|
3809
|
-
return this.http.post(`/domains/${
|
|
3938
|
+
return this.http.post(`/domains/${encodePathParam(domain)}/suspend`, { reason });
|
|
3810
3939
|
}
|
|
3811
3940
|
/** Unsuspend a domain */
|
|
3812
3941
|
async unsuspend(domain) {
|
|
3813
|
-
return this.http.post(`/domains/${
|
|
3942
|
+
return this.http.post(`/domains/${encodePathParam(domain)}/unsuspend`, {});
|
|
3814
3943
|
}
|
|
3815
3944
|
};
|
|
3816
3945
|
|
|
@@ -3837,7 +3966,7 @@ var DnsClient = class {
|
|
|
3837
3966
|
}
|
|
3838
3967
|
/** Get a specific zone */
|
|
3839
3968
|
async getZone(zoneName) {
|
|
3840
|
-
return this.http.get(`/dns/zones/${
|
|
3969
|
+
return this.http.get(`/dns/zones/${encodePathParam(zoneName)}`);
|
|
3841
3970
|
}
|
|
3842
3971
|
/** Create a new DNS zone */
|
|
3843
3972
|
async createZone(request) {
|
|
@@ -3845,38 +3974,38 @@ var DnsClient = class {
|
|
|
3845
3974
|
}
|
|
3846
3975
|
/** Delete a DNS zone */
|
|
3847
3976
|
async deleteZone(zoneName) {
|
|
3848
|
-
return this.http.delete(`/dns/zones/${
|
|
3977
|
+
return this.http.delete(`/dns/zones/${encodePathParam(zoneName)}`);
|
|
3849
3978
|
}
|
|
3850
3979
|
/** Add a record to a zone */
|
|
3851
3980
|
async addRecord(zoneName, record) {
|
|
3852
|
-
return this.http.post(`/dns/zones/${
|
|
3981
|
+
return this.http.post(`/dns/zones/${encodePathParam(zoneName)}/records`, record);
|
|
3853
3982
|
}
|
|
3854
3983
|
/** Update a record in a zone */
|
|
3855
3984
|
async updateRecord(zoneName, recordId, updates) {
|
|
3856
3985
|
return this.http.put(
|
|
3857
|
-
`/dns/zones/${
|
|
3986
|
+
`/dns/zones/${encodePathParam(zoneName)}/records/${encodePathParam(recordId)}`,
|
|
3858
3987
|
updates
|
|
3859
3988
|
);
|
|
3860
3989
|
}
|
|
3861
3990
|
/** Delete a record from a zone */
|
|
3862
3991
|
async deleteRecord(zoneName, recordId) {
|
|
3863
3992
|
return this.http.delete(
|
|
3864
|
-
`/dns/zones/${
|
|
3993
|
+
`/dns/zones/${encodePathParam(zoneName)}/records/${encodePathParam(recordId)}`
|
|
3865
3994
|
);
|
|
3866
3995
|
}
|
|
3867
3996
|
/** Generate DNSSEC keys for a zone */
|
|
3868
3997
|
async generateDnssecKeys(zoneName, algorithm) {
|
|
3869
|
-
return this.http.post(`/dns/zones/${
|
|
3998
|
+
return this.http.post(`/dns/zones/${encodePathParam(zoneName)}/dnssec/keys`, {
|
|
3870
3999
|
algorithm
|
|
3871
4000
|
});
|
|
3872
4001
|
}
|
|
3873
4002
|
/** Get DNSSEC keys for a zone */
|
|
3874
4003
|
async getDnssecKeys(zoneName) {
|
|
3875
|
-
return this.http.get(`/dns/zones/${
|
|
4004
|
+
return this.http.get(`/dns/zones/${encodePathParam(zoneName)}/dnssec/keys`);
|
|
3876
4005
|
}
|
|
3877
4006
|
/** Get DS record for a zone (for registrar configuration) */
|
|
3878
4007
|
async getDsRecord(zoneName) {
|
|
3879
|
-
return this.http.get(`/dns/zones/${
|
|
4008
|
+
return this.http.get(`/dns/zones/${encodePathParam(zoneName)}/dnssec/ds`);
|
|
3880
4009
|
}
|
|
3881
4010
|
/** Clear DNS cache */
|
|
3882
4011
|
async clearCache() {
|
|
@@ -3891,10 +4020,8 @@ var HealthClient = class {
|
|
|
3891
4020
|
}
|
|
3892
4021
|
http;
|
|
3893
4022
|
/**
|
|
3894
|
-
* Per-cluster aggregate health probe. Wraps
|
|
3895
|
-
*
|
|
3896
|
-
* `apps/smart-gateway/src/health/health.controller.ts:213-263`. Returns
|
|
3897
|
-
* local validator + host + genesis state in a single payload.
|
|
4023
|
+
* Per-cluster aggregate health probe. Wraps `GET /api/v3/cluster/health`.
|
|
4024
|
+
* Returns local validator + host + genesis state in a single payload.
|
|
3898
4025
|
*/
|
|
3899
4026
|
async getCluster() {
|
|
3900
4027
|
return this.http.get("/cluster/health");
|
|
@@ -3977,7 +4104,7 @@ var DatabaseClient = class {
|
|
|
3977
4104
|
async insert(collection, document) {
|
|
3978
4105
|
const appId = this.getAppId();
|
|
3979
4106
|
return this.http.post(
|
|
3980
|
-
`/api/db/${
|
|
4107
|
+
`/api/db/${encodePathParam(appId)}/${encodePathParam(collection)}`,
|
|
3981
4108
|
document
|
|
3982
4109
|
);
|
|
3983
4110
|
}
|
|
@@ -3995,7 +4122,7 @@ var DatabaseClient = class {
|
|
|
3995
4122
|
if (options?.sort) params.set("sort", options.sort);
|
|
3996
4123
|
const qs = params.toString();
|
|
3997
4124
|
return this.http.get(
|
|
3998
|
-
`/api/db/${
|
|
4125
|
+
`/api/db/${encodePathParam(appId)}/${encodePathParam(collection)}${qs ? `?${qs}` : ""}`
|
|
3999
4126
|
);
|
|
4000
4127
|
}
|
|
4001
4128
|
/**
|
|
@@ -4004,7 +4131,7 @@ var DatabaseClient = class {
|
|
|
4004
4131
|
async update(collection, documentId, updates) {
|
|
4005
4132
|
const appId = this.getAppId();
|
|
4006
4133
|
return this.http.put(
|
|
4007
|
-
`/api/db/${
|
|
4134
|
+
`/api/db/${encodePathParam(appId)}/${encodePathParam(collection)}/${encodePathParam(documentId)}`,
|
|
4008
4135
|
updates
|
|
4009
4136
|
);
|
|
4010
4137
|
}
|
|
@@ -4014,7 +4141,7 @@ var DatabaseClient = class {
|
|
|
4014
4141
|
async delete(collection, documentId) {
|
|
4015
4142
|
const appId = this.getAppId();
|
|
4016
4143
|
return this.http.delete(
|
|
4017
|
-
`/api/db/${
|
|
4144
|
+
`/api/db/${encodePathParam(appId)}/${encodePathParam(collection)}/${encodePathParam(documentId)}`
|
|
4018
4145
|
);
|
|
4019
4146
|
}
|
|
4020
4147
|
/**
|
|
@@ -4026,7 +4153,7 @@ var DatabaseClient = class {
|
|
|
4026
4153
|
*/
|
|
4027
4154
|
async listCollections() {
|
|
4028
4155
|
const appId = this.getAppId();
|
|
4029
|
-
return this.http.get(`/api/db/${
|
|
4156
|
+
return this.http.get(`/api/db/${encodePathParam(appId)}/collections`);
|
|
4030
4157
|
}
|
|
4031
4158
|
/**
|
|
4032
4159
|
* Create a new collection in the database.
|
|
@@ -4036,7 +4163,7 @@ var DatabaseClient = class {
|
|
|
4036
4163
|
*/
|
|
4037
4164
|
async createCollection(name) {
|
|
4038
4165
|
const appId = this.getAppId();
|
|
4039
|
-
return this.http.post(`/api/db/${
|
|
4166
|
+
return this.http.post(`/api/db/${encodePathParam(appId)}/collections`, { name });
|
|
4040
4167
|
}
|
|
4041
4168
|
/**
|
|
4042
4169
|
* Drop a collection and all its documents.
|
|
@@ -4047,7 +4174,7 @@ var DatabaseClient = class {
|
|
|
4047
4174
|
async dropCollection(name) {
|
|
4048
4175
|
const appId = this.getAppId();
|
|
4049
4176
|
return this.http.delete(
|
|
4050
|
-
`/api/db/${
|
|
4177
|
+
`/api/db/${encodePathParam(appId)}/collections/${encodePathParam(name)}`
|
|
4051
4178
|
);
|
|
4052
4179
|
}
|
|
4053
4180
|
// ========== State Proofs ==========
|
|
@@ -4056,7 +4183,7 @@ var DatabaseClient = class {
|
|
|
4056
4183
|
*/
|
|
4057
4184
|
async getStateRoot() {
|
|
4058
4185
|
const appId = this.getAppId();
|
|
4059
|
-
return this.http.get(`/api/db/${
|
|
4186
|
+
return this.http.get(`/api/db/${encodePathParam(appId)}/state/root`);
|
|
4060
4187
|
}
|
|
4061
4188
|
/**
|
|
4062
4189
|
* Get a Merkle proof for a specific document
|
|
@@ -4064,7 +4191,7 @@ var DatabaseClient = class {
|
|
|
4064
4191
|
async getDocumentProof(documentId) {
|
|
4065
4192
|
const appId = this.getAppId();
|
|
4066
4193
|
return this.http.get(
|
|
4067
|
-
`/api/db/${
|
|
4194
|
+
`/api/db/${encodePathParam(appId)}/${encodePathParam(documentId)}/proof`
|
|
4068
4195
|
);
|
|
4069
4196
|
}
|
|
4070
4197
|
/**
|
|
@@ -4078,7 +4205,7 @@ var DatabaseClient = class {
|
|
|
4078
4205
|
if (options?.limit !== void 0) params.set("limit", String(options.limit));
|
|
4079
4206
|
const qs = params.toString();
|
|
4080
4207
|
return this.http.get(
|
|
4081
|
-
`/api/db/${
|
|
4208
|
+
`/api/db/${encodePathParam(appId)}/state/transitions${qs ? `?${qs}` : ""}`
|
|
4082
4209
|
);
|
|
4083
4210
|
}
|
|
4084
4211
|
/**
|
|
@@ -4086,7 +4213,7 @@ var DatabaseClient = class {
|
|
|
4086
4213
|
*/
|
|
4087
4214
|
async getDbStats() {
|
|
4088
4215
|
const appId = this.getAppId();
|
|
4089
|
-
return this.http.get(`/api/db/${
|
|
4216
|
+
return this.http.get(`/api/db/${encodePathParam(appId)}/stats`);
|
|
4090
4217
|
}
|
|
4091
4218
|
};
|
|
4092
4219
|
|
|
@@ -4103,47 +4230,35 @@ var StorageClient = class {
|
|
|
4103
4230
|
*/
|
|
4104
4231
|
async upload(file, filename, metadata) {
|
|
4105
4232
|
const appId = this.getAppId();
|
|
4106
|
-
return this.http.upload(`/api/storage/${
|
|
4233
|
+
return this.http.upload(`/api/storage/${encodePathParam(appId)}/upload`, file, filename, metadata);
|
|
4107
4234
|
}
|
|
4108
4235
|
/**
|
|
4109
4236
|
* Download a file by CID
|
|
4110
4237
|
*/
|
|
4111
4238
|
async download(cid) {
|
|
4112
4239
|
const appId = this.getAppId();
|
|
4113
|
-
return this.http.get(`/api/storage/${
|
|
4240
|
+
return this.http.get(`/api/storage/${encodePathParam(appId)}/download/${encodePathParam(cid)}`);
|
|
4114
4241
|
}
|
|
4115
4242
|
/**
|
|
4116
4243
|
* Get file metadata
|
|
4117
4244
|
*/
|
|
4118
4245
|
async getMetadata(cid) {
|
|
4119
4246
|
const appId = this.getAppId();
|
|
4120
|
-
return this.http.get(`/api/storage/${
|
|
4247
|
+
return this.http.get(`/api/storage/${encodePathParam(appId)}/metadata/${encodePathParam(cid)}`);
|
|
4121
4248
|
}
|
|
4122
4249
|
/**
|
|
4123
4250
|
* Delete a file
|
|
4124
4251
|
*/
|
|
4125
4252
|
async delete(cid) {
|
|
4126
4253
|
const appId = this.getAppId();
|
|
4127
|
-
return this.http.delete(`/api/storage/${
|
|
4254
|
+
return this.http.delete(`/api/storage/${encodePathParam(appId)}/${encodePathParam(cid)}`);
|
|
4128
4255
|
}
|
|
4129
4256
|
/**
|
|
4130
|
-
*
|
|
4257
|
+
* List all files for the app.
|
|
4131
4258
|
*
|
|
4132
|
-
* @
|
|
4133
|
-
*
|
|
4134
|
-
*
|
|
4135
|
-
* stream body via `download(cid)`. This alias forwards to `download`
|
|
4136
|
-
* for back-compat; remove in the next major SDK release.
|
|
4137
|
-
*/
|
|
4138
|
-
async getFile(cid) {
|
|
4139
|
-
return this.download(cid);
|
|
4140
|
-
}
|
|
4141
|
-
/**
|
|
4142
|
-
* List all files for the app
|
|
4143
|
-
*
|
|
4144
|
-
* @param pagination.offset Server reads `offset`; the legacy `skip`
|
|
4145
|
-
* option was a client-only synonym that the server silently ignored.
|
|
4146
|
-
* Use `offset` going forward.
|
|
4259
|
+
* @param pagination - Optional `limit` and `offset` (the server reads
|
|
4260
|
+
* `offset` for pagination).
|
|
4261
|
+
* @returns The file list and total count.
|
|
4147
4262
|
*/
|
|
4148
4263
|
async listFiles(pagination) {
|
|
4149
4264
|
const appId = this.getAppId();
|
|
@@ -4151,21 +4266,21 @@ var StorageClient = class {
|
|
|
4151
4266
|
if (pagination?.limit !== void 0) params.set("limit", String(pagination.limit));
|
|
4152
4267
|
if (pagination?.offset !== void 0) params.set("offset", String(pagination.offset));
|
|
4153
4268
|
const qs = params.toString();
|
|
4154
|
-
return this.http.get(`/api/storage/${
|
|
4269
|
+
return this.http.get(`/api/storage/${encodePathParam(appId)}/files${qs ? `?${qs}` : ""}`);
|
|
4155
4270
|
}
|
|
4156
4271
|
/**
|
|
4157
4272
|
* Get storage usage for the current app
|
|
4158
4273
|
*/
|
|
4159
4274
|
async getUsage() {
|
|
4160
4275
|
const appId = this.getAppId();
|
|
4161
|
-
return this.http.get(`/api/storage/${
|
|
4276
|
+
return this.http.get(`/api/storage/${encodePathParam(appId)}/usage`);
|
|
4162
4277
|
}
|
|
4163
4278
|
/**
|
|
4164
4279
|
* Check if a file exists
|
|
4165
4280
|
*/
|
|
4166
4281
|
async exists(cid) {
|
|
4167
4282
|
const appId = this.getAppId();
|
|
4168
|
-
return this.http.get(`/api/storage/${
|
|
4283
|
+
return this.http.get(`/api/storage/${encodePathParam(appId)}/exists/${encodePathParam(cid)}`);
|
|
4169
4284
|
}
|
|
4170
4285
|
};
|
|
4171
4286
|
|
|
@@ -4182,7 +4297,7 @@ var FunctionsClient = class {
|
|
|
4182
4297
|
*/
|
|
4183
4298
|
async deploy(request) {
|
|
4184
4299
|
const appId = this.getAppId();
|
|
4185
|
-
return this.http.post(`/api/functions/${
|
|
4300
|
+
return this.http.post(`/api/functions/${encodePathParam(appId)}`, request);
|
|
4186
4301
|
}
|
|
4187
4302
|
/**
|
|
4188
4303
|
* Invoke a function
|
|
@@ -4190,7 +4305,7 @@ var FunctionsClient = class {
|
|
|
4190
4305
|
async invoke(functionId, payload) {
|
|
4191
4306
|
const appId = this.getAppId();
|
|
4192
4307
|
return this.http.post(
|
|
4193
|
-
`/api/functions/${
|
|
4308
|
+
`/api/functions/${encodePathParam(appId)}/${encodePathParam(functionId)}/invoke`,
|
|
4194
4309
|
payload ?? {}
|
|
4195
4310
|
);
|
|
4196
4311
|
}
|
|
@@ -4199,7 +4314,7 @@ var FunctionsClient = class {
|
|
|
4199
4314
|
*/
|
|
4200
4315
|
async list() {
|
|
4201
4316
|
const appId = this.getAppId();
|
|
4202
|
-
return this.http.get(`/api/functions/${
|
|
4317
|
+
return this.http.get(`/api/functions/${encodePathParam(appId)}`);
|
|
4203
4318
|
}
|
|
4204
4319
|
/**
|
|
4205
4320
|
* Get function details
|
|
@@ -4207,7 +4322,7 @@ var FunctionsClient = class {
|
|
|
4207
4322
|
async get(functionId) {
|
|
4208
4323
|
const appId = this.getAppId();
|
|
4209
4324
|
return this.http.get(
|
|
4210
|
-
`/api/functions/${
|
|
4325
|
+
`/api/functions/${encodePathParam(appId)}/${encodePathParam(functionId)}`
|
|
4211
4326
|
);
|
|
4212
4327
|
}
|
|
4213
4328
|
/**
|
|
@@ -4216,7 +4331,7 @@ var FunctionsClient = class {
|
|
|
4216
4331
|
async update(functionId, updates) {
|
|
4217
4332
|
const appId = this.getAppId();
|
|
4218
4333
|
return this.http.put(
|
|
4219
|
-
`/api/functions/${
|
|
4334
|
+
`/api/functions/${encodePathParam(appId)}/${encodePathParam(functionId)}`,
|
|
4220
4335
|
updates
|
|
4221
4336
|
);
|
|
4222
4337
|
}
|
|
@@ -4226,7 +4341,7 @@ var FunctionsClient = class {
|
|
|
4226
4341
|
async delete(functionId) {
|
|
4227
4342
|
const appId = this.getAppId();
|
|
4228
4343
|
return this.http.delete(
|
|
4229
|
-
`/api/functions/${
|
|
4344
|
+
`/api/functions/${encodePathParam(appId)}/${encodePathParam(functionId)}`
|
|
4230
4345
|
);
|
|
4231
4346
|
}
|
|
4232
4347
|
/**
|
|
@@ -4240,7 +4355,7 @@ var FunctionsClient = class {
|
|
|
4240
4355
|
if (options?.level) params.set("level", options.level);
|
|
4241
4356
|
const qs = params.toString();
|
|
4242
4357
|
return this.http.get(
|
|
4243
|
-
`/api/functions/${
|
|
4358
|
+
`/api/functions/${encodePathParam(appId)}/${encodePathParam(functionId)}/logs${qs ? `?${qs}` : ""}`
|
|
4244
4359
|
);
|
|
4245
4360
|
}
|
|
4246
4361
|
/**
|
|
@@ -4248,7 +4363,7 @@ var FunctionsClient = class {
|
|
|
4248
4363
|
*/
|
|
4249
4364
|
async getStats() {
|
|
4250
4365
|
const appId = this.getAppId();
|
|
4251
|
-
return this.http.get(`/api/functions/${
|
|
4366
|
+
return this.http.get(`/api/functions/${encodePathParam(appId)}/stats`);
|
|
4252
4367
|
}
|
|
4253
4368
|
};
|
|
4254
4369
|
|
|
@@ -4265,28 +4380,28 @@ var MessagingClient = class {
|
|
|
4265
4380
|
*/
|
|
4266
4381
|
async createChannel(config) {
|
|
4267
4382
|
const appId = this.getAppId();
|
|
4268
|
-
return this.http.post(`/api/messaging/${
|
|
4383
|
+
return this.http.post(`/api/messaging/${encodePathParam(appId)}/channels`, config);
|
|
4269
4384
|
}
|
|
4270
4385
|
/**
|
|
4271
4386
|
* Delete a channel
|
|
4272
4387
|
*/
|
|
4273
4388
|
async deleteChannel(channelId) {
|
|
4274
4389
|
const appId = this.getAppId();
|
|
4275
|
-
return this.http.delete(`/api/messaging/${
|
|
4390
|
+
return this.http.delete(`/api/messaging/${encodePathParam(appId)}/channels/${encodePathParam(channelId)}`);
|
|
4276
4391
|
}
|
|
4277
4392
|
/**
|
|
4278
4393
|
* Get a channel by ID
|
|
4279
4394
|
*/
|
|
4280
4395
|
async getChannel(channelId) {
|
|
4281
4396
|
const appId = this.getAppId();
|
|
4282
|
-
return this.http.get(`/api/messaging/${
|
|
4397
|
+
return this.http.get(`/api/messaging/${encodePathParam(appId)}/channels/${encodePathParam(channelId)}`);
|
|
4283
4398
|
}
|
|
4284
4399
|
/**
|
|
4285
4400
|
* List all channels for the app
|
|
4286
4401
|
*/
|
|
4287
4402
|
async listChannels() {
|
|
4288
4403
|
const appId = this.getAppId();
|
|
4289
|
-
return this.http.get(`/api/messaging/${
|
|
4404
|
+
return this.http.get(`/api/messaging/${encodePathParam(appId)}/channels`);
|
|
4290
4405
|
}
|
|
4291
4406
|
/**
|
|
4292
4407
|
* Publish a message to a channel
|
|
@@ -4294,7 +4409,7 @@ var MessagingClient = class {
|
|
|
4294
4409
|
async publish(channel, message, metadata) {
|
|
4295
4410
|
const appId = this.getAppId();
|
|
4296
4411
|
return this.http.post(
|
|
4297
|
-
`/api/messaging/${
|
|
4412
|
+
`/api/messaging/${encodePathParam(appId)}/channels/${encodePathParam(channel)}/publish`,
|
|
4298
4413
|
{ data: message, metadata }
|
|
4299
4414
|
);
|
|
4300
4415
|
}
|
|
@@ -4309,7 +4424,7 @@ var MessagingClient = class {
|
|
|
4309
4424
|
if (options?.after) params.set("after", options.after);
|
|
4310
4425
|
const qs = params.toString();
|
|
4311
4426
|
return this.http.get(
|
|
4312
|
-
`/api/messaging/${
|
|
4427
|
+
`/api/messaging/${encodePathParam(appId)}/channels/${encodePathParam(channel)}/history${qs ? `?${qs}` : ""}`
|
|
4313
4428
|
);
|
|
4314
4429
|
}
|
|
4315
4430
|
/**
|
|
@@ -4323,7 +4438,7 @@ var MessagingClient = class {
|
|
|
4323
4438
|
async setPresence(channel, member) {
|
|
4324
4439
|
const appId = this.getAppId();
|
|
4325
4440
|
return this.http.post(
|
|
4326
|
-
`/api/messaging/${
|
|
4441
|
+
`/api/messaging/${encodePathParam(appId)}/channels/${encodePathParam(channel)}/presence`,
|
|
4327
4442
|
member
|
|
4328
4443
|
);
|
|
4329
4444
|
}
|
|
@@ -4339,7 +4454,7 @@ var MessagingClient = class {
|
|
|
4339
4454
|
async removePresence(channel, clientId) {
|
|
4340
4455
|
const appId = this.getAppId();
|
|
4341
4456
|
return this.http.delete(
|
|
4342
|
-
`/api/messaging/${
|
|
4457
|
+
`/api/messaging/${encodePathParam(appId)}/channels/${encodePathParam(channel)}/presence/${encodePathParam(clientId)}`
|
|
4343
4458
|
);
|
|
4344
4459
|
}
|
|
4345
4460
|
/**
|
|
@@ -4348,7 +4463,7 @@ var MessagingClient = class {
|
|
|
4348
4463
|
async getPresence(channel) {
|
|
4349
4464
|
const appId = this.getAppId();
|
|
4350
4465
|
return this.http.get(
|
|
4351
|
-
`/api/messaging/${
|
|
4466
|
+
`/api/messaging/${encodePathParam(appId)}/channels/${encodePathParam(channel)}/presence`
|
|
4352
4467
|
);
|
|
4353
4468
|
}
|
|
4354
4469
|
/**
|
|
@@ -4356,7 +4471,7 @@ var MessagingClient = class {
|
|
|
4356
4471
|
*/
|
|
4357
4472
|
async getStats() {
|
|
4358
4473
|
const appId = this.getAppId();
|
|
4359
|
-
return this.http.get(`/api/messaging/${
|
|
4474
|
+
return this.http.get(`/api/messaging/${encodePathParam(appId)}/stats`);
|
|
4360
4475
|
}
|
|
4361
4476
|
};
|
|
4362
4477
|
|
|
@@ -4444,7 +4559,7 @@ var RulesClient = class {
|
|
|
4444
4559
|
}
|
|
4445
4560
|
/** Fetch a published rule by its HCS consensus timestamp. */
|
|
4446
4561
|
async get(consensusTimestamp) {
|
|
4447
|
-
return this.http.get(`/api/rules/${
|
|
4562
|
+
return this.http.get(`/api/rules/${encodePathParam(consensusTimestamp)}`);
|
|
4448
4563
|
}
|
|
4449
4564
|
/** List rules owned by the authenticated entity, optionally filtered by type. */
|
|
4450
4565
|
async listByOwner(filter) {
|
|
@@ -4461,13 +4576,13 @@ var RulesClient = class {
|
|
|
4461
4576
|
/** Walk the version history of a published rule. */
|
|
4462
4577
|
async getVersionHistory(consensusTimestamp) {
|
|
4463
4578
|
return this.http.get(
|
|
4464
|
-
`/api/rules/${
|
|
4579
|
+
`/api/rules/${encodePathParam(consensusTimestamp)}/versions`
|
|
4465
4580
|
);
|
|
4466
4581
|
}
|
|
4467
4582
|
/** Deprecate a published rule (owner-only). */
|
|
4468
4583
|
async deprecate(consensusTimestamp) {
|
|
4469
4584
|
return this.http.post(
|
|
4470
|
-
`/api/rules/${
|
|
4585
|
+
`/api/rules/${encodePathParam(consensusTimestamp)}/deprecate`,
|
|
4471
4586
|
{}
|
|
4472
4587
|
);
|
|
4473
4588
|
}
|
|
@@ -4505,7 +4620,7 @@ var EntitiesClient = class {
|
|
|
4505
4620
|
}
|
|
4506
4621
|
/** Fetch an entity by its canonical `entityId`. */
|
|
4507
4622
|
async get(entityId) {
|
|
4508
|
-
return this.http.get(`/api/entities/${
|
|
4623
|
+
return this.http.get(`/api/entities/${encodePathParam(entityId)}`);
|
|
4509
4624
|
}
|
|
4510
4625
|
/** List entities owned by the authenticated wallet, optionally filtered by type. */
|
|
4511
4626
|
async listByOwner(filter) {
|
|
@@ -4521,10 +4636,16 @@ var BaasClient = class _BaasClient {
|
|
|
4521
4636
|
appId;
|
|
4522
4637
|
timeout;
|
|
4523
4638
|
allowInsecure;
|
|
4524
|
-
authToken = null;
|
|
4525
4639
|
http;
|
|
4526
4640
|
/** Last HTTP error (for getHttpHealth) */
|
|
4527
4641
|
lastHttpError;
|
|
4642
|
+
/**
|
|
4643
|
+
* Auth options from the last {@link authenticate} call, retained so the
|
|
4644
|
+
* client can transparently re-authenticate when the session token expires
|
|
4645
|
+
* (the http client invokes {@link reauthenticate} on a 401). Undefined until
|
|
4646
|
+
* the first successful authenticate.
|
|
4647
|
+
*/
|
|
4648
|
+
authContext;
|
|
4528
4649
|
// ========== Sub-Clients ==========
|
|
4529
4650
|
/** Trustless database with state proofs and Merkle verification */
|
|
4530
4651
|
db;
|
|
@@ -4554,7 +4675,11 @@ var BaasClient = class _BaasClient {
|
|
|
4554
4675
|
const baseUrlWithPrefix = this.pathPrefix ? this.hostUrl.replace(/\/$/, "") + this.pathPrefix : this.hostUrl;
|
|
4555
4676
|
this.http = createHttpClient({
|
|
4556
4677
|
baseUrl: baseUrlWithPrefix,
|
|
4557
|
-
timeout: this.timeout
|
|
4678
|
+
timeout: this.timeout,
|
|
4679
|
+
// Transparent session refresh: on a 401, re-run the challenge-response
|
|
4680
|
+
// with the retained signer and retry once. No-op until authenticate() has
|
|
4681
|
+
// been called (authContext set). Excludes /api/auth/* (see http client).
|
|
4682
|
+
onUnauthorized: () => this.reauthenticate()
|
|
4558
4683
|
});
|
|
4559
4684
|
const getAppId = () => this.requireAppId();
|
|
4560
4685
|
this.db = new DatabaseClient(this.http, getAppId);
|
|
@@ -4608,30 +4733,25 @@ var BaasClient = class _BaasClient {
|
|
|
4608
4733
|
*/
|
|
4609
4734
|
static async connectToCluster(config) {
|
|
4610
4735
|
const allowInsecure = config.allowInsecure ?? false;
|
|
4611
|
-
const
|
|
4612
|
-
|
|
4613
|
-
|
|
4614
|
-
"connectToCluster requires either a non-empty `bootstrap` list or a known `network` name.",
|
|
4615
|
-
400
|
|
4616
|
-
);
|
|
4617
|
-
}
|
|
4618
|
-
const discovery = new ClusterDiscoveryClient({
|
|
4619
|
-
bootstrap,
|
|
4736
|
+
const resolved = await resolveClusterEndpoint({
|
|
4737
|
+
bootstrap: config.bootstrap,
|
|
4738
|
+
network: config.network,
|
|
4620
4739
|
allowInsecure,
|
|
4621
|
-
trustAnchor: config.trustAnchor
|
|
4622
|
-
network: config.trustAnchor.network,
|
|
4623
|
-
registryTopicId: config.trustAnchor.registryTopicId,
|
|
4624
|
-
mirrorNodeUrl: config.trustAnchor.mirrorNodeUrl,
|
|
4625
|
-
allowInsecure
|
|
4626
|
-
} : void 0
|
|
4740
|
+
trustAnchor: config.trustAnchor
|
|
4627
4741
|
});
|
|
4628
|
-
|
|
4629
|
-
|
|
4742
|
+
if (!resolved.ok) {
|
|
4743
|
+
if (resolved.reason === "no-seeds") {
|
|
4744
|
+
throw new BaasError(
|
|
4745
|
+
"connectToCluster requires either a non-empty `bootstrap` list or a known `network` name.",
|
|
4746
|
+
400
|
|
4747
|
+
);
|
|
4748
|
+
}
|
|
4630
4749
|
throw new BaasError(
|
|
4631
4750
|
"No active clusters available via bootstrap seeds. Check network reachability or bootstrap URLs.",
|
|
4632
4751
|
503
|
|
4633
4752
|
);
|
|
4634
4753
|
}
|
|
4754
|
+
const cluster = resolved.cluster;
|
|
4635
4755
|
return new _BaasClient({
|
|
4636
4756
|
hostUrl: cluster.endpoints.gatewayUrl,
|
|
4637
4757
|
appId: config.appId,
|
|
@@ -4649,7 +4769,7 @@ var BaasClient = class _BaasClient {
|
|
|
4649
4769
|
}
|
|
4650
4770
|
/** Check if the client is authenticated */
|
|
4651
4771
|
isAuthenticated() {
|
|
4652
|
-
return this.
|
|
4772
|
+
return this.http.getAuthToken() !== void 0;
|
|
4653
4773
|
}
|
|
4654
4774
|
/** Get the current app ID */
|
|
4655
4775
|
getAppId() {
|
|
@@ -4695,93 +4815,80 @@ var BaasClient = class _BaasClient {
|
|
|
4695
4815
|
*/
|
|
4696
4816
|
async authenticate(options) {
|
|
4697
4817
|
const { chain, walletAddress, publicKey, signFn } = options;
|
|
4698
|
-
|
|
4699
|
-
|
|
4700
|
-
|
|
4818
|
+
this.authContext = options;
|
|
4819
|
+
let challenge;
|
|
4820
|
+
try {
|
|
4821
|
+
challenge = await this.http.post("/api/auth/challenge", {
|
|
4822
|
+
chain,
|
|
4823
|
+
walletAddress,
|
|
4824
|
+
appId: this.appId
|
|
4825
|
+
});
|
|
4826
|
+
} catch (err) {
|
|
4827
|
+
throw asBaasError(err);
|
|
4828
|
+
}
|
|
4829
|
+
const signature = await signFn(challenge.message);
|
|
4830
|
+
let result;
|
|
4831
|
+
try {
|
|
4832
|
+
result = await this.http.post("/api/auth/verify", {
|
|
4833
|
+
challengeId: challenge.challengeId,
|
|
4834
|
+
signature,
|
|
4835
|
+
publicKey
|
|
4836
|
+
});
|
|
4837
|
+
} catch (err) {
|
|
4838
|
+
throw asBaasError(err);
|
|
4839
|
+
}
|
|
4840
|
+
this.http.setAuthToken(result.token);
|
|
4841
|
+
return result;
|
|
4842
|
+
}
|
|
4843
|
+
/**
|
|
4844
|
+
* Re-run the challenge-response with the retained signer to mint a fresh
|
|
4845
|
+
* session token. Invoked by the http client's `onUnauthorized` hook when a
|
|
4846
|
+
* request 401s because the token expired — so long-lived clients keep working
|
|
4847
|
+
* without the caller re-implementing refresh. No-op if {@link authenticate}
|
|
4848
|
+
* was never called. The `/api/auth/*` calls below are excluded from the http
|
|
4849
|
+
* client's 401-retry path, so this can never recurse.
|
|
4850
|
+
*/
|
|
4851
|
+
async reauthenticate() {
|
|
4852
|
+
const ctx = this.authContext;
|
|
4853
|
+
if (!ctx) return;
|
|
4854
|
+
const challenge = await this.http.post("/api/auth/challenge", {
|
|
4855
|
+
chain: ctx.chain,
|
|
4856
|
+
walletAddress: ctx.walletAddress,
|
|
4701
4857
|
appId: this.appId
|
|
4702
4858
|
});
|
|
4703
|
-
const signature = await signFn(challenge.message);
|
|
4704
|
-
const result = await this.post("/api/auth/verify", {
|
|
4859
|
+
const signature = await ctx.signFn(challenge.message);
|
|
4860
|
+
const result = await this.http.post("/api/auth/verify", {
|
|
4705
4861
|
challengeId: challenge.challengeId,
|
|
4706
4862
|
signature,
|
|
4707
|
-
publicKey
|
|
4863
|
+
publicKey: ctx.publicKey
|
|
4708
4864
|
});
|
|
4709
|
-
this.
|
|
4710
|
-
this.http.setAuthToken?.(result.token);
|
|
4711
|
-
return result;
|
|
4865
|
+
this.http.setAuthToken(result.token);
|
|
4712
4866
|
}
|
|
4713
4867
|
/** Validate the current session */
|
|
4714
4868
|
async validateSession() {
|
|
4715
4869
|
this.requireAuth();
|
|
4716
|
-
|
|
4870
|
+
try {
|
|
4871
|
+
return await this.http.get("/api/auth/session");
|
|
4872
|
+
} catch (err) {
|
|
4873
|
+
throw asBaasError(err);
|
|
4874
|
+
}
|
|
4717
4875
|
}
|
|
4718
4876
|
/** Destroy the current session on server and clear local token */
|
|
4719
4877
|
async logout() {
|
|
4720
|
-
if (this.
|
|
4878
|
+
if (this.http.getAuthToken()) {
|
|
4721
4879
|
try {
|
|
4722
|
-
await this.post("/api/auth/logout", {});
|
|
4880
|
+
await this.http.post("/api/auth/logout", {});
|
|
4723
4881
|
} catch {
|
|
4724
4882
|
}
|
|
4725
4883
|
}
|
|
4726
|
-
this.
|
|
4884
|
+
this.http.setAuthToken(void 0);
|
|
4727
4885
|
}
|
|
4728
4886
|
// ========== HTTP Helpers ==========
|
|
4729
4887
|
requireAuth() {
|
|
4730
|
-
if (!this.
|
|
4888
|
+
if (!this.http.getAuthToken()) {
|
|
4731
4889
|
throw new BaasError("Authentication required. Call authenticate() first.", 401);
|
|
4732
4890
|
}
|
|
4733
4891
|
}
|
|
4734
|
-
getHeaders() {
|
|
4735
|
-
const headers = {
|
|
4736
|
-
"Content-Type": "application/json"
|
|
4737
|
-
};
|
|
4738
|
-
if (this.authToken) {
|
|
4739
|
-
headers["Authorization"] = `Bearer ${this.authToken}`;
|
|
4740
|
-
}
|
|
4741
|
-
return headers;
|
|
4742
|
-
}
|
|
4743
|
-
async post(path, body) {
|
|
4744
|
-
return this.request("POST", path, body);
|
|
4745
|
-
}
|
|
4746
|
-
async get(path) {
|
|
4747
|
-
return this.request("GET", path);
|
|
4748
|
-
}
|
|
4749
|
-
async request(method, path, body) {
|
|
4750
|
-
const url = `${this.hostUrl}${this.pathPrefix}${path}`;
|
|
4751
|
-
const controller = new AbortController();
|
|
4752
|
-
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
4753
|
-
try {
|
|
4754
|
-
const options = {
|
|
4755
|
-
method,
|
|
4756
|
-
headers: this.getHeaders(),
|
|
4757
|
-
signal: controller.signal
|
|
4758
|
-
};
|
|
4759
|
-
if (body !== void 0) {
|
|
4760
|
-
options.body = JSON.stringify(body);
|
|
4761
|
-
}
|
|
4762
|
-
const response = await fetch(url, options);
|
|
4763
|
-
clearTimeout(timeoutId);
|
|
4764
|
-
if (!response.ok) {
|
|
4765
|
-
const errorData = await response.json().catch(() => ({}));
|
|
4766
|
-
throw new BaasError(
|
|
4767
|
-
errorData.message || `API error: ${response.status} ${response.statusText}`,
|
|
4768
|
-
response.status,
|
|
4769
|
-
errorData
|
|
4770
|
-
);
|
|
4771
|
-
}
|
|
4772
|
-
const text = await response.text();
|
|
4773
|
-
if (!text) return void 0;
|
|
4774
|
-
return JSON.parse(text);
|
|
4775
|
-
} catch (error) {
|
|
4776
|
-
clearTimeout(timeoutId);
|
|
4777
|
-
if (error instanceof BaasError) throw error;
|
|
4778
|
-
const err = error;
|
|
4779
|
-
if (err.name === "AbortError") {
|
|
4780
|
-
throw new BaasError("Request timeout", 408);
|
|
4781
|
-
}
|
|
4782
|
-
throw new BaasError(`Network error: ${err.message}`, 0, { originalError: err.message });
|
|
4783
|
-
}
|
|
4784
|
-
}
|
|
4785
4892
|
};
|
|
4786
4893
|
var BaasError = class extends Error {
|
|
4787
4894
|
constructor(message, statusCode, details) {
|
|
@@ -4793,6 +4900,17 @@ var BaasError = class extends Error {
|
|
|
4793
4900
|
statusCode;
|
|
4794
4901
|
details;
|
|
4795
4902
|
};
|
|
4903
|
+
function asBaasError(err) {
|
|
4904
|
+
if (err instanceof BaasError) return err;
|
|
4905
|
+
if (err instanceof SdkHttpError) {
|
|
4906
|
+
const details = err.details ?? void 0;
|
|
4907
|
+
return new BaasError(err.message, err.statusCode, details);
|
|
4908
|
+
}
|
|
4909
|
+
const e = err;
|
|
4910
|
+
return new BaasError(`Network error: ${e?.message ?? String(err)}`, 0, {
|
|
4911
|
+
originalError: e?.message ?? String(err)
|
|
4912
|
+
});
|
|
4913
|
+
}
|
|
4796
4914
|
function validateUrl2(url, allowInsecure = false) {
|
|
4797
4915
|
try {
|
|
4798
4916
|
const parsed = new URL(url);
|
|
@@ -5016,10 +5134,12 @@ exports.SmartEngineService = __decorateClass([
|
|
|
5016
5134
|
// src/nestjs/smart-engine.module.ts
|
|
5017
5135
|
exports.SmartEngineModule = class SmartEngineModule {
|
|
5018
5136
|
/**
|
|
5019
|
-
* Configure the module with static configuration
|
|
5137
|
+
* Configure the module with static configuration.
|
|
5020
5138
|
*
|
|
5021
|
-
* @param config - SmartEngine service configuration
|
|
5022
|
-
* @param isGlobal - Whether to make the module global
|
|
5139
|
+
* @param config - SmartEngine service configuration.
|
|
5140
|
+
* @param isGlobal - Whether to make the module global. @defaultValue true
|
|
5141
|
+
* @returns A `DynamicModule` exporting {@link SmartEngineService} plus the
|
|
5142
|
+
* BaaS / rules / entities clients.
|
|
5023
5143
|
*/
|
|
5024
5144
|
static forRoot(config, isGlobal = true) {
|
|
5025
5145
|
return {
|
|
@@ -5042,11 +5162,15 @@ exports.SmartEngineModule = class SmartEngineModule {
|
|
|
5042
5162
|
};
|
|
5043
5163
|
}
|
|
5044
5164
|
/**
|
|
5045
|
-
* Configure the module with async configuration
|
|
5165
|
+
* Configure the module with async configuration.
|
|
5046
5166
|
*
|
|
5047
5167
|
* Supports factory functions, configuration classes, and existing providers.
|
|
5048
5168
|
*
|
|
5049
|
-
* @param options - Async configuration options
|
|
5169
|
+
* @param options - Async configuration options.
|
|
5170
|
+
* @returns A `DynamicModule` exporting {@link SmartEngineService} plus the
|
|
5171
|
+
* BaaS / rules / entities clients.
|
|
5172
|
+
* @throws Error if `options` provides none of `useFactory`, `useClass`, or
|
|
5173
|
+
* `useExisting`.
|
|
5050
5174
|
*/
|
|
5051
5175
|
static forRootAsync(options) {
|
|
5052
5176
|
const asyncProviders = this.createAsyncProviders(options);
|