@hsuite/smart-engines-sdk 3.4.0 → 3.5.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/dist/index.js CHANGED
@@ -123,12 +123,12 @@ var require_lib = __commonJS({
123
123
  if (lengths.length > 0 && !lengths.includes(b.length))
124
124
  throw new Error("Uint8Array expected of length " + lengths + ", got length=" + b.length);
125
125
  }
126
- function isArrayOf(isString, arr) {
126
+ function isArrayOf(isString2, arr) {
127
127
  if (!Array.isArray(arr))
128
128
  return false;
129
129
  if (arr.length === 0)
130
130
  return true;
131
- if (isString) {
131
+ if (isString2) {
132
132
  return arr.every((item) => typeof item === "string");
133
133
  } else {
134
134
  return arr.every((item) => Number.isSafeInteger(item));
@@ -6008,7 +6008,8 @@ __export(discovery_exports, {
6008
6008
  MirrorNodeClient: () => MirrorNodeClient,
6009
6009
  MirrorNodeError: () => MirrorNodeError,
6010
6010
  PlatformImagesClient: () => PlatformImagesClient,
6011
- ValidatorDiscoveryClient: () => ValidatorDiscoveryClient
6011
+ ValidatorDiscoveryClient: () => ValidatorDiscoveryClient,
6012
+ resolveClusterEndpoint: () => resolveClusterEndpoint
6012
6013
  });
6013
6014
 
6014
6015
  // src/discovery/mirror-node.ts
@@ -6556,6 +6557,178 @@ var ClusterDiscoveryClient = class {
6556
6557
  }
6557
6558
  };
6558
6559
 
6560
+ // src/http/index.ts
6561
+ var SdkHttpError = class extends Error {
6562
+ constructor(message, statusCode, details) {
6563
+ super(message);
6564
+ this.statusCode = statusCode;
6565
+ this.details = details;
6566
+ this.name = "SdkHttpError";
6567
+ }
6568
+ statusCode;
6569
+ details;
6570
+ };
6571
+ function createHttpClient(config) {
6572
+ const timeout = config.timeout ?? 3e4;
6573
+ function getHeaders(contentType) {
6574
+ const headers = {};
6575
+ if (contentType) {
6576
+ headers["Content-Type"] = contentType;
6577
+ }
6578
+ if (config.authToken) {
6579
+ headers["Authorization"] = `Bearer ${config.authToken}`;
6580
+ }
6581
+ if (config.apiKey) {
6582
+ headers["X-API-Key"] = config.apiKey;
6583
+ }
6584
+ return headers;
6585
+ }
6586
+ function setAuthToken(token) {
6587
+ config.authToken = token;
6588
+ }
6589
+ function getAuthToken() {
6590
+ return config.authToken;
6591
+ }
6592
+ async function request(method, path, body) {
6593
+ const url = `${config.baseUrl}${path}`;
6594
+ const controller = new AbortController();
6595
+ const timeoutId = setTimeout(() => controller.abort(), timeout);
6596
+ try {
6597
+ const init = {
6598
+ method,
6599
+ headers: getHeaders("application/json"),
6600
+ signal: controller.signal
6601
+ };
6602
+ if (body !== void 0) {
6603
+ init.body = JSON.stringify(body);
6604
+ }
6605
+ const response = await fetch(url, init);
6606
+ clearTimeout(timeoutId);
6607
+ if (!response.ok) {
6608
+ const errorData = await response.json().catch(() => ({}));
6609
+ throw new SdkHttpError(
6610
+ errorData.message || `API error: ${response.status} ${response.statusText}`,
6611
+ response.status,
6612
+ errorData
6613
+ );
6614
+ }
6615
+ const text = await response.text();
6616
+ if (!text) return void 0;
6617
+ return JSON.parse(text);
6618
+ } catch (error) {
6619
+ clearTimeout(timeoutId);
6620
+ if (error instanceof SdkHttpError) throw error;
6621
+ const err = error;
6622
+ if (err.name === "AbortError") {
6623
+ throw new SdkHttpError("Request timeout", 408);
6624
+ }
6625
+ throw new SdkHttpError(`Network error: ${err.message}`, 0, error);
6626
+ }
6627
+ }
6628
+ async function getText(path) {
6629
+ const url = `${config.baseUrl}${path}`;
6630
+ const controller = new AbortController();
6631
+ const timeoutId = setTimeout(() => controller.abort(), timeout);
6632
+ try {
6633
+ const response = await fetch(url, {
6634
+ method: "GET",
6635
+ headers: getHeaders(),
6636
+ signal: controller.signal
6637
+ });
6638
+ clearTimeout(timeoutId);
6639
+ if (!response.ok) {
6640
+ const errBody = await response.json().catch(() => ({}));
6641
+ throw new SdkHttpError(
6642
+ errBody.message || `API error: ${response.status} ${response.statusText}`,
6643
+ response.status,
6644
+ errBody
6645
+ );
6646
+ }
6647
+ return await response.text();
6648
+ } catch (error) {
6649
+ clearTimeout(timeoutId);
6650
+ if (error instanceof SdkHttpError) throw error;
6651
+ const err = error;
6652
+ if (err.name === "AbortError") {
6653
+ throw new SdkHttpError("Request timeout", 408);
6654
+ }
6655
+ throw new SdkHttpError(`Network error: ${err.message}`, 0, error);
6656
+ }
6657
+ }
6658
+ async function upload(path, file, filename, metadata, fieldName = "file") {
6659
+ const url = `${config.baseUrl}${path}`;
6660
+ const controller = new AbortController();
6661
+ const timeoutId = setTimeout(() => controller.abort(), timeout * 2);
6662
+ try {
6663
+ const formData = new FormData();
6664
+ const blob = file instanceof Blob ? file : new Blob([new Uint8Array(file)]);
6665
+ formData.append(fieldName, blob, filename);
6666
+ if (metadata) {
6667
+ for (const [key, value] of Object.entries(metadata)) {
6668
+ formData.append(key, value);
6669
+ }
6670
+ }
6671
+ const headers = {};
6672
+ if (config.authToken) {
6673
+ headers["Authorization"] = `Bearer ${config.authToken}`;
6674
+ }
6675
+ if (config.apiKey) {
6676
+ headers["X-API-Key"] = config.apiKey;
6677
+ }
6678
+ const response = await fetch(url, {
6679
+ method: "POST",
6680
+ headers,
6681
+ body: formData,
6682
+ signal: controller.signal
6683
+ });
6684
+ clearTimeout(timeoutId);
6685
+ if (!response.ok) {
6686
+ const errorData = await response.json().catch(() => ({}));
6687
+ throw new SdkHttpError(
6688
+ errorData.message || `Upload error: ${response.status} ${response.statusText}`,
6689
+ response.status,
6690
+ errorData
6691
+ );
6692
+ }
6693
+ return response.json();
6694
+ } catch (error) {
6695
+ clearTimeout(timeoutId);
6696
+ if (error instanceof SdkHttpError) throw error;
6697
+ const err = error;
6698
+ if (err.name === "AbortError") {
6699
+ throw new SdkHttpError("Upload timeout", 408);
6700
+ }
6701
+ throw new SdkHttpError(`Upload error: ${err.message}`, 0, error);
6702
+ }
6703
+ }
6704
+ const client = {
6705
+ post: (path, body) => request("POST", path, body),
6706
+ get: (path) => request("GET", path),
6707
+ put: (path, body) => request("PUT", path, body),
6708
+ patch: (path, body) => request("PATCH", path, body),
6709
+ delete: (path) => request("DELETE", path),
6710
+ getText,
6711
+ upload: ((path, file, filename, metadata, fieldName) => upload(path, file, filename, metadata, fieldName)),
6712
+ setAuthToken,
6713
+ getAuthToken
6714
+ };
6715
+ return client;
6716
+ }
6717
+ function encodePathParam(param) {
6718
+ return encodeURIComponent(param).replace(/%2F/gi, "");
6719
+ }
6720
+ function isRuleRejected(err) {
6721
+ if (!(err instanceof SdkHttpError)) return false;
6722
+ if (err.statusCode !== 403) return false;
6723
+ const d = err.details;
6724
+ if (d === null || typeof d !== "object") return false;
6725
+ const obj = d;
6726
+ if (obj.error !== "rule_rejected") return false;
6727
+ if (typeof obj.reason !== "string") return false;
6728
+ if (!Array.isArray(obj.ruleAtoms)) return false;
6729
+ return obj.ruleAtoms.every((a) => typeof a === "string");
6730
+ }
6731
+
6559
6732
  // src/discovery/discovery-client.ts
6560
6733
  var DiscoveryClient = class {
6561
6734
  constructor(http) {
@@ -6589,7 +6762,7 @@ var DiscoveryClient = class {
6589
6762
  * try/catch.
6590
6763
  */
6591
6764
  async getClusterByNode(nodeId) {
6592
- return this.http.get(`/discovery/clusters/${encodeURIComponent(nodeId)}`);
6765
+ return this.http.get(`/discovery/clusters/${encodePathParam(nodeId)}`);
6593
6766
  }
6594
6767
  };
6595
6768
  var PlatformImagesClient = class {
@@ -6619,7 +6792,7 @@ var PlatformImagesClient = class {
6619
6792
  * authorized?" queries.
6620
6793
  */
6621
6794
  async get(imageName) {
6622
- return this.http.get(`/discovery/platform-images/${encodeURIComponent(imageName)}`);
6795
+ return this.http.get(`/discovery/platform-images/${encodePathParam(imageName)}`);
6623
6796
  }
6624
6797
  /**
6625
6798
  * `GET /api/v3/discovery/platform-images/:imageName/:version` —
@@ -6628,7 +6801,7 @@ var PlatformImagesClient = class {
6628
6801
  */
6629
6802
  async getVersion(imageName, version) {
6630
6803
  return this.http.get(
6631
- `/discovery/platform-images/${encodeURIComponent(imageName)}/${encodeURIComponent(version)}`
6804
+ `/discovery/platform-images/${encodePathParam(imageName)}/${encodePathParam(version)}`
6632
6805
  );
6633
6806
  }
6634
6807
  /**
@@ -6642,13 +6815,66 @@ var PlatformImagesClient = class {
6642
6815
  */
6643
6816
  async verify(imageName, version, digest) {
6644
6817
  return this.http.get(
6645
- `/discovery/platform-images/${encodeURIComponent(imageName)}/${encodeURIComponent(
6818
+ `/discovery/platform-images/${encodePathParam(imageName)}/${encodePathParam(
6646
6819
  version
6647
6820
  )}/verify?digest=${encodeURIComponent(digest)}`
6648
6821
  );
6649
6822
  }
6650
6823
  };
6651
6824
 
6825
+ // src/network-presets.ts
6826
+ var KNOWN_NETWORKS = {
6827
+ testnet: {
6828
+ bootstrap: ["https://gateway.testnet.hsuite.network"]
6829
+ },
6830
+ mainnet: {
6831
+ // Mainnet entrypoint reserved. The SDK still resolves the name so
6832
+ // upgrade-by-flipping-NETWORK works; the bootstrap URL is the
6833
+ // pre-allocated DNS we own. If mainnet isn't deployed yet, the discovery
6834
+ // fetch will fail at runtime with the same "no seed reachable" error
6835
+ // any unreachable URL produces — the caller learns the network is not
6836
+ // live, rather than getting a baffling "unknown network" TypeScript
6837
+ // error at compile time.
6838
+ bootstrap: ["https://gateway.hsuite.network"]
6839
+ }
6840
+ };
6841
+ function resolveNetwork(name) {
6842
+ const preset = KNOWN_NETWORKS[name];
6843
+ if (!preset) {
6844
+ throw new Error(
6845
+ `Unknown network: "${name}". Known networks: ${Object.keys(KNOWN_NETWORKS).join(", ")}`
6846
+ );
6847
+ }
6848
+ return preset;
6849
+ }
6850
+ function isKnownNetwork(name) {
6851
+ return Object.prototype.hasOwnProperty.call(KNOWN_NETWORKS, name);
6852
+ }
6853
+
6854
+ // src/discovery/resolve-cluster.ts
6855
+ async function resolveClusterEndpoint(config) {
6856
+ const allowInsecure = config.allowInsecure ?? false;
6857
+ const bootstrap = config.bootstrap ? [...config.bootstrap] : config.network ? [...resolveNetwork(config.network).bootstrap] : [];
6858
+ if (bootstrap.length === 0) {
6859
+ return { ok: false, reason: "no-seeds" };
6860
+ }
6861
+ const discovery = new ClusterDiscoveryClient({
6862
+ bootstrap,
6863
+ allowInsecure,
6864
+ trustAnchor: config.trustAnchor ? {
6865
+ network: config.trustAnchor.network,
6866
+ registryTopicId: config.trustAnchor.registryTopicId,
6867
+ mirrorNodeUrl: config.trustAnchor.mirrorNodeUrl,
6868
+ allowInsecure
6869
+ } : void 0
6870
+ });
6871
+ const cluster = await discovery.getRandomCluster();
6872
+ if (!cluster) {
6873
+ return { ok: false, reason: "no-clusters" };
6874
+ }
6875
+ return { ok: true, cluster };
6876
+ }
6877
+
6652
6878
  // src/auth/index.ts
6653
6879
  var auth_exports = {};
6654
6880
  __export(auth_exports, {
@@ -6665,6 +6891,10 @@ var SUPPORTED_AUTH_CHAINS = [
6665
6891
  "stellar",
6666
6892
  "solana"
6667
6893
  ];
6894
+ function toBytes(value) {
6895
+ if (value instanceof Uint8Array) return value;
6896
+ return value.toBytes();
6897
+ }
6668
6898
  function validateValidatorUrl(url, allowInsecure = false) {
6669
6899
  try {
6670
6900
  const parsed = new URL(url);
@@ -6864,275 +7094,90 @@ var ValidatorAuthClient = class {
6864
7094
  }
6865
7095
  }
6866
7096
  /**
6867
- * Sign challenge with Hedera private key
7097
+ * Sign challenge with Hedera private key.
7098
+ *
7099
+ * Structurally typed against the surface of `@hashgraph/sdk`'s
7100
+ * `PrivateKey`. We don't `import` the SDK directly — pulling it into
7101
+ * the smart-engine SDK's runtime would bloat browser bundles and bring
7102
+ * peer-dep churn — but any object with a compatible `sign(...)` method
7103
+ * works.
6868
7104
  *
6869
7105
  * @param challenge - Challenge string from validator
6870
- * @param privateKey - Hedera PrivateKey instance from @hashgraph/sdk
7106
+ * @param privateKey - Hedera PrivateKey instance (or compatible signer)
6871
7107
  * @returns Hex-encoded signature
6872
7108
  */
6873
7109
  signChallengeHedera(challenge, privateKey) {
6874
- const messageBytes = Buffer.from(challenge, "utf-8");
7110
+ const messageBytes = new Uint8Array(Buffer.from(challenge, "utf-8"));
6875
7111
  const signature = privateKey.sign(messageBytes);
6876
- return Buffer.from(signature).toString("hex");
7112
+ return Buffer.from(toBytes(signature)).toString("hex");
6877
7113
  }
6878
7114
  /**
6879
- * Sign challenge with XRPL wallet
7115
+ * Sign challenge with XRPL wallet.
7116
+ *
7117
+ * Structurally typed against the surface of xrpl's `Wallet` — see the
7118
+ * comment on {@link HederaSigner} for the "no direct import" rationale.
7119
+ * Accepts both the modern `{ signedTransaction }` envelope and the
7120
+ * legacy bare-string return shape.
6880
7121
  *
6881
7122
  * @param challenge - Challenge string from validator
6882
- * @param wallet - XRPL Wallet instance from xrpl library
7123
+ * @param wallet - XRPL Wallet instance (or compatible signer)
6883
7124
  * @returns Hex-encoded signature
6884
7125
  */
6885
7126
  signChallengeXRPL(challenge, wallet) {
6886
7127
  const signature = wallet.sign(challenge);
6887
- if (typeof signature === "string" && /^[0-9A-Fa-f]+$/.test(signature)) {
6888
- return signature;
6889
- }
6890
- return Buffer.from(signature).toString("hex");
6891
- }
6892
- /**
6893
- * Complete authentication flow in one call
6894
- *
6895
- * @param validatorUrl - Validator API base URL
6896
- * @param chain - Blockchain type
6897
- * @param address - Wallet address
6898
- * @param publicKey - Public key (hex)
6899
- * @param signFn - Function to sign the challenge
6900
- * @param metadata - Optional metadata
6901
- * @returns Session token and info
6902
- */
6903
- async authenticateWithSigner(validatorUrl, chain, address, publicKey, signFn, metadata) {
6904
- const challengeResponse = await this.requestChallenge(validatorUrl, chain, address);
6905
- const signature = await signFn(challengeResponse.challenge);
6906
- return this.authenticate(validatorUrl, {
6907
- chain,
6908
- address,
6909
- publicKey,
6910
- signature,
6911
- challenge: challengeResponse.challenge,
6912
- metadata
6913
- });
6914
- }
6915
- };
6916
- var ValidatorAuthError = class extends Error {
6917
- constructor(message, statusCode, details) {
6918
- super(message);
6919
- this.statusCode = statusCode;
6920
- this.details = details;
6921
- this.name = "ValidatorAuthError";
6922
- }
6923
- statusCode;
6924
- details;
6925
- };
6926
- var { sign: rippleSign } = require_dist2();
6927
- function createXrplWeb3Signer(seed) {
6928
- const wallet = xrpl.Wallet.fromSeed(seed);
6929
- return {
6930
- chain: "xrpl",
6931
- address: wallet.classicAddress,
6932
- publicKey: wallet.publicKey,
6933
- signFn: (challenge) => {
6934
- const messageHex = Buffer.from(challenge, "utf-8").toString("hex").toUpperCase();
6935
- return rippleSign(messageHex, wallet.privateKey);
6936
- },
6937
- wallet
6938
- };
6939
- }
6940
-
6941
- // src/http/index.ts
6942
- var SdkHttpError = class extends Error {
6943
- constructor(message, statusCode, details) {
6944
- super(message);
6945
- this.statusCode = statusCode;
6946
- this.details = details;
6947
- this.name = "SdkHttpError";
6948
- }
6949
- statusCode;
6950
- details;
6951
- };
6952
- function createHttpClient(config) {
6953
- const timeout = config.timeout ?? 3e4;
6954
- function getHeaders(contentType) {
6955
- const headers = {};
6956
- if (contentType) {
6957
- headers["Content-Type"] = contentType;
6958
- }
6959
- if (config.authToken) {
6960
- headers["Authorization"] = `Bearer ${config.authToken}`;
6961
- }
6962
- if (config.apiKey) {
6963
- headers["X-API-Key"] = config.apiKey;
6964
- }
6965
- return headers;
6966
- }
6967
- function setAuthToken(token) {
6968
- config.authToken = token;
6969
- }
6970
- async function request(method, path, body) {
6971
- const url = `${config.baseUrl}${path}`;
6972
- const controller = new AbortController();
6973
- const timeoutId = setTimeout(() => controller.abort(), timeout);
6974
- try {
6975
- const init = {
6976
- method,
6977
- headers: getHeaders("application/json"),
6978
- signal: controller.signal
6979
- };
6980
- if (body !== void 0) {
6981
- init.body = JSON.stringify(body);
6982
- }
6983
- const response = await fetch(url, init);
6984
- clearTimeout(timeoutId);
6985
- if (!response.ok) {
6986
- const errorData = await response.json().catch(() => ({}));
6987
- throw new SdkHttpError(
6988
- errorData.message || `API error: ${response.status} ${response.statusText}`,
6989
- response.status,
6990
- errorData
6991
- );
6992
- }
6993
- const text = await response.text();
6994
- if (!text) return void 0;
6995
- return JSON.parse(text);
6996
- } catch (error) {
6997
- clearTimeout(timeoutId);
6998
- if (error instanceof SdkHttpError) throw error;
6999
- const err = error;
7000
- if (err.name === "AbortError") {
7001
- throw new SdkHttpError("Request timeout", 408);
7002
- }
7003
- throw new SdkHttpError(`Network error: ${err.message}`, 0, error);
7004
- }
7005
- }
7006
- async function getText(path) {
7007
- const url = `${config.baseUrl}${path}`;
7008
- const controller = new AbortController();
7009
- const timeoutId = setTimeout(() => controller.abort(), timeout);
7010
- try {
7011
- const response = await fetch(url, {
7012
- method: "GET",
7013
- headers: getHeaders(),
7014
- signal: controller.signal
7015
- });
7016
- clearTimeout(timeoutId);
7017
- if (!response.ok) {
7018
- const errBody = await response.json().catch(() => ({}));
7019
- throw new SdkHttpError(
7020
- errBody.message || `API error: ${response.status} ${response.statusText}`,
7021
- response.status,
7022
- errBody
7023
- );
7024
- }
7025
- return await response.text();
7026
- } catch (error) {
7027
- clearTimeout(timeoutId);
7028
- if (error instanceof SdkHttpError) throw error;
7029
- const err = error;
7030
- if (err.name === "AbortError") {
7031
- throw new SdkHttpError("Request timeout", 408);
7032
- }
7033
- throw new SdkHttpError(`Network error: ${err.message}`, 0, error);
7034
- }
7035
- }
7036
- async function upload(path, file, filename, metadata, fieldName = "file") {
7037
- const url = `${config.baseUrl}${path}`;
7038
- const controller = new AbortController();
7039
- const timeoutId = setTimeout(() => controller.abort(), timeout * 2);
7040
- try {
7041
- const formData = new FormData();
7042
- const blob = file instanceof Blob ? file : new Blob([new Uint8Array(file)]);
7043
- formData.append(fieldName, blob, filename);
7044
- if (metadata) {
7045
- for (const [key, value] of Object.entries(metadata)) {
7046
- formData.append(key, value);
7047
- }
7048
- }
7049
- const headers = {};
7050
- if (config.authToken) {
7051
- headers["Authorization"] = `Bearer ${config.authToken}`;
7052
- }
7053
- if (config.apiKey) {
7054
- headers["X-API-Key"] = config.apiKey;
7055
- }
7056
- const response = await fetch(url, {
7057
- method: "POST",
7058
- headers,
7059
- body: formData,
7060
- signal: controller.signal
7061
- });
7062
- clearTimeout(timeoutId);
7063
- if (!response.ok) {
7064
- const errorData = await response.json().catch(() => ({}));
7065
- throw new SdkHttpError(
7066
- errorData.message || `Upload error: ${response.status} ${response.statusText}`,
7067
- response.status,
7068
- errorData
7069
- );
7070
- }
7071
- return response.json();
7072
- } catch (error) {
7073
- clearTimeout(timeoutId);
7074
- if (error instanceof SdkHttpError) throw error;
7075
- const err = error;
7076
- if (err.name === "AbortError") {
7077
- throw new SdkHttpError("Upload timeout", 408);
7078
- }
7079
- throw new SdkHttpError(`Upload error: ${err.message}`, 0, error);
7128
+ if (typeof signature === "string") {
7129
+ if (/^[0-9A-Fa-f]+$/.test(signature)) return signature;
7130
+ return Buffer.from(signature).toString("hex");
7080
7131
  }
7132
+ return signature.signedTransaction;
7081
7133
  }
7082
- const client = {
7083
- post: (path, body) => request("POST", path, body),
7084
- get: (path) => request("GET", path),
7085
- put: (path, body) => request("PUT", path, body),
7086
- patch: (path, body) => request("PATCH", path, body),
7087
- delete: (path) => request("DELETE", path),
7088
- getText,
7089
- upload: ((path, file, filename, metadata, fieldName) => upload(path, file, filename, metadata, fieldName)),
7090
- setAuthToken
7091
- };
7092
- return client;
7093
- }
7094
- function encodePathParam(param) {
7095
- return encodeURIComponent(param).replace(/%2F/gi, "");
7096
- }
7097
- function isRuleRejected(err) {
7098
- if (!(err instanceof SdkHttpError)) return false;
7099
- if (err.statusCode !== 403) return false;
7100
- const d = err.details;
7101
- if (d === null || typeof d !== "object") return false;
7102
- const obj = d;
7103
- if (obj.error !== "rule_rejected") return false;
7104
- if (typeof obj.reason !== "string") return false;
7105
- if (!Array.isArray(obj.ruleAtoms)) return false;
7106
- return obj.ruleAtoms.every((a) => typeof a === "string");
7107
- }
7108
-
7109
- // src/network-presets.ts
7110
- var KNOWN_NETWORKS = {
7111
- testnet: {
7112
- bootstrap: ["https://gateway.testnet.hsuite.network"]
7113
- },
7114
- mainnet: {
7115
- // Mainnet entrypoint reserved. The SDK still resolves the name so
7116
- // upgrade-by-flipping-NETWORK works; the bootstrap URL is the
7117
- // pre-allocated DNS we own. If mainnet isn't deployed yet, the discovery
7118
- // fetch will fail at runtime with the same "no seed reachable" error
7119
- // any unreachable URL produces — the caller learns the network is not
7120
- // live, rather than getting a baffling "unknown network" TypeScript
7121
- // error at compile time.
7122
- bootstrap: ["https://gateway.hsuite.network"]
7134
+ /**
7135
+ * Complete authentication flow in one call
7136
+ *
7137
+ * @param validatorUrl - Validator API base URL
7138
+ * @param chain - Blockchain type
7139
+ * @param address - Wallet address
7140
+ * @param publicKey - Public key (hex)
7141
+ * @param signFn - Function to sign the challenge
7142
+ * @param metadata - Optional metadata
7143
+ * @returns Session token and info
7144
+ */
7145
+ async authenticateWithSigner(validatorUrl, chain, address, publicKey, signFn, metadata) {
7146
+ const challengeResponse = await this.requestChallenge(validatorUrl, chain, address);
7147
+ const signature = await signFn(challengeResponse.challenge);
7148
+ return this.authenticate(validatorUrl, {
7149
+ chain,
7150
+ address,
7151
+ publicKey,
7152
+ signature,
7153
+ challenge: challengeResponse.challenge,
7154
+ metadata
7155
+ });
7123
7156
  }
7124
7157
  };
7125
- function resolveNetwork(name) {
7126
- const preset = KNOWN_NETWORKS[name];
7127
- if (!preset) {
7128
- throw new Error(
7129
- `Unknown network: "${name}". Known networks: ${Object.keys(KNOWN_NETWORKS).join(", ")}`
7130
- );
7158
+ var ValidatorAuthError = class extends Error {
7159
+ constructor(message, statusCode, details) {
7160
+ super(message);
7161
+ this.statusCode = statusCode;
7162
+ this.details = details;
7163
+ this.name = "ValidatorAuthError";
7131
7164
  }
7132
- return preset;
7133
- }
7134
- function isKnownNetwork(name) {
7135
- return Object.prototype.hasOwnProperty.call(KNOWN_NETWORKS, name);
7165
+ statusCode;
7166
+ details;
7167
+ };
7168
+ var { sign: rippleSign } = require_dist2();
7169
+ function createXrplWeb3Signer(seed) {
7170
+ const wallet = xrpl.Wallet.fromSeed(seed);
7171
+ return {
7172
+ chain: "xrpl",
7173
+ address: wallet.classicAddress,
7174
+ publicKey: wallet.publicKey,
7175
+ signFn: (challenge) => {
7176
+ const messageHex = Buffer.from(challenge, "utf-8").toString("hex").toUpperCase();
7177
+ return rippleSign(messageHex, wallet.privateKey);
7178
+ },
7179
+ wallet
7180
+ };
7136
7181
  }
7137
7182
 
7138
7183
  // src/subscription/index.ts
@@ -7156,13 +7201,13 @@ var SubscriptionClient = class {
7156
7201
  * Get subscription status by app ID
7157
7202
  */
7158
7203
  async getStatus(appId) {
7159
- return this.http.get(`/subscription/status/${encodeURIComponent(appId)}`);
7204
+ return this.http.get(`/subscription/status/${encodePathParam(appId)}`);
7160
7205
  }
7161
7206
  /**
7162
7207
  * Mint subscription NFT after deposit is confirmed
7163
7208
  */
7164
7209
  async mintNft(appId) {
7165
- return this.http.post(`/subscription/mint/${encodeURIComponent(appId)}`, {});
7210
+ return this.http.post(`/subscription/mint/${encodePathParam(appId)}`, {});
7166
7211
  }
7167
7212
  /**
7168
7213
  * Renew subscription by extending period
@@ -7231,13 +7276,13 @@ var SubscriptionClient = class {
7231
7276
  * List subscriptions by status
7232
7277
  */
7233
7278
  async listByStatus(status) {
7234
- return this.http.get(`/subscription/list/status/${encodeURIComponent(status)}`);
7279
+ return this.http.get(`/subscription/list/status/${encodePathParam(status)}`);
7235
7280
  }
7236
7281
  /**
7237
7282
  * Get subscription balance
7238
7283
  */
7239
7284
  async getBalance(appId) {
7240
- return this.http.get(`/subscription/balance/${encodeURIComponent(appId)}`);
7285
+ return this.http.get(`/subscription/balance/${encodePathParam(appId)}`);
7241
7286
  }
7242
7287
  // ─── Tier-Change Endpoints ────────────────────────────────────────────────
7243
7288
  /**
@@ -7269,19 +7314,19 @@ var SubscriptionClient = class {
7269
7314
  */
7270
7315
  async getActiveFor(walletAddress) {
7271
7316
  return this.http.get(
7272
- `/subscription/active-for/${encodeURIComponent(walletAddress)}`
7317
+ `/subscription/active-for/${encodePathParam(walletAddress)}`
7273
7318
  );
7274
7319
  }
7275
7320
  /** Today's consumption breakdown by category for an app. Owner-only. */
7276
7321
  async getUsage(appId) {
7277
- return this.http.get(`/subscription/usage/${encodeURIComponent(appId)}`);
7322
+ return this.http.get(`/subscription/usage/${encodePathParam(appId)}`);
7278
7323
  }
7279
7324
  /**
7280
7325
  * Current usage with overage info: usage percent, grace status,
7281
7326
  * upgrade suggestion, projected days until limit. Owner-only.
7282
7327
  */
7283
7328
  async getUsageStatus(appId) {
7284
- return this.http.get(`/subscription/usage/status/${encodeURIComponent(appId)}`);
7329
+ return this.http.get(`/subscription/usage/status/${encodePathParam(appId)}`);
7285
7330
  }
7286
7331
  /**
7287
7332
  * Subscription balance deduction history. Pagination + ISO-8601 range
@@ -7295,7 +7340,7 @@ var SubscriptionClient = class {
7295
7340
  if (options?.to) params.append("to", options.to);
7296
7341
  const qs = params.toString();
7297
7342
  return this.http.get(
7298
- `/subscription/billing/${encodeURIComponent(appId)}${qs ? `?${qs}` : ""}`
7343
+ `/subscription/billing/${encodePathParam(appId)}${qs ? `?${qs}` : ""}`
7299
7344
  );
7300
7345
  }
7301
7346
  /**
@@ -7338,7 +7383,7 @@ var TSSClient = class {
7338
7383
  * Get entity details by ID
7339
7384
  */
7340
7385
  async getEntity(entityId) {
7341
- return this.http.get(`/tss/entity/${encodeURIComponent(entityId)}`);
7386
+ return this.http.get(`/tss/entity/${encodePathParam(entityId)}`);
7342
7387
  }
7343
7388
  /**
7344
7389
  * Sign a transaction using MPC.
@@ -7395,7 +7440,7 @@ var TSSClient = class {
7395
7440
  * Get multi-sig transaction status by transaction ID
7396
7441
  */
7397
7442
  async getMultiSigStatus(txId) {
7398
- return this.http.get(`/tss/multisig/transactions/${encodeURIComponent(txId)}`);
7443
+ return this.http.get(`/tss/multisig/transactions/${encodePathParam(txId)}`);
7399
7444
  }
7400
7445
  /**
7401
7446
  * Async-job variant of {@link createEntity}.
@@ -7419,7 +7464,7 @@ var TSSClient = class {
7419
7464
  * {@link createEntityAsync} or {@link reshareClusterAsync}.
7420
7465
  */
7421
7466
  async getJob(jobId) {
7422
- return this.http.get(`/tss/jobs/${encodeURIComponent(jobId)}`);
7467
+ return this.http.get(`/tss/jobs/${encodePathParam(jobId)}`);
7423
7468
  }
7424
7469
  /**
7425
7470
  * Sign a hex payload as smart-app entity `appId` via the cluster's TSS
@@ -7431,7 +7476,7 @@ var TSSClient = class {
7431
7476
  * - ≥32 bytes, ≤8KB
7432
7477
  */
7433
7478
  async signForApp(appId, request) {
7434
- return this.http.post(`/tss/entity/${encodeURIComponent(appId)}/sign`, request);
7479
+ return this.http.post(`/tss/entity/${encodePathParam(appId)}/sign`, request);
7435
7480
  }
7436
7481
  };
7437
7482
 
@@ -7456,31 +7501,31 @@ var IPFSClient = class {
7456
7501
  * Pin content by CID to ensure it persists
7457
7502
  */
7458
7503
  async pin(cid) {
7459
- return this.http.post(`/ipfs/pin/${encodeURIComponent(cid)}`, {});
7504
+ return this.http.post(`/ipfs/pin/${encodePathParam(cid)}`, {});
7460
7505
  }
7461
7506
  /**
7462
7507
  * Unpin content by CID
7463
7508
  */
7464
7509
  async unpin(cid) {
7465
- return this.http.delete(`/ipfs/unpin/${encodeURIComponent(cid)}`);
7510
+ return this.http.delete(`/ipfs/unpin/${encodePathParam(cid)}`);
7466
7511
  }
7467
7512
  /**
7468
7513
  * Get a file by CID
7469
7514
  */
7470
7515
  async getFile(cid) {
7471
- return this.http.get(`/ipfs/file/${encodeURIComponent(cid)}`);
7516
+ return this.http.get(`/ipfs/file/${encodePathParam(cid)}`);
7472
7517
  }
7473
7518
  /**
7474
7519
  * Get raw content by CID
7475
7520
  */
7476
7521
  async getContent(cid) {
7477
- return this.http.get(`/ipfs/${encodeURIComponent(cid)}`);
7522
+ return this.http.get(`/ipfs/${encodePathParam(cid)}`);
7478
7523
  }
7479
7524
  /**
7480
7525
  * Get file metadata by CID
7481
7526
  */
7482
7527
  async getMetadata(cid) {
7483
- return this.http.get(`/ipfs/metadata/${encodeURIComponent(cid)}`);
7528
+ return this.http.get(`/ipfs/metadata/${encodePathParam(cid)}`);
7484
7529
  }
7485
7530
  /**
7486
7531
  * List all pinned content
@@ -7538,7 +7583,7 @@ var HederaTssClient = class {
7538
7583
  var HederaTransactionsClient = class {
7539
7584
  constructor(http, tssHttp) {
7540
7585
  this.http = http;
7541
- this.tss = new HederaTssClient(tssHttp ?? http);
7586
+ this.tss = new HederaTssClient(tssHttp);
7542
7587
  }
7543
7588
  http;
7544
7589
  /**
@@ -7549,10 +7594,10 @@ var HederaTransactionsClient = class {
7549
7594
  * - `client.hedera.tss.createTopic(...)` makes the cluster sign+submit in one call.
7550
7595
  *
7551
7596
  * `tssHttp` is the validator's `/api/v3`-rooted HTTP client (different from
7552
- * the `/api/transactions` one this class uses for prepare paths). When the
7553
- * legacy single-arg constructor is used (no tssHttp passed), `tss` falls
7554
- * back to the same `http` instance for backwards compatibility — callers
7555
- * outside `SmartEngineClient` rarely use the TSS surface.
7597
+ * the `/api/transactions` one this class uses for prepare paths). Both
7598
+ * clients are required the previous single-arg fallback to `http` was
7599
+ * unreachable through `SmartEngineClient` (the only call site always
7600
+ * passes both).
7556
7601
  */
7557
7602
  tss;
7558
7603
  /** Prepare an HCS topic creation transaction. */
@@ -7733,7 +7778,7 @@ var SnapshotsClient = class {
7733
7778
  */
7734
7779
  async generate(tokenId, options) {
7735
7780
  return this.http.post(
7736
- `/snapshots/generate/${encodeURIComponent(tokenId)}`,
7781
+ `/snapshots/generate/${encodePathParam(tokenId)}`,
7737
7782
  options || {}
7738
7783
  );
7739
7784
  }
@@ -7741,7 +7786,7 @@ var SnapshotsClient = class {
7741
7786
  * Get snapshot details by ID
7742
7787
  */
7743
7788
  async get(snapshotId) {
7744
- return this.http.get(`/snapshots/${encodeURIComponent(snapshotId)}`);
7789
+ return this.http.get(`/snapshots/${encodePathParam(snapshotId)}`);
7745
7790
  }
7746
7791
  /**
7747
7792
  * List snapshots for a token
@@ -7752,7 +7797,7 @@ var SnapshotsClient = class {
7752
7797
  if (pagination?.limit !== void 0) params.set("limit", String(pagination.limit));
7753
7798
  const qs = params.toString();
7754
7799
  return this.http.get(
7755
- `/snapshots/token/${encodeURIComponent(tokenId)}${qs ? `?${qs}` : ""}`
7800
+ `/snapshots/token/${encodePathParam(tokenId)}${qs ? `?${qs}` : ""}`
7756
7801
  );
7757
7802
  }
7758
7803
  /**
@@ -7764,7 +7809,7 @@ var SnapshotsClient = class {
7764
7809
  async download(snapshotId, format) {
7765
7810
  const params = format ? `?format=${encodeURIComponent(format)}` : "";
7766
7811
  return this.http.get(
7767
- `/snapshots/${encodeURIComponent(snapshotId)}/download${params}`
7812
+ `/snapshots/${encodePathParam(snapshotId)}/download${params}`
7768
7813
  );
7769
7814
  }
7770
7815
  };
@@ -7951,20 +7996,20 @@ var SettlementClient = class {
7951
7996
  * Get the current status of a settlement by ID.
7952
7997
  */
7953
7998
  async getStatus(settlementId) {
7954
- return this.http.get(`/settlement/${encodeURIComponent(settlementId)}/status`);
7999
+ return this.http.get(`/settlement/${encodePathParam(settlementId)}/status`);
7955
8000
  }
7956
8001
  /**
7957
8002
  * Confirm that XRP has landed on the destination address.
7958
8003
  * Advances the settlement to the next processing step.
7959
8004
  */
7960
8005
  async confirmXrpLanded(settlementId) {
7961
- return this.http.post(`/settlement/${encodeURIComponent(settlementId)}/confirm-xrp`, {});
8006
+ return this.http.post(`/settlement/${encodePathParam(settlementId)}/confirm-xrp`, {});
7962
8007
  }
7963
8008
  /**
7964
8009
  * Get settlement history for a given entity.
7965
8010
  */
7966
8011
  async getHistory(entityId) {
7967
- return this.http.get(`/settlement/history/${encodeURIComponent(entityId)}`);
8012
+ return this.http.get(`/settlement/history/${encodePathParam(entityId)}`);
7968
8013
  }
7969
8014
  };
7970
8015
 
@@ -8020,39 +8065,39 @@ var DaoDashboardClient = class {
8020
8065
  /** Aggregated dashboard counters for a user's governance home screen. */
8021
8066
  async getStats(userAddress) {
8022
8067
  return this.http.get(
8023
- `/dao/dashboard/stats/${encodeURIComponent(userAddress)}`
8068
+ `/dao/dashboard/stats/${encodePathParam(userAddress)}`
8024
8069
  );
8025
8070
  }
8026
8071
  /** Active proposals across every DAO the user belongs to, with vote state. */
8027
8072
  async getActiveProposals(userAddress) {
8028
8073
  return this.http.get(
8029
- `/dao/dashboard/active-proposals/${encodeURIComponent(userAddress)}`
8074
+ `/dao/dashboard/active-proposals/${encodePathParam(userAddress)}`
8030
8075
  );
8031
8076
  }
8032
8077
  /** Paginated vote history across DAOs. */
8033
8078
  async getVoteHistory(userAddress, opts = {}) {
8034
8079
  const qs = buildQuery({ limit: opts.limit, offset: opts.offset });
8035
8080
  return this.http.get(
8036
- `/dao/dashboard/vote-history/${encodeURIComponent(userAddress)}${qs}`
8081
+ `/dao/dashboard/vote-history/${encodePathParam(userAddress)}${qs}`
8037
8082
  );
8038
8083
  }
8039
8084
  /** Activity feed (proposal-created/vote-cast/etc.) across user's DAOs. */
8040
8085
  async getActivity(userAddress, opts = {}) {
8041
8086
  const qs = buildQuery({ limit: opts.limit, daoId: opts.daoId });
8042
8087
  return this.http.get(
8043
- `/dao/dashboard/activity/${encodeURIComponent(userAddress)}${qs}`
8088
+ `/dao/dashboard/activity/${encodePathParam(userAddress)}${qs}`
8044
8089
  );
8045
8090
  }
8046
8091
  /** Items the user must act on (sign prepared messages, claim NFTs, …). */
8047
8092
  async getPendingActions(userAddress) {
8048
8093
  return this.http.get(
8049
- `/dao/dashboard/pending-actions/${encodeURIComponent(userAddress)}`
8094
+ `/dao/dashboard/pending-actions/${encodePathParam(userAddress)}`
8050
8095
  );
8051
8096
  }
8052
8097
  /** Governance impact metrics — weight delivered, success rate, streak. */
8053
8098
  async getImpact(userAddress) {
8054
8099
  return this.http.get(
8055
- `/dao/dashboard/impact/${encodeURIComponent(userAddress)}`
8100
+ `/dao/dashboard/impact/${encodePathParam(userAddress)}`
8056
8101
  );
8057
8102
  }
8058
8103
  };
@@ -8068,13 +8113,13 @@ function buildQuery2(params) {
8068
8113
  return qs ? `?${qs}` : "";
8069
8114
  }
8070
8115
  function encodeDaoId(daoId) {
8071
- return encodeURIComponent(daoId);
8116
+ return encodePathParam(daoId);
8072
8117
  }
8073
8118
  function encodeProposalId(proposalId) {
8074
- return encodeURIComponent(proposalId);
8119
+ return encodePathParam(proposalId);
8075
8120
  }
8076
8121
  function encodeAddress(address) {
8077
- return encodeURIComponent(address);
8122
+ return encodePathParam(address);
8078
8123
  }
8079
8124
  var DaoClient = class {
8080
8125
  constructor(http) {
@@ -8355,7 +8400,7 @@ var AgentsClient = class {
8355
8400
  }
8356
8401
  /** Get agent details */
8357
8402
  async get(agentId) {
8358
- return this.http.get(`/api/agents/${encodeURIComponent(agentId)}`);
8403
+ return this.http.get(`/api/agents/${encodePathParam(agentId)}`);
8359
8404
  }
8360
8405
  /** List all agents */
8361
8406
  async list() {
@@ -8367,33 +8412,33 @@ var AgentsClient = class {
8367
8412
  * the caller is expected to sign and submit the prepared bytes.
8368
8413
  */
8369
8414
  async fund(agentId, request) {
8370
- return this.http.post(`/api/agents/${encodeURIComponent(agentId)}/fund`, request);
8415
+ return this.http.post(`/api/agents/${encodePathParam(agentId)}/fund`, request);
8371
8416
  }
8372
8417
  /**
8373
8418
  * Execute a trade (agent-wallet OR owner). Returns a
8374
8419
  * `PreparedTransactionResponse` wrapped in a `success: true` envelope.
8375
8420
  */
8376
8421
  async trade(agentId, request) {
8377
- return this.http.post(`/api/agents/${encodeURIComponent(agentId)}/trade`, request);
8422
+ return this.http.post(`/api/agents/${encodePathParam(agentId)}/trade`, request);
8378
8423
  }
8379
8424
  /**
8380
8425
  * Withdraw from agent treasury (owner-only). Returns a
8381
8426
  * `PreparedTransactionResponse` wrapped in a `success: true` envelope.
8382
8427
  */
8383
8428
  async withdraw(agentId, request) {
8384
- return this.http.post(`/api/agents/${encodeURIComponent(agentId)}/withdraw`, request);
8429
+ return this.http.post(`/api/agents/${encodePathParam(agentId)}/withdraw`, request);
8385
8430
  }
8386
8431
  /** Pause an agent */
8387
8432
  async pause(agentId) {
8388
- return this.http.post(`/api/agents/${encodeURIComponent(agentId)}/pause`, {});
8433
+ return this.http.post(`/api/agents/${encodePathParam(agentId)}/pause`, {});
8389
8434
  }
8390
8435
  /** Resume a paused agent */
8391
8436
  async resume(agentId) {
8392
- return this.http.post(`/api/agents/${encodeURIComponent(agentId)}/resume`, {});
8437
+ return this.http.post(`/api/agents/${encodePathParam(agentId)}/resume`, {});
8393
8438
  }
8394
8439
  /** Revoke an agent (permanent) */
8395
8440
  async revoke(agentId) {
8396
- return this.http.post(`/api/agents/${encodeURIComponent(agentId)}/revoke`, {});
8441
+ return this.http.post(`/api/agents/${encodePathParam(agentId)}/revoke`, {});
8397
8442
  }
8398
8443
  /**
8399
8444
  * Update agent rules.
@@ -8404,23 +8449,23 @@ var AgentsClient = class {
8404
8449
  * the verb mismatch.
8405
8450
  */
8406
8451
  async updateRules(agentId, rules) {
8407
- return this.http.patch(`/api/agents/${encodeURIComponent(agentId)}/rules`, rules);
8452
+ return this.http.patch(`/api/agents/${encodePathParam(agentId)}/rules`, rules);
8408
8453
  }
8409
8454
  /** Get agent events */
8410
8455
  async getEvents(agentId) {
8411
- return this.http.get(`/api/agents/${encodeURIComponent(agentId)}/events`);
8456
+ return this.http.get(`/api/agents/${encodePathParam(agentId)}/events`);
8412
8457
  }
8413
8458
  /** Get agent balances across chains */
8414
8459
  async getBalances(agentId) {
8415
- return this.http.get(`/api/agents/${encodeURIComponent(agentId)}/balances`);
8460
+ return this.http.get(`/api/agents/${encodePathParam(agentId)}/balances`);
8416
8461
  }
8417
8462
  /** Approve a pending agent operation */
8418
8463
  async approve(agentId, operationId) {
8419
- return this.http.post(`/api/agents/${encodeURIComponent(agentId)}/approve/${encodeURIComponent(operationId)}`, {});
8464
+ return this.http.post(`/api/agents/${encodePathParam(agentId)}/approve/${encodePathParam(operationId)}`, {});
8420
8465
  }
8421
8466
  /** Reject a pending agent operation */
8422
8467
  async reject(agentId, operationId) {
8423
- return this.http.post(`/api/agents/${encodeURIComponent(agentId)}/reject/${encodeURIComponent(operationId)}`, {});
8468
+ return this.http.post(`/api/agents/${encodePathParam(agentId)}/reject/${encodePathParam(operationId)}`, {});
8424
8469
  }
8425
8470
  };
8426
8471
 
@@ -8459,7 +8504,7 @@ var DeploymentClient = class {
8459
8504
  */
8460
8505
  async uploadFrontend(appId, bundle, filename = "bundle.tar.gz") {
8461
8506
  return this.http.upload(
8462
- `/api/deployment/apps/${encodeURIComponent(appId)}/frontend`,
8507
+ `/api/deployment/apps/${encodePathParam(appId)}/frontend`,
8463
8508
  bundle,
8464
8509
  filename,
8465
8510
  void 0,
@@ -8473,20 +8518,20 @@ var DeploymentClient = class {
8473
8518
  * until `runtime.runtimeState === 'RUNNING'` for the URL to be live.
8474
8519
  */
8475
8520
  async deploy(appId, request) {
8476
- return this.http.post(`/api/deployment/apps/${encodeURIComponent(appId)}/deploy`, request);
8521
+ return this.http.post(`/api/deployment/apps/${encodePathParam(appId)}/deploy`, request);
8477
8522
  }
8478
8523
  /**
8479
8524
  * Roll back to a previously-deployed image tag (must exist in
8480
8525
  * `runtime.deploymentHistory[]`).
8481
8526
  */
8482
8527
  async rollback(appId, request) {
8483
- return this.http.post(`/api/deployment/apps/${encodeURIComponent(appId)}/rollback`, request);
8528
+ return this.http.post(`/api/deployment/apps/${encodePathParam(appId)}/rollback`, request);
8484
8529
  }
8485
8530
  /**
8486
8531
  * Live combined lifecycle + runtime status of an app.
8487
8532
  */
8488
8533
  async status(appId) {
8489
- return this.http.get(`/api/deployment/apps/${encodeURIComponent(appId)}/status`);
8534
+ return this.http.get(`/api/deployment/apps/${encodePathParam(appId)}/status`);
8490
8535
  }
8491
8536
  /**
8492
8537
  * List all deployed apps for the authenticated developer.
@@ -8498,31 +8543,31 @@ var DeploymentClient = class {
8498
8543
  * Get app details.
8499
8544
  */
8500
8545
  async get(appId) {
8501
- return this.http.get(`/api/deployment/apps/${encodeURIComponent(appId)}`);
8546
+ return this.http.get(`/api/deployment/apps/${encodePathParam(appId)}`);
8502
8547
  }
8503
8548
  /**
8504
8549
  * Update app configuration. Runtime effect lands in PR-H.
8505
8550
  */
8506
8551
  async update(appId, updates) {
8507
- return this.http.put(`/api/deployment/apps/${encodeURIComponent(appId)}`, updates);
8552
+ return this.http.put(`/api/deployment/apps/${encodePathParam(appId)}`, updates);
8508
8553
  }
8509
8554
  /**
8510
8555
  * Delete an app. Runtime effect (namespace teardown) lands in PR-H.
8511
8556
  */
8512
8557
  async delete(appId) {
8513
- return this.http.delete(`/api/deployment/apps/${encodeURIComponent(appId)}`);
8558
+ return this.http.delete(`/api/deployment/apps/${encodePathParam(appId)}`);
8514
8559
  }
8515
8560
  /**
8516
8561
  * Suspend an app. Runtime effect (scale to zero) lands in PR-H.
8517
8562
  */
8518
8563
  async suspend(appId) {
8519
- return this.http.post(`/api/deployment/apps/${encodeURIComponent(appId)}/suspend`, {});
8564
+ return this.http.post(`/api/deployment/apps/${encodePathParam(appId)}/suspend`, {});
8520
8565
  }
8521
8566
  /**
8522
8567
  * Resume a suspended app. Runtime effect (scale back up) lands in PR-H.
8523
8568
  */
8524
8569
  async resume(appId) {
8525
- return this.http.post(`/api/deployment/apps/${encodeURIComponent(appId)}/resume`, {});
8570
+ return this.http.post(`/api/deployment/apps/${encodePathParam(appId)}/resume`, {});
8526
8571
  }
8527
8572
  /**
8528
8573
  * Get deployment statistics.
@@ -8549,7 +8594,7 @@ var DeploymentClient = class {
8549
8594
  * CGNAT / cloud metadata destinations (SSRF guard).
8550
8595
  */
8551
8596
  async setWebhook(appId, webhookUrl) {
8552
- return this.http.put(`/api/deployment/apps/${encodeURIComponent(appId)}/webhook`, {
8597
+ return this.http.put(`/api/deployment/apps/${encodePathParam(appId)}/webhook`, {
8553
8598
  webhookUrl
8554
8599
  });
8555
8600
  }
@@ -8565,7 +8610,7 @@ var DeploymentClient = class {
8565
8610
  * exposition format.
8566
8611
  */
8567
8612
  async getMetrics(appId) {
8568
- return this.http.getText(`/api/deployment/apps/${encodeURIComponent(appId)}/metrics`);
8613
+ return this.http.getText(`/api/deployment/apps/${encodePathParam(appId)}/metrics`);
8569
8614
  }
8570
8615
  /**
8571
8616
  * Rotate the smart-app's tenant-secret KEK (ADR-011 Phase 6).
@@ -8576,7 +8621,7 @@ var DeploymentClient = class {
8576
8621
  */
8577
8622
  async rotateKek(appId) {
8578
8623
  return this.http.post(
8579
- `/api/deployment/apps/${encodeURIComponent(appId)}/credentials/rotate-kek`,
8624
+ `/api/deployment/apps/${encodePathParam(appId)}/credentials/rotate-kek`,
8580
8625
  {}
8581
8626
  );
8582
8627
  }
@@ -8590,7 +8635,7 @@ var DeploymentClient = class {
8590
8635
  */
8591
8636
  async revokeKek(appId, version) {
8592
8637
  return this.http.post(
8593
- `/api/deployment/apps/${encodeURIComponent(appId)}/credentials/revoke-kek`,
8638
+ `/api/deployment/apps/${encodePathParam(appId)}/credentials/revoke-kek`,
8594
8639
  { version }
8595
8640
  );
8596
8641
  }
@@ -8794,16 +8839,6 @@ var TokensClient = class {
8794
8839
  async getMigrationsForToken(tokenId) {
8795
8840
  return this.http.get(`/tokens/${encodePathParam(tokenId)}/migrations`);
8796
8841
  }
8797
- /**
8798
- * Get token details. NOTE: collides with `client.getTokenInfo(...)` —
8799
- * see the class JSDoc above for the route-order details. Prefer
8800
- * `client.getTokenInfo(...)` unless you have a reason to call this one.
8801
- */
8802
- async getDetails(chain, tokenId) {
8803
- return this.http.get(
8804
- `/tokens/${encodePathParam(chain)}/${encodePathParam(tokenId)}`
8805
- );
8806
- }
8807
8842
  };
8808
8843
 
8809
8844
  // src/operator/index.ts
@@ -9036,30 +9071,25 @@ var SmartEngineClient = class _SmartEngineClient {
9036
9071
  */
9037
9072
  static async connectToCluster(config) {
9038
9073
  const allowInsecure = config.allowInsecure ?? false;
9039
- const bootstrap = config.bootstrap ? [...config.bootstrap] : [...resolveNetwork(config.network).bootstrap];
9040
- if (bootstrap.length === 0) {
9041
- throw new SmartEngineError2(
9042
- "connectToCluster requires either a non-empty `bootstrap` list or a known `network` name.",
9043
- 400
9044
- );
9045
- }
9046
- const discovery = new ClusterDiscoveryClient({
9047
- bootstrap,
9074
+ const resolved = await resolveClusterEndpoint({
9075
+ bootstrap: config.bootstrap,
9076
+ network: config.network,
9048
9077
  allowInsecure,
9049
- trustAnchor: config.trustAnchor ? {
9050
- network: config.trustAnchor.network,
9051
- registryTopicId: config.trustAnchor.registryTopicId,
9052
- mirrorNodeUrl: config.trustAnchor.mirrorNodeUrl,
9053
- allowInsecure
9054
- } : void 0
9078
+ trustAnchor: config.trustAnchor
9055
9079
  });
9056
- const cluster = await discovery.getRandomCluster();
9057
- if (!cluster) {
9080
+ if (!resolved.ok) {
9081
+ if (resolved.reason === "no-seeds") {
9082
+ throw new SmartEngineError2(
9083
+ "connectToCluster requires either a non-empty `bootstrap` list or a known `network` name.",
9084
+ 400
9085
+ );
9086
+ }
9058
9087
  throw new SmartEngineError2(
9059
9088
  "No active clusters available via bootstrap seeds. Check bootstrap URLs and network reachability.",
9060
9089
  503
9061
9090
  );
9062
9091
  }
9092
+ const cluster = resolved.cluster;
9063
9093
  const gatewayUrl = cluster.endpoints.gatewayUrl;
9064
9094
  validateClientUrl(gatewayUrl, allowInsecure);
9065
9095
  const auth = new ValidatorAuthClient({ security: { allowInsecure } });
@@ -9084,7 +9114,7 @@ var SmartEngineClient = class _SmartEngineClient {
9084
9114
  }
9085
9115
  /** Check if client has an auth token */
9086
9116
  isAuthenticated() {
9087
- return !!this.http.authToken;
9117
+ return this.http.getAuthToken() !== void 0;
9088
9118
  }
9089
9119
  /**
9090
9120
  * Get HTTP resilience health information
@@ -9315,7 +9345,7 @@ var RoutingClient = class {
9315
9345
  }
9316
9346
  /** Unregister a host. */
9317
9347
  async unregisterHost(hostId) {
9318
- return this.http.delete(`/routing/hosts/${encodeURIComponent(hostId)}`);
9348
+ return this.http.delete(`/routing/hosts/${encodePathParam(hostId)}`);
9319
9349
  }
9320
9350
  /** Get all registered hosts. */
9321
9351
  async getAllHosts() {
@@ -9327,19 +9357,19 @@ var RoutingClient = class {
9327
9357
  }
9328
9358
  /** Get a specific host by ID. */
9329
9359
  async getHost(hostId) {
9330
- return this.http.get(`/routing/hosts/${encodeURIComponent(hostId)}`);
9360
+ return this.http.get(`/routing/hosts/${encodePathParam(hostId)}`);
9331
9361
  }
9332
9362
  /** Trigger host re-verification. */
9333
9363
  async verifyHost(hostId) {
9334
- return this.http.post(`/routing/hosts/${encodeURIComponent(hostId)}/verify`, {});
9364
+ return this.http.post(`/routing/hosts/${encodePathParam(hostId)}/verify`, {});
9335
9365
  }
9336
9366
  /** Set routing configuration for an app. */
9337
9367
  async setRoutingConfig(appId, config) {
9338
- return this.http.put(`/routing/config/${encodeURIComponent(appId)}`, config);
9368
+ return this.http.put(`/routing/config/${encodePathParam(appId)}`, config);
9339
9369
  }
9340
9370
  /** Get routing configuration for an app. */
9341
9371
  async getRoutingConfig(appId) {
9342
- return this.http.get(`/routing/config/${encodeURIComponent(appId)}`);
9372
+ return this.http.get(`/routing/config/${encodePathParam(appId)}`);
9343
9373
  }
9344
9374
  /** Proxy a request through the gateway. */
9345
9375
  async proxyRequest(request) {
@@ -9355,7 +9385,7 @@ var RoutingClient = class {
9355
9385
  * field; treat `appId` as the success signal.
9356
9386
  */
9357
9387
  async mapDomainToApp(domain, appId) {
9358
- return this.http.post(`/routing/domains/${encodeURIComponent(domain)}/map`, { appId });
9388
+ return this.http.post(`/routing/domains/${encodePathParam(domain)}/map`, { appId });
9359
9389
  }
9360
9390
  };
9361
9391
 
@@ -9371,11 +9401,11 @@ var DomainsClient = class {
9371
9401
  }
9372
9402
  /** Check domain availability */
9373
9403
  async checkAvailability(domain) {
9374
- return this.http.get(`/domains/check/${encodeURIComponent(domain)}`);
9404
+ return this.http.get(`/domains/check/${encodePathParam(domain)}`);
9375
9405
  }
9376
9406
  /** Get domain information */
9377
9407
  async getInfo(domain) {
9378
- return this.http.get(`/domains/${encodeURIComponent(domain)}`);
9408
+ return this.http.get(`/domains/${encodePathParam(domain)}`);
9379
9409
  }
9380
9410
  /** List domains, optionally filtered by owner */
9381
9411
  async list(owner) {
@@ -9388,47 +9418,47 @@ var DomainsClient = class {
9388
9418
  * `apps/smart-gateway/src/domains/domains.controller.ts:226-234`).
9389
9419
  */
9390
9420
  async generateVerificationToken(domain, method) {
9391
- return this.http.post(`/domains/${encodeURIComponent(domain)}/verification`, { method });
9421
+ return this.http.post(`/domains/${encodePathParam(domain)}/verification`, { method });
9392
9422
  }
9393
9423
  /** Verify domain ownership */
9394
9424
  async verifyOwnership(domain, token) {
9395
- return this.http.post(`/domains/${encodeURIComponent(domain)}/verify`, { token });
9425
+ return this.http.post(`/domains/${encodePathParam(domain)}/verify`, { token });
9396
9426
  }
9397
9427
  /** Configure DNS records for a domain */
9398
9428
  async configureDns(domain, records) {
9399
- return this.http.post(`/domains/${encodeURIComponent(domain)}/dns`, { records });
9429
+ return this.http.post(`/domains/${encodePathParam(domain)}/dns`, { records });
9400
9430
  }
9401
9431
  /** Enable DNSSEC for a domain */
9402
9432
  async enableDnssec(domain) {
9403
- return this.http.post(`/domains/${encodeURIComponent(domain)}/dnssec/enable`, {});
9433
+ return this.http.post(`/domains/${encodePathParam(domain)}/dnssec/enable`, {});
9404
9434
  }
9405
9435
  /** Disable DNSSEC for a domain */
9406
9436
  async disableDnssec(domain) {
9407
- return this.http.post(`/domains/${encodeURIComponent(domain)}/dnssec/disable`, {});
9437
+ return this.http.post(`/domains/${encodePathParam(domain)}/dnssec/disable`, {});
9408
9438
  }
9409
9439
  /** Renew a domain */
9410
9440
  async renew(domain, years) {
9411
- return this.http.post(`/domains/${encodeURIComponent(domain)}/renew`, { years: years ?? 1 });
9441
+ return this.http.post(`/domains/${encodePathParam(domain)}/renew`, { years: years ?? 1 });
9412
9442
  }
9413
9443
  /** Initiate a domain transfer */
9414
9444
  async transfer(domain, request) {
9415
- return this.http.post(`/domains/${encodeURIComponent(domain)}/transfer`, request);
9445
+ return this.http.post(`/domains/${encodePathParam(domain)}/transfer`, request);
9416
9446
  }
9417
9447
  /** Approve a pending domain transfer */
9418
9448
  async approveTransfer(domain) {
9419
- return this.http.post(`/domains/${encodeURIComponent(domain)}/transfer/approve`, {});
9449
+ return this.http.post(`/domains/${encodePathParam(domain)}/transfer/approve`, {});
9420
9450
  }
9421
9451
  /** Reject a pending domain transfer */
9422
9452
  async rejectTransfer(domain) {
9423
- return this.http.post(`/domains/${encodeURIComponent(domain)}/transfer/reject`, {});
9453
+ return this.http.post(`/domains/${encodePathParam(domain)}/transfer/reject`, {});
9424
9454
  }
9425
9455
  /** Suspend a domain */
9426
9456
  async suspend(domain, reason) {
9427
- return this.http.post(`/domains/${encodeURIComponent(domain)}/suspend`, { reason });
9457
+ return this.http.post(`/domains/${encodePathParam(domain)}/suspend`, { reason });
9428
9458
  }
9429
9459
  /** Unsuspend a domain */
9430
9460
  async unsuspend(domain) {
9431
- return this.http.post(`/domains/${encodeURIComponent(domain)}/unsuspend`, {});
9461
+ return this.http.post(`/domains/${encodePathParam(domain)}/unsuspend`, {});
9432
9462
  }
9433
9463
  };
9434
9464
 
@@ -9455,7 +9485,7 @@ var DnsClient = class {
9455
9485
  }
9456
9486
  /** Get a specific zone */
9457
9487
  async getZone(zoneName) {
9458
- return this.http.get(`/dns/zones/${encodeURIComponent(zoneName)}`);
9488
+ return this.http.get(`/dns/zones/${encodePathParam(zoneName)}`);
9459
9489
  }
9460
9490
  /** Create a new DNS zone */
9461
9491
  async createZone(request) {
@@ -9463,38 +9493,38 @@ var DnsClient = class {
9463
9493
  }
9464
9494
  /** Delete a DNS zone */
9465
9495
  async deleteZone(zoneName) {
9466
- return this.http.delete(`/dns/zones/${encodeURIComponent(zoneName)}`);
9496
+ return this.http.delete(`/dns/zones/${encodePathParam(zoneName)}`);
9467
9497
  }
9468
9498
  /** Add a record to a zone */
9469
9499
  async addRecord(zoneName, record) {
9470
- return this.http.post(`/dns/zones/${encodeURIComponent(zoneName)}/records`, record);
9500
+ return this.http.post(`/dns/zones/${encodePathParam(zoneName)}/records`, record);
9471
9501
  }
9472
9502
  /** Update a record in a zone */
9473
9503
  async updateRecord(zoneName, recordId, updates) {
9474
9504
  return this.http.put(
9475
- `/dns/zones/${encodeURIComponent(zoneName)}/records/${encodeURIComponent(recordId)}`,
9505
+ `/dns/zones/${encodePathParam(zoneName)}/records/${encodePathParam(recordId)}`,
9476
9506
  updates
9477
9507
  );
9478
9508
  }
9479
9509
  /** Delete a record from a zone */
9480
9510
  async deleteRecord(zoneName, recordId) {
9481
9511
  return this.http.delete(
9482
- `/dns/zones/${encodeURIComponent(zoneName)}/records/${encodeURIComponent(recordId)}`
9512
+ `/dns/zones/${encodePathParam(zoneName)}/records/${encodePathParam(recordId)}`
9483
9513
  );
9484
9514
  }
9485
9515
  /** Generate DNSSEC keys for a zone */
9486
9516
  async generateDnssecKeys(zoneName, algorithm) {
9487
- return this.http.post(`/dns/zones/${encodeURIComponent(zoneName)}/dnssec/keys`, {
9517
+ return this.http.post(`/dns/zones/${encodePathParam(zoneName)}/dnssec/keys`, {
9488
9518
  algorithm
9489
9519
  });
9490
9520
  }
9491
9521
  /** Get DNSSEC keys for a zone */
9492
9522
  async getDnssecKeys(zoneName) {
9493
- return this.http.get(`/dns/zones/${encodeURIComponent(zoneName)}/dnssec/keys`);
9523
+ return this.http.get(`/dns/zones/${encodePathParam(zoneName)}/dnssec/keys`);
9494
9524
  }
9495
9525
  /** Get DS record for a zone (for registrar configuration) */
9496
9526
  async getDsRecord(zoneName) {
9497
- return this.http.get(`/dns/zones/${encodeURIComponent(zoneName)}/dnssec/ds`);
9527
+ return this.http.get(`/dns/zones/${encodePathParam(zoneName)}/dnssec/ds`);
9498
9528
  }
9499
9529
  /** Clear DNS cache */
9500
9530
  async clearCache() {
@@ -10107,7 +10137,7 @@ var DatabaseClient = class {
10107
10137
  async insert(collection, document) {
10108
10138
  const appId = this.getAppId();
10109
10139
  return this.http.post(
10110
- `/api/db/${encodeURIComponent(appId)}/${encodeURIComponent(collection)}`,
10140
+ `/api/db/${encodePathParam(appId)}/${encodePathParam(collection)}`,
10111
10141
  document
10112
10142
  );
10113
10143
  }
@@ -10125,7 +10155,7 @@ var DatabaseClient = class {
10125
10155
  if (options?.sort) params.set("sort", options.sort);
10126
10156
  const qs = params.toString();
10127
10157
  return this.http.get(
10128
- `/api/db/${encodeURIComponent(appId)}/${encodeURIComponent(collection)}${qs ? `?${qs}` : ""}`
10158
+ `/api/db/${encodePathParam(appId)}/${encodePathParam(collection)}${qs ? `?${qs}` : ""}`
10129
10159
  );
10130
10160
  }
10131
10161
  /**
@@ -10134,7 +10164,7 @@ var DatabaseClient = class {
10134
10164
  async update(collection, documentId, updates) {
10135
10165
  const appId = this.getAppId();
10136
10166
  return this.http.put(
10137
- `/api/db/${encodeURIComponent(appId)}/${encodeURIComponent(collection)}/${encodeURIComponent(documentId)}`,
10167
+ `/api/db/${encodePathParam(appId)}/${encodePathParam(collection)}/${encodePathParam(documentId)}`,
10138
10168
  updates
10139
10169
  );
10140
10170
  }
@@ -10144,7 +10174,7 @@ var DatabaseClient = class {
10144
10174
  async delete(collection, documentId) {
10145
10175
  const appId = this.getAppId();
10146
10176
  return this.http.delete(
10147
- `/api/db/${encodeURIComponent(appId)}/${encodeURIComponent(collection)}/${encodeURIComponent(documentId)}`
10177
+ `/api/db/${encodePathParam(appId)}/${encodePathParam(collection)}/${encodePathParam(documentId)}`
10148
10178
  );
10149
10179
  }
10150
10180
  /**
@@ -10156,7 +10186,7 @@ var DatabaseClient = class {
10156
10186
  */
10157
10187
  async listCollections() {
10158
10188
  const appId = this.getAppId();
10159
- return this.http.get(`/api/db/${encodeURIComponent(appId)}/collections`);
10189
+ return this.http.get(`/api/db/${encodePathParam(appId)}/collections`);
10160
10190
  }
10161
10191
  /**
10162
10192
  * Create a new collection in the database.
@@ -10166,7 +10196,7 @@ var DatabaseClient = class {
10166
10196
  */
10167
10197
  async createCollection(name) {
10168
10198
  const appId = this.getAppId();
10169
- return this.http.post(`/api/db/${encodeURIComponent(appId)}/collections`, { name });
10199
+ return this.http.post(`/api/db/${encodePathParam(appId)}/collections`, { name });
10170
10200
  }
10171
10201
  /**
10172
10202
  * Drop a collection and all its documents.
@@ -10177,7 +10207,7 @@ var DatabaseClient = class {
10177
10207
  async dropCollection(name) {
10178
10208
  const appId = this.getAppId();
10179
10209
  return this.http.delete(
10180
- `/api/db/${encodeURIComponent(appId)}/collections/${encodeURIComponent(name)}`
10210
+ `/api/db/${encodePathParam(appId)}/collections/${encodePathParam(name)}`
10181
10211
  );
10182
10212
  }
10183
10213
  // ========== State Proofs ==========
@@ -10186,7 +10216,7 @@ var DatabaseClient = class {
10186
10216
  */
10187
10217
  async getStateRoot() {
10188
10218
  const appId = this.getAppId();
10189
- return this.http.get(`/api/db/${encodeURIComponent(appId)}/state/root`);
10219
+ return this.http.get(`/api/db/${encodePathParam(appId)}/state/root`);
10190
10220
  }
10191
10221
  /**
10192
10222
  * Get a Merkle proof for a specific document
@@ -10194,7 +10224,7 @@ var DatabaseClient = class {
10194
10224
  async getDocumentProof(documentId) {
10195
10225
  const appId = this.getAppId();
10196
10226
  return this.http.get(
10197
- `/api/db/${encodeURIComponent(appId)}/${encodeURIComponent(documentId)}/proof`
10227
+ `/api/db/${encodePathParam(appId)}/${encodePathParam(documentId)}/proof`
10198
10228
  );
10199
10229
  }
10200
10230
  /**
@@ -10208,7 +10238,7 @@ var DatabaseClient = class {
10208
10238
  if (options?.limit !== void 0) params.set("limit", String(options.limit));
10209
10239
  const qs = params.toString();
10210
10240
  return this.http.get(
10211
- `/api/db/${encodeURIComponent(appId)}/state/transitions${qs ? `?${qs}` : ""}`
10241
+ `/api/db/${encodePathParam(appId)}/state/transitions${qs ? `?${qs}` : ""}`
10212
10242
  );
10213
10243
  }
10214
10244
  /**
@@ -10216,7 +10246,7 @@ var DatabaseClient = class {
10216
10246
  */
10217
10247
  async getDbStats() {
10218
10248
  const appId = this.getAppId();
10219
- return this.http.get(`/api/db/${encodeURIComponent(appId)}/stats`);
10249
+ return this.http.get(`/api/db/${encodePathParam(appId)}/stats`);
10220
10250
  }
10221
10251
  };
10222
10252
 
@@ -10233,28 +10263,28 @@ var StorageClient = class {
10233
10263
  */
10234
10264
  async upload(file, filename, metadata) {
10235
10265
  const appId = this.getAppId();
10236
- return this.http.upload(`/api/storage/${encodeURIComponent(appId)}/upload`, file, filename, metadata);
10266
+ return this.http.upload(`/api/storage/${encodePathParam(appId)}/upload`, file, filename, metadata);
10237
10267
  }
10238
10268
  /**
10239
10269
  * Download a file by CID
10240
10270
  */
10241
10271
  async download(cid) {
10242
10272
  const appId = this.getAppId();
10243
- return this.http.get(`/api/storage/${encodeURIComponent(appId)}/download/${encodeURIComponent(cid)}`);
10273
+ return this.http.get(`/api/storage/${encodePathParam(appId)}/download/${encodePathParam(cid)}`);
10244
10274
  }
10245
10275
  /**
10246
10276
  * Get file metadata
10247
10277
  */
10248
10278
  async getMetadata(cid) {
10249
10279
  const appId = this.getAppId();
10250
- return this.http.get(`/api/storage/${encodeURIComponent(appId)}/metadata/${encodeURIComponent(cid)}`);
10280
+ return this.http.get(`/api/storage/${encodePathParam(appId)}/metadata/${encodePathParam(cid)}`);
10251
10281
  }
10252
10282
  /**
10253
10283
  * Delete a file
10254
10284
  */
10255
10285
  async delete(cid) {
10256
10286
  const appId = this.getAppId();
10257
- return this.http.delete(`/api/storage/${encodeURIComponent(appId)}/${encodeURIComponent(cid)}`);
10287
+ return this.http.delete(`/api/storage/${encodePathParam(appId)}/${encodePathParam(cid)}`);
10258
10288
  }
10259
10289
  /**
10260
10290
  * Get file info.
@@ -10263,7 +10293,7 @@ var StorageClient = class {
10263
10293
  * bare-CID metadata route — every metadata lookup must go through
10264
10294
  * `getMetadata(cid)` (`/api/storage/:appId/metadata/:cid`) or the
10265
10295
  * stream body via `download(cid)`. This alias forwards to `download`
10266
- * for back-compat; remove in the next major SDK release.
10296
+ * for back-compat; **scheduled for removal in 4.0.0**.
10267
10297
  */
10268
10298
  async getFile(cid) {
10269
10299
  return this.download(cid);
@@ -10281,21 +10311,21 @@ var StorageClient = class {
10281
10311
  if (pagination?.limit !== void 0) params.set("limit", String(pagination.limit));
10282
10312
  if (pagination?.offset !== void 0) params.set("offset", String(pagination.offset));
10283
10313
  const qs = params.toString();
10284
- return this.http.get(`/api/storage/${encodeURIComponent(appId)}/files${qs ? `?${qs}` : ""}`);
10314
+ return this.http.get(`/api/storage/${encodePathParam(appId)}/files${qs ? `?${qs}` : ""}`);
10285
10315
  }
10286
10316
  /**
10287
10317
  * Get storage usage for the current app
10288
10318
  */
10289
10319
  async getUsage() {
10290
10320
  const appId = this.getAppId();
10291
- return this.http.get(`/api/storage/${encodeURIComponent(appId)}/usage`);
10321
+ return this.http.get(`/api/storage/${encodePathParam(appId)}/usage`);
10292
10322
  }
10293
10323
  /**
10294
10324
  * Check if a file exists
10295
10325
  */
10296
10326
  async exists(cid) {
10297
10327
  const appId = this.getAppId();
10298
- return this.http.get(`/api/storage/${encodeURIComponent(appId)}/exists/${encodeURIComponent(cid)}`);
10328
+ return this.http.get(`/api/storage/${encodePathParam(appId)}/exists/${encodePathParam(cid)}`);
10299
10329
  }
10300
10330
  };
10301
10331
 
@@ -10312,7 +10342,7 @@ var FunctionsClient = class {
10312
10342
  */
10313
10343
  async deploy(request) {
10314
10344
  const appId = this.getAppId();
10315
- return this.http.post(`/api/functions/${encodeURIComponent(appId)}`, request);
10345
+ return this.http.post(`/api/functions/${encodePathParam(appId)}`, request);
10316
10346
  }
10317
10347
  /**
10318
10348
  * Invoke a function
@@ -10320,7 +10350,7 @@ var FunctionsClient = class {
10320
10350
  async invoke(functionId, payload) {
10321
10351
  const appId = this.getAppId();
10322
10352
  return this.http.post(
10323
- `/api/functions/${encodeURIComponent(appId)}/${encodeURIComponent(functionId)}/invoke`,
10353
+ `/api/functions/${encodePathParam(appId)}/${encodePathParam(functionId)}/invoke`,
10324
10354
  payload ?? {}
10325
10355
  );
10326
10356
  }
@@ -10329,7 +10359,7 @@ var FunctionsClient = class {
10329
10359
  */
10330
10360
  async list() {
10331
10361
  const appId = this.getAppId();
10332
- return this.http.get(`/api/functions/${encodeURIComponent(appId)}`);
10362
+ return this.http.get(`/api/functions/${encodePathParam(appId)}`);
10333
10363
  }
10334
10364
  /**
10335
10365
  * Get function details
@@ -10337,7 +10367,7 @@ var FunctionsClient = class {
10337
10367
  async get(functionId) {
10338
10368
  const appId = this.getAppId();
10339
10369
  return this.http.get(
10340
- `/api/functions/${encodeURIComponent(appId)}/${encodeURIComponent(functionId)}`
10370
+ `/api/functions/${encodePathParam(appId)}/${encodePathParam(functionId)}`
10341
10371
  );
10342
10372
  }
10343
10373
  /**
@@ -10346,7 +10376,7 @@ var FunctionsClient = class {
10346
10376
  async update(functionId, updates) {
10347
10377
  const appId = this.getAppId();
10348
10378
  return this.http.put(
10349
- `/api/functions/${encodeURIComponent(appId)}/${encodeURIComponent(functionId)}`,
10379
+ `/api/functions/${encodePathParam(appId)}/${encodePathParam(functionId)}`,
10350
10380
  updates
10351
10381
  );
10352
10382
  }
@@ -10356,7 +10386,7 @@ var FunctionsClient = class {
10356
10386
  async delete(functionId) {
10357
10387
  const appId = this.getAppId();
10358
10388
  return this.http.delete(
10359
- `/api/functions/${encodeURIComponent(appId)}/${encodeURIComponent(functionId)}`
10389
+ `/api/functions/${encodePathParam(appId)}/${encodePathParam(functionId)}`
10360
10390
  );
10361
10391
  }
10362
10392
  /**
@@ -10370,7 +10400,7 @@ var FunctionsClient = class {
10370
10400
  if (options?.level) params.set("level", options.level);
10371
10401
  const qs = params.toString();
10372
10402
  return this.http.get(
10373
- `/api/functions/${encodeURIComponent(appId)}/${encodeURIComponent(functionId)}/logs${qs ? `?${qs}` : ""}`
10403
+ `/api/functions/${encodePathParam(appId)}/${encodePathParam(functionId)}/logs${qs ? `?${qs}` : ""}`
10374
10404
  );
10375
10405
  }
10376
10406
  /**
@@ -10378,7 +10408,7 @@ var FunctionsClient = class {
10378
10408
  */
10379
10409
  async getStats() {
10380
10410
  const appId = this.getAppId();
10381
- return this.http.get(`/api/functions/${encodeURIComponent(appId)}/stats`);
10411
+ return this.http.get(`/api/functions/${encodePathParam(appId)}/stats`);
10382
10412
  }
10383
10413
  };
10384
10414
 
@@ -10395,28 +10425,28 @@ var MessagingClient = class {
10395
10425
  */
10396
10426
  async createChannel(config) {
10397
10427
  const appId = this.getAppId();
10398
- return this.http.post(`/api/messaging/${encodeURIComponent(appId)}/channels`, config);
10428
+ return this.http.post(`/api/messaging/${encodePathParam(appId)}/channels`, config);
10399
10429
  }
10400
10430
  /**
10401
10431
  * Delete a channel
10402
10432
  */
10403
10433
  async deleteChannel(channelId) {
10404
10434
  const appId = this.getAppId();
10405
- return this.http.delete(`/api/messaging/${encodeURIComponent(appId)}/channels/${encodeURIComponent(channelId)}`);
10435
+ return this.http.delete(`/api/messaging/${encodePathParam(appId)}/channels/${encodePathParam(channelId)}`);
10406
10436
  }
10407
10437
  /**
10408
10438
  * Get a channel by ID
10409
10439
  */
10410
10440
  async getChannel(channelId) {
10411
10441
  const appId = this.getAppId();
10412
- return this.http.get(`/api/messaging/${encodeURIComponent(appId)}/channels/${encodeURIComponent(channelId)}`);
10442
+ return this.http.get(`/api/messaging/${encodePathParam(appId)}/channels/${encodePathParam(channelId)}`);
10413
10443
  }
10414
10444
  /**
10415
10445
  * List all channels for the app
10416
10446
  */
10417
10447
  async listChannels() {
10418
10448
  const appId = this.getAppId();
10419
- return this.http.get(`/api/messaging/${encodeURIComponent(appId)}/channels`);
10449
+ return this.http.get(`/api/messaging/${encodePathParam(appId)}/channels`);
10420
10450
  }
10421
10451
  /**
10422
10452
  * Publish a message to a channel
@@ -10424,7 +10454,7 @@ var MessagingClient = class {
10424
10454
  async publish(channel, message, metadata) {
10425
10455
  const appId = this.getAppId();
10426
10456
  return this.http.post(
10427
- `/api/messaging/${encodeURIComponent(appId)}/channels/${encodeURIComponent(channel)}/publish`,
10457
+ `/api/messaging/${encodePathParam(appId)}/channels/${encodePathParam(channel)}/publish`,
10428
10458
  { data: message, metadata }
10429
10459
  );
10430
10460
  }
@@ -10439,7 +10469,7 @@ var MessagingClient = class {
10439
10469
  if (options?.after) params.set("after", options.after);
10440
10470
  const qs = params.toString();
10441
10471
  return this.http.get(
10442
- `/api/messaging/${encodeURIComponent(appId)}/channels/${encodeURIComponent(channel)}/history${qs ? `?${qs}` : ""}`
10472
+ `/api/messaging/${encodePathParam(appId)}/channels/${encodePathParam(channel)}/history${qs ? `?${qs}` : ""}`
10443
10473
  );
10444
10474
  }
10445
10475
  /**
@@ -10453,7 +10483,7 @@ var MessagingClient = class {
10453
10483
  async setPresence(channel, member) {
10454
10484
  const appId = this.getAppId();
10455
10485
  return this.http.post(
10456
- `/api/messaging/${encodeURIComponent(appId)}/channels/${encodeURIComponent(channel)}/presence`,
10486
+ `/api/messaging/${encodePathParam(appId)}/channels/${encodePathParam(channel)}/presence`,
10457
10487
  member
10458
10488
  );
10459
10489
  }
@@ -10469,7 +10499,7 @@ var MessagingClient = class {
10469
10499
  async removePresence(channel, clientId) {
10470
10500
  const appId = this.getAppId();
10471
10501
  return this.http.delete(
10472
- `/api/messaging/${encodeURIComponent(appId)}/channels/${encodeURIComponent(channel)}/presence/${encodeURIComponent(clientId)}`
10502
+ `/api/messaging/${encodePathParam(appId)}/channels/${encodePathParam(channel)}/presence/${encodePathParam(clientId)}`
10473
10503
  );
10474
10504
  }
10475
10505
  /**
@@ -10478,7 +10508,7 @@ var MessagingClient = class {
10478
10508
  async getPresence(channel) {
10479
10509
  const appId = this.getAppId();
10480
10510
  return this.http.get(
10481
- `/api/messaging/${encodeURIComponent(appId)}/channels/${encodeURIComponent(channel)}/presence`
10511
+ `/api/messaging/${encodePathParam(appId)}/channels/${encodePathParam(channel)}/presence`
10482
10512
  );
10483
10513
  }
10484
10514
  /**
@@ -10486,7 +10516,7 @@ var MessagingClient = class {
10486
10516
  */
10487
10517
  async getStats() {
10488
10518
  const appId = this.getAppId();
10489
- return this.http.get(`/api/messaging/${encodeURIComponent(appId)}/stats`);
10519
+ return this.http.get(`/api/messaging/${encodePathParam(appId)}/stats`);
10490
10520
  }
10491
10521
  };
10492
10522
 
@@ -10574,7 +10604,7 @@ var RulesClient = class {
10574
10604
  }
10575
10605
  /** Fetch a published rule by its HCS consensus timestamp. */
10576
10606
  async get(consensusTimestamp) {
10577
- return this.http.get(`/api/rules/${encodeURIComponent(consensusTimestamp)}`);
10607
+ return this.http.get(`/api/rules/${encodePathParam(consensusTimestamp)}`);
10578
10608
  }
10579
10609
  /** List rules owned by the authenticated entity, optionally filtered by type. */
10580
10610
  async listByOwner(filter) {
@@ -10591,13 +10621,13 @@ var RulesClient = class {
10591
10621
  /** Walk the version history of a published rule. */
10592
10622
  async getVersionHistory(consensusTimestamp) {
10593
10623
  return this.http.get(
10594
- `/api/rules/${encodeURIComponent(consensusTimestamp)}/versions`
10624
+ `/api/rules/${encodePathParam(consensusTimestamp)}/versions`
10595
10625
  );
10596
10626
  }
10597
10627
  /** Deprecate a published rule (owner-only). */
10598
10628
  async deprecate(consensusTimestamp) {
10599
10629
  return this.http.post(
10600
- `/api/rules/${encodeURIComponent(consensusTimestamp)}/deprecate`,
10630
+ `/api/rules/${encodePathParam(consensusTimestamp)}/deprecate`,
10601
10631
  {}
10602
10632
  );
10603
10633
  }
@@ -10635,7 +10665,7 @@ var EntitiesClient = class {
10635
10665
  }
10636
10666
  /** Fetch an entity by its canonical `entityId`. */
10637
10667
  async get(entityId) {
10638
- return this.http.get(`/api/entities/${encodeURIComponent(entityId)}`);
10668
+ return this.http.get(`/api/entities/${encodePathParam(entityId)}`);
10639
10669
  }
10640
10670
  /** List entities owned by the authenticated wallet, optionally filtered by type. */
10641
10671
  async listByOwner(filter) {
@@ -10651,7 +10681,6 @@ var BaasClient = class _BaasClient {
10651
10681
  appId;
10652
10682
  timeout;
10653
10683
  allowInsecure;
10654
- authToken = null;
10655
10684
  http;
10656
10685
  /** Last HTTP error (for getHttpHealth) */
10657
10686
  lastHttpError;
@@ -10738,30 +10767,25 @@ var BaasClient = class _BaasClient {
10738
10767
  */
10739
10768
  static async connectToCluster(config) {
10740
10769
  const allowInsecure = config.allowInsecure ?? false;
10741
- const bootstrap = config.bootstrap ? [...config.bootstrap] : [...resolveNetwork(config.network).bootstrap];
10742
- if (bootstrap.length === 0) {
10743
- throw new BaasError(
10744
- "connectToCluster requires either a non-empty `bootstrap` list or a known `network` name.",
10745
- 400
10746
- );
10747
- }
10748
- const discovery = new ClusterDiscoveryClient({
10749
- bootstrap,
10770
+ const resolved = await resolveClusterEndpoint({
10771
+ bootstrap: config.bootstrap,
10772
+ network: config.network,
10750
10773
  allowInsecure,
10751
- trustAnchor: config.trustAnchor ? {
10752
- network: config.trustAnchor.network,
10753
- registryTopicId: config.trustAnchor.registryTopicId,
10754
- mirrorNodeUrl: config.trustAnchor.mirrorNodeUrl,
10755
- allowInsecure
10756
- } : void 0
10774
+ trustAnchor: config.trustAnchor
10757
10775
  });
10758
- const cluster = await discovery.getRandomCluster();
10759
- if (!cluster) {
10776
+ if (!resolved.ok) {
10777
+ if (resolved.reason === "no-seeds") {
10778
+ throw new BaasError(
10779
+ "connectToCluster requires either a non-empty `bootstrap` list or a known `network` name.",
10780
+ 400
10781
+ );
10782
+ }
10760
10783
  throw new BaasError(
10761
10784
  "No active clusters available via bootstrap seeds. Check network reachability or bootstrap URLs.",
10762
10785
  503
10763
10786
  );
10764
10787
  }
10788
+ const cluster = resolved.cluster;
10765
10789
  return new _BaasClient({
10766
10790
  hostUrl: cluster.endpoints.gatewayUrl,
10767
10791
  appId: config.appId,
@@ -10779,7 +10803,7 @@ var BaasClient = class _BaasClient {
10779
10803
  }
10780
10804
  /** Check if the client is authenticated */
10781
10805
  isAuthenticated() {
10782
- return this.authToken !== null;
10806
+ return this.http.getAuthToken() !== void 0;
10783
10807
  }
10784
10808
  /** Get the current app ID */
10785
10809
  getAppId() {
@@ -10825,93 +10849,55 @@ var BaasClient = class _BaasClient {
10825
10849
  */
10826
10850
  async authenticate(options) {
10827
10851
  const { chain, walletAddress, publicKey, signFn } = options;
10828
- const challenge = await this.post("/api/auth/challenge", {
10829
- chain,
10830
- walletAddress,
10831
- appId: this.appId
10832
- });
10852
+ let challenge;
10853
+ try {
10854
+ challenge = await this.http.post("/api/auth/challenge", {
10855
+ chain,
10856
+ walletAddress,
10857
+ appId: this.appId
10858
+ });
10859
+ } catch (err) {
10860
+ throw asBaasError(err);
10861
+ }
10833
10862
  const signature = await signFn(challenge.message);
10834
- const result = await this.post("/api/auth/verify", {
10835
- challengeId: challenge.challengeId,
10836
- signature,
10837
- publicKey
10838
- });
10839
- this.authToken = result.token;
10840
- this.http.setAuthToken?.(result.token);
10863
+ let result;
10864
+ try {
10865
+ result = await this.http.post("/api/auth/verify", {
10866
+ challengeId: challenge.challengeId,
10867
+ signature,
10868
+ publicKey
10869
+ });
10870
+ } catch (err) {
10871
+ throw asBaasError(err);
10872
+ }
10873
+ this.http.setAuthToken(result.token);
10841
10874
  return result;
10842
10875
  }
10843
10876
  /** Validate the current session */
10844
10877
  async validateSession() {
10845
10878
  this.requireAuth();
10846
- return this.get("/api/auth/session");
10879
+ try {
10880
+ return await this.http.get("/api/auth/session");
10881
+ } catch (err) {
10882
+ throw asBaasError(err);
10883
+ }
10847
10884
  }
10848
10885
  /** Destroy the current session on server and clear local token */
10849
10886
  async logout() {
10850
- if (this.authToken) {
10887
+ if (this.http.getAuthToken()) {
10851
10888
  try {
10852
- await this.post("/api/auth/logout", {});
10889
+ await this.http.post("/api/auth/logout", {});
10853
10890
  } catch {
10854
10891
  }
10855
10892
  }
10856
- this.authToken = null;
10893
+ this.http.setAuthToken(void 0);
10857
10894
  }
10858
10895
  // ========== HTTP Helpers ==========
10859
10896
  requireAuth() {
10860
- if (!this.authToken) {
10897
+ if (!this.http.getAuthToken()) {
10861
10898
  throw new BaasError("Authentication required. Call authenticate() first.", 401);
10862
10899
  }
10863
10900
  }
10864
- getHeaders() {
10865
- const headers = {
10866
- "Content-Type": "application/json"
10867
- };
10868
- if (this.authToken) {
10869
- headers["Authorization"] = `Bearer ${this.authToken}`;
10870
- }
10871
- return headers;
10872
- }
10873
- async post(path, body) {
10874
- return this.request("POST", path, body);
10875
- }
10876
- async get(path) {
10877
- return this.request("GET", path);
10878
- }
10879
- async request(method, path, body) {
10880
- const url = `${this.hostUrl}${this.pathPrefix}${path}`;
10881
- const controller = new AbortController();
10882
- const timeoutId = setTimeout(() => controller.abort(), this.timeout);
10883
- try {
10884
- const options = {
10885
- method,
10886
- headers: this.getHeaders(),
10887
- signal: controller.signal
10888
- };
10889
- if (body !== void 0) {
10890
- options.body = JSON.stringify(body);
10891
- }
10892
- const response = await fetch(url, options);
10893
- clearTimeout(timeoutId);
10894
- if (!response.ok) {
10895
- const errorData = await response.json().catch(() => ({}));
10896
- throw new BaasError(
10897
- errorData.message || `API error: ${response.status} ${response.statusText}`,
10898
- response.status,
10899
- errorData
10900
- );
10901
- }
10902
- const text = await response.text();
10903
- if (!text) return void 0;
10904
- return JSON.parse(text);
10905
- } catch (error) {
10906
- clearTimeout(timeoutId);
10907
- if (error instanceof BaasError) throw error;
10908
- const err = error;
10909
- if (err.name === "AbortError") {
10910
- throw new BaasError("Request timeout", 408);
10911
- }
10912
- throw new BaasError(`Network error: ${err.message}`, 0, { originalError: err.message });
10913
- }
10914
- }
10915
10901
  };
10916
10902
  var BaasError = class extends Error {
10917
10903
  constructor(message, statusCode, details) {
@@ -10923,6 +10909,17 @@ var BaasError = class extends Error {
10923
10909
  statusCode;
10924
10910
  details;
10925
10911
  };
10912
+ function asBaasError(err) {
10913
+ if (err instanceof BaasError) return err;
10914
+ if (err instanceof SdkHttpError) {
10915
+ const details = err.details ?? void 0;
10916
+ return new BaasError(err.message, err.statusCode, details);
10917
+ }
10918
+ const e = err;
10919
+ return new BaasError(`Network error: ${e?.message ?? String(err)}`, 0, {
10920
+ originalError: e?.message ?? String(err)
10921
+ });
10922
+ }
10926
10923
  function validateUrl2(url, allowInsecure = false) {
10927
10924
  try {
10928
10925
  const parsed = new URL(url);
@@ -11104,6 +11101,251 @@ async function verifyPqcAttestation(cert, payload, registrySnapshot) {
11104
11101
  };
11105
11102
  }
11106
11103
 
11104
+ // src/pqc-verify-envelope/index.ts
11105
+ var pqc_verify_envelope_exports = {};
11106
+ __export(pqc_verify_envelope_exports, {
11107
+ KYBER_MIN_TIMESTAMP_MS: () => KYBER_MIN_TIMESTAMP_MS,
11108
+ validateEnvelopeSchema: () => validateEnvelopeSchema,
11109
+ verifyPqcEnvelope: () => verifyPqcEnvelope
11110
+ });
11111
+
11112
+ // src/pqc-verify-envelope/envelope-schema-validator.ts
11113
+ var KEM_CT_LEN = {
11114
+ "ml-kem-768": 1088,
11115
+ "ml-kem-1024": 1568
11116
+ };
11117
+ var AES_IV_LEN = 12;
11118
+ var AES_TAG_LEN = 16;
11119
+ var KDF_SALT_LEN = 16;
11120
+ function tryDecodeBase64(s) {
11121
+ if (typeof s !== "string" || s.length === 0) return null;
11122
+ try {
11123
+ const buf = Buffer.from(s, "base64");
11124
+ if (buf.toString("base64").replace(/=+$/, "") !== s.replace(/=+$/, "")) {
11125
+ return null;
11126
+ }
11127
+ return new Uint8Array(buf);
11128
+ } catch {
11129
+ return null;
11130
+ }
11131
+ }
11132
+ function isString(v) {
11133
+ return typeof v === "string";
11134
+ }
11135
+ function isNonEmptyString(v) {
11136
+ return typeof v === "string" && v.length > 0;
11137
+ }
11138
+ function isFiniteNumber(v) {
11139
+ return typeof v === "number" && Number.isFinite(v);
11140
+ }
11141
+ function isPlainObject(v) {
11142
+ return typeof v === "object" && v !== null && !Array.isArray(v);
11143
+ }
11144
+ function validateEnvelopeSchema(envelope) {
11145
+ if (!isPlainObject(envelope)) {
11146
+ return { ok: false, reason: "envelope must be a JSON object" };
11147
+ }
11148
+ const version = envelope.version;
11149
+ if (version === "kyber-aes-v1") {
11150
+ return validateKyberAesV1(envelope);
11151
+ }
11152
+ if (version === "aes-v0") {
11153
+ return validateAesV0(envelope);
11154
+ }
11155
+ return {
11156
+ ok: false,
11157
+ reason: `unknown envelope version: ${JSON.stringify(version)}`
11158
+ };
11159
+ }
11160
+ function validateKyberAesV1(env) {
11161
+ const kemAlgorithm = env.kemAlgorithm;
11162
+ if (kemAlgorithm !== "ml-kem-768" && kemAlgorithm !== "ml-kem-1024") {
11163
+ return {
11164
+ ok: false,
11165
+ reason: `kemAlgorithm must be 'ml-kem-768' or 'ml-kem-1024'`
11166
+ };
11167
+ }
11168
+ if (!isNonEmptyString(env.kemCiphertext)) {
11169
+ return { ok: false, reason: "kemCiphertext must be a non-empty base64 string" };
11170
+ }
11171
+ const kemCtBytes = tryDecodeBase64(env.kemCiphertext);
11172
+ if (!kemCtBytes) {
11173
+ return { ok: false, reason: "kemCiphertext is not valid base64" };
11174
+ }
11175
+ const expectedKemLen = KEM_CT_LEN[kemAlgorithm];
11176
+ if (kemCtBytes.length !== expectedKemLen) {
11177
+ return {
11178
+ ok: false,
11179
+ reason: `kemCiphertext length ${kemCtBytes.length} != expected ${expectedKemLen} for ${kemAlgorithm}`
11180
+ };
11181
+ }
11182
+ if (!isString(env.recipientPkFingerprint) || !/^[0-9a-f]{32}$/i.test(env.recipientPkFingerprint)) {
11183
+ return {
11184
+ ok: false,
11185
+ reason: "recipientPkFingerprint must be a 32-char hex string (16-byte sha384 prefix)"
11186
+ };
11187
+ }
11188
+ if (env.aesAlgorithm !== "aes-256-gcm") {
11189
+ return { ok: false, reason: `aesAlgorithm must be 'aes-256-gcm'` };
11190
+ }
11191
+ if (!isNonEmptyString(env.aesIv)) {
11192
+ return { ok: false, reason: "aesIv must be a non-empty base64 string" };
11193
+ }
11194
+ const ivBytes = tryDecodeBase64(env.aesIv);
11195
+ if (!ivBytes) return { ok: false, reason: "aesIv is not valid base64" };
11196
+ if (ivBytes.length !== AES_IV_LEN) {
11197
+ return {
11198
+ ok: false,
11199
+ reason: `aesIv length ${ivBytes.length} != expected ${AES_IV_LEN} (AES-GCM 96-bit nonce)`
11200
+ };
11201
+ }
11202
+ if (typeof env.aesCiphertext !== "string") {
11203
+ return { ok: false, reason: "aesCiphertext must be a base64 string" };
11204
+ }
11205
+ if (env.aesCiphertext.length > 0) {
11206
+ const ctBytes = tryDecodeBase64(env.aesCiphertext);
11207
+ if (!ctBytes) return { ok: false, reason: "aesCiphertext is not valid base64" };
11208
+ }
11209
+ if (!isNonEmptyString(env.aesAuthTag)) {
11210
+ return { ok: false, reason: "aesAuthTag must be a non-empty base64 string" };
11211
+ }
11212
+ const tagBytes = tryDecodeBase64(env.aesAuthTag);
11213
+ if (!tagBytes) return { ok: false, reason: "aesAuthTag is not valid base64" };
11214
+ if (tagBytes.length !== AES_TAG_LEN) {
11215
+ return {
11216
+ ok: false,
11217
+ reason: `aesAuthTag length ${tagBytes.length} != expected ${AES_TAG_LEN} (AES-GCM 128-bit tag)`
11218
+ };
11219
+ }
11220
+ if (env.kdfAlgorithm !== "hkdf-sha384") {
11221
+ return { ok: false, reason: `kdfAlgorithm must be 'hkdf-sha384'` };
11222
+ }
11223
+ if (!isNonEmptyString(env.kdfSalt)) {
11224
+ return { ok: false, reason: "kdfSalt must be a non-empty base64 string" };
11225
+ }
11226
+ const saltBytes = tryDecodeBase64(env.kdfSalt);
11227
+ if (!saltBytes) return { ok: false, reason: "kdfSalt is not valid base64" };
11228
+ if (saltBytes.length !== KDF_SALT_LEN) {
11229
+ return {
11230
+ ok: false,
11231
+ reason: `kdfSalt length ${saltBytes.length} != expected ${KDF_SALT_LEN}`
11232
+ };
11233
+ }
11234
+ if (!isNonEmptyString(env.kdfLabel)) {
11235
+ return { ok: false, reason: "kdfLabel must be a non-empty string" };
11236
+ }
11237
+ if (env.kdfLabel.length > 256) {
11238
+ return {
11239
+ ok: false,
11240
+ reason: `kdfLabel length ${env.kdfLabel.length} exceeds 256-char limit`
11241
+ };
11242
+ }
11243
+ if (!isFiniteNumber(env.encryptedAt)) {
11244
+ return { ok: false, reason: "encryptedAt must be a finite number (millis epoch)" };
11245
+ }
11246
+ return { ok: true, version: "kyber-aes-v1" };
11247
+ }
11248
+ function validateAesV0(env) {
11249
+ if (!isNonEmptyString(env.aesIv)) {
11250
+ return { ok: false, reason: "aesIv must be a non-empty base64 string" };
11251
+ }
11252
+ const ivBytes = tryDecodeBase64(env.aesIv);
11253
+ if (!ivBytes) return { ok: false, reason: "aesIv is not valid base64" };
11254
+ if (ivBytes.length !== AES_IV_LEN) {
11255
+ return {
11256
+ ok: false,
11257
+ reason: `aesIv length ${ivBytes.length} != expected ${AES_IV_LEN} (AES-GCM 96-bit nonce)`
11258
+ };
11259
+ }
11260
+ if (typeof env.aesCiphertext !== "string") {
11261
+ return { ok: false, reason: "aesCiphertext must be a base64 string" };
11262
+ }
11263
+ if (env.aesCiphertext.length > 0) {
11264
+ const ctBytes = tryDecodeBase64(env.aesCiphertext);
11265
+ if (!ctBytes) return { ok: false, reason: "aesCiphertext is not valid base64" };
11266
+ }
11267
+ if (!isNonEmptyString(env.aesAuthTag)) {
11268
+ return { ok: false, reason: "aesAuthTag must be a non-empty base64 string" };
11269
+ }
11270
+ const tagBytes = tryDecodeBase64(env.aesAuthTag);
11271
+ if (!tagBytes) return { ok: false, reason: "aesAuthTag is not valid base64" };
11272
+ if (tagBytes.length !== AES_TAG_LEN) {
11273
+ return {
11274
+ ok: false,
11275
+ reason: `aesAuthTag length ${tagBytes.length} != expected ${AES_TAG_LEN} (AES-GCM 128-bit tag)`
11276
+ };
11277
+ }
11278
+ return { ok: true, version: "aes-v0" };
11279
+ }
11280
+
11281
+ // src/pqc-verify-envelope/verify-pqc-envelope.ts
11282
+ var KYBER_MIN_TIMESTAMP_MS = 17040672e5;
11283
+ async function verifyPqcEnvelope(envelope, options = {}) {
11284
+ const schema = validateEnvelopeSchema(envelope);
11285
+ if (!schema.ok) {
11286
+ return {
11287
+ valid: false,
11288
+ reason: `schema-invalid: ${schema.reason}`,
11289
+ details: { schemaValid: false, base64Valid: false, timestampPlausible: false }
11290
+ };
11291
+ }
11292
+ const env = envelope;
11293
+ const version = schema.version;
11294
+ const details = {
11295
+ version,
11296
+ schemaValid: true,
11297
+ base64Valid: true,
11298
+ // computed below for kyber-aes-v1; legacy has no encryptedAt so treat as plausible.
11299
+ timestampPlausible: true
11300
+ };
11301
+ if (version === "kyber-aes-v1") {
11302
+ details.kemAlgorithm = env.kemAlgorithm;
11303
+ details.recipientPkFingerprint = env.recipientPkFingerprint;
11304
+ details.kdfLabel = env.kdfLabel;
11305
+ details.encryptedAt = env.encryptedAt;
11306
+ const minTs = options.minTimestamp ?? KYBER_MIN_TIMESTAMP_MS;
11307
+ const maxTs = options.maxTimestamp ?? Date.now();
11308
+ const ts = details.encryptedAt;
11309
+ if (ts < minTs) {
11310
+ details.timestampPlausible = false;
11311
+ return {
11312
+ valid: false,
11313
+ reason: `timestamp-before-minimum: encryptedAt=${ts} < min=${minTs}`,
11314
+ details
11315
+ };
11316
+ }
11317
+ if (ts > maxTs) {
11318
+ details.timestampPlausible = false;
11319
+ return {
11320
+ valid: false,
11321
+ reason: `timestamp-in-future: encryptedAt=${ts} > max=${maxTs}`,
11322
+ details
11323
+ };
11324
+ }
11325
+ if (options.expectedLabel !== void 0) {
11326
+ if (details.kdfLabel !== options.expectedLabel) {
11327
+ return {
11328
+ valid: false,
11329
+ reason: `label-mismatch: expected='${options.expectedLabel}' actual='${details.kdfLabel}'`,
11330
+ details
11331
+ };
11332
+ }
11333
+ }
11334
+ if (options.expectedRecipientPkFingerprint !== void 0) {
11335
+ const a = (details.recipientPkFingerprint ?? "").toLowerCase();
11336
+ const b = options.expectedRecipientPkFingerprint.toLowerCase();
11337
+ if (a !== b) {
11338
+ return {
11339
+ valid: false,
11340
+ reason: `recipient-pk-fingerprint-mismatch: expected='${b}' actual='${a}'`,
11341
+ details
11342
+ };
11343
+ }
11344
+ }
11345
+ }
11346
+ return { valid: true, version, details };
11347
+ }
11348
+
11107
11349
  // src/rules/atoms/index.ts
11108
11350
  var atom = {
11109
11351
  timeRange: (cfg) => ({
@@ -12543,6 +12785,7 @@ exports.HistoricalBalanceClient = HistoricalBalanceClient;
12543
12785
  exports.HistoricalBalanceClientError = HistoricalBalanceClientError;
12544
12786
  exports.IPFSClient = IPFSClient;
12545
12787
  exports.KNOWN_NETWORKS = KNOWN_NETWORKS;
12788
+ exports.KYBER_MIN_TIMESTAMP_MS = KYBER_MIN_TIMESTAMP_MS;
12546
12789
  exports.KeyConditionSchema = KeyConditionSchema;
12547
12790
  exports.MIRROR_NODE_URLS = MIRROR_NODE_URLS;
12548
12791
  exports.MessagingClient = MessagingClient;
@@ -12637,6 +12880,7 @@ exports.operator = operator_exports;
12637
12880
  exports.parsePqcCert = parsePqcCert;
12638
12881
  exports.personhood = personhood_exports;
12639
12882
  exports.pqcVerify = pqc_verify_exports;
12883
+ exports.pqcVerifyEnvelope = pqc_verify_envelope_exports;
12640
12884
  exports.resilientFetch = resilientFetch;
12641
12885
  exports.resolveNetwork = resolveNetwork;
12642
12886
  exports.resources = resources_exports;
@@ -12655,7 +12899,9 @@ exports.tradingAgent = tradingAgent;
12655
12899
  exports.utilityToken = utilityToken;
12656
12900
  exports.validate = validate;
12657
12901
  exports.validateAgentRules = validateAgentRules;
12902
+ exports.validateEnvelopeSchema = validateEnvelopeSchema;
12658
12903
  exports.verifyPqcAttestation = verifyPqcAttestation;
12904
+ exports.verifyPqcEnvelope = verifyPqcEnvelope;
12659
12905
  exports.vestingSchedule = vestingSchedule;
12660
12906
  //# sourceMappingURL=index.js.map
12661
12907
  //# sourceMappingURL=index.js.map