@hsuite/smart-engines-sdk 3.13.1 → 4.0.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.
@@ -1021,9 +1021,11 @@ var ClusterDiscoveryClient = class {
1021
1021
  }
1022
1022
  /**
1023
1023
  * Convenience wrapper returning just the gateway URL of a random
1024
- * active cluster. The single most-used SDK entry pointmost
1025
- * downstream callers want `new SmartEngineClient({ baseUrl: ... })`
1026
- * and don't care about the rest of the metadata.
1024
+ * active cluster. Feed this to `BaasClient` (the host BaaS tier) e.g.
1025
+ * `new BaasClient({ hostUrl, pathPrefix: '/host' })` or
1026
+ * `BaasClient.connectToCluster({ network })`. Do NOT feed it to
1027
+ * `SmartEngineClient`: that client's raw `/api/v3/*` tier is un-ingressed at
1028
+ * the gateway and will 404 (it requires an explicit `validatorBaseUrl`).
1027
1029
  */
1028
1030
  async getRandomGatewayUrl(forceRefresh = false) {
1029
1031
  const cluster = await this.getRandomCluster(forceRefresh);
@@ -1149,6 +1151,13 @@ var SdkHttpError = class extends Error {
1149
1151
  }
1150
1152
  statusCode;
1151
1153
  details;
1154
+ /**
1155
+ * True for transient failures worth retrying: a 5xx, a 429 (rate limit), a 408
1156
+ * (timeout), or a 0 (network/abort). Deterministic 4xx client errors are not.
1157
+ */
1158
+ get isRetryable() {
1159
+ return this.statusCode === 0 || this.statusCode === 408 || this.statusCode === 429 || this.statusCode >= 500;
1160
+ }
1152
1161
  };
1153
1162
  function createHttpClient(config) {
1154
1163
  const timeout = config.timeout ?? 3e4;
@@ -1166,6 +1175,10 @@ function createHttpClient(config) {
1166
1175
  if (opts?.customerToken) {
1167
1176
  headers["X-Customer-Session-Token"] = opts.customerToken;
1168
1177
  }
1178
+ if (opts?.onBehalfOf) {
1179
+ headers["Authorization"] = `Bearer ${opts.onBehalfOf}`;
1180
+ headers["X-Customer-Session-Claim"] = opts.onBehalfOf;
1181
+ }
1169
1182
  if (opts?.headers) {
1170
1183
  Object.assign(headers, opts.headers);
1171
1184
  }
@@ -1273,6 +1286,41 @@ function createHttpClient(config) {
1273
1286
  throw new SdkHttpError(`Network error: ${err.message}`, 0, error);
1274
1287
  }
1275
1288
  }
1289
+ async function getBinaryWithMeta(path, opts) {
1290
+ const url = `${config.baseUrl}${path}`;
1291
+ const controller = new AbortController();
1292
+ const timeoutId = setTimeout(() => controller.abort(), timeout);
1293
+ try {
1294
+ const response = await fetch(url, {
1295
+ method: "GET",
1296
+ headers: getHeaders(void 0, opts),
1297
+ signal: controller.signal
1298
+ });
1299
+ clearTimeout(timeoutId);
1300
+ if (!response.ok) {
1301
+ const errBody = await response.json().catch(() => ({}));
1302
+ throw new SdkHttpError(
1303
+ errBody.message || `API error: ${response.status} ${response.statusText}`,
1304
+ response.status,
1305
+ errBody
1306
+ );
1307
+ }
1308
+ const bytes = new Uint8Array(await response.arrayBuffer());
1309
+ const contentType = response.headers.get("content-type") ?? void 0;
1310
+ const disposition = response.headers.get("content-disposition") ?? "";
1311
+ const match = /filename\*?=(?:UTF-8'')?"?([^"\n;]+)"?/i.exec(disposition);
1312
+ const filename = match ? decodeURIComponent(match[1].trim()) : void 0;
1313
+ return { bytes, contentType, filename };
1314
+ } catch (error) {
1315
+ clearTimeout(timeoutId);
1316
+ if (error instanceof SdkHttpError) throw error;
1317
+ const err = error;
1318
+ if (err.name === "AbortError") {
1319
+ throw new SdkHttpError("Request timeout", 408);
1320
+ }
1321
+ throw new SdkHttpError(`Network error: ${err.message}`, 0, error);
1322
+ }
1323
+ }
1276
1324
  async function upload(path, file, filename, metadata, fieldName = "file", opts) {
1277
1325
  const url = `${config.baseUrl}${path}`;
1278
1326
  const controller = new AbortController();
@@ -1296,6 +1344,10 @@ function createHttpClient(config) {
1296
1344
  if (opts?.customerToken) {
1297
1345
  headers["X-Customer-Session-Token"] = opts.customerToken;
1298
1346
  }
1347
+ if (opts?.onBehalfOf) {
1348
+ headers["Authorization"] = `Bearer ${opts.onBehalfOf}`;
1349
+ headers["X-Customer-Session-Claim"] = opts.onBehalfOf;
1350
+ }
1299
1351
  if (opts?.headers) {
1300
1352
  Object.assign(headers, opts.headers);
1301
1353
  }
@@ -1353,6 +1405,7 @@ function createHttpClient(config) {
1353
1405
  delete: (path, opts) => withAuthRetry(path, () => request("DELETE", path, void 0, opts)),
1354
1406
  getText: (path, opts) => withAuthRetry(path, () => getText(path, opts)),
1355
1407
  getBinary: (path, opts) => withAuthRetry(path, () => getBinary(path, opts)),
1408
+ getBinaryWithMeta: (path, opts) => withAuthRetry(path, () => getBinaryWithMeta(path, opts)),
1356
1409
  upload: ((path, file, filename, metadata, fieldName, opts) => withAuthRetry(path, () => upload(path, file, filename, metadata, fieldName, opts))),
1357
1410
  setAuthToken,
1358
1411
  getAuthToken
@@ -2992,9 +3045,12 @@ var AgentsClient = class {
2992
3045
  return this.http.get("/api/v3/baas/agents", opts);
2993
3046
  }
2994
3047
  /**
2995
- * Fund agent treasury (owner-only). Returns a
3048
+ * Fund agent treasury (owner-only). Normally returns a
2996
3049
  * `PreparedTransactionResponse` wrapped in a `success: true` envelope —
2997
- * the caller is expected to sign and submit the prepared bytes.
3050
+ * the caller is expected to sign and submit the prepared bytes. When the
3051
+ * amount trips an approval-required rule the host instead returns an
3052
+ * {@link AgentPendingApprovalResponse}; discriminate with
3053
+ * {@link isAgentFundPending}.
2998
3054
  */
2999
3055
  async fund(agentId, request, opts) {
3000
3056
  return this.http.post(`/api/v3/baas/agents/${encodePathParam(agentId)}/fund`, request, opts);
@@ -3033,6 +3089,14 @@ var AgentsClient = class {
3033
3089
  async revoke(agentId, opts) {
3034
3090
  return this.http.post(`/api/v3/baas/agents/${encodePathParam(agentId)}/revoke`, {}, opts);
3035
3091
  }
3092
+ /**
3093
+ * Get an agent's certification snapshot (identity, rule refs, BLS group key,
3094
+ * and recent on-chain activity). A 404 throws `SdkHttpError` via `http.get`
3095
+ * — parity with {@link get}.
3096
+ */
3097
+ async certification(agentId, opts) {
3098
+ return this.http.get(`/api/v3/baas/agents/${encodePathParam(agentId)}/certification`, opts);
3099
+ }
3036
3100
  /**
3037
3101
  * Update agent rules.
3038
3102
  *
@@ -3541,7 +3605,7 @@ var SmartEngineClient = class _SmartEngineClient {
3541
3605
  discovery;
3542
3606
  constructor(config) {
3543
3607
  this.allowInsecure = config.allowInsecure ?? false;
3544
- this.baseUrl = validateClientUrl(config.baseUrl, this.allowInsecure);
3608
+ this.baseUrl = validateClientUrl(config.validatorBaseUrl, this.allowInsecure);
3545
3609
  this.http = createHttpClient({
3546
3610
  baseUrl: `${this.baseUrl}/api/v3`,
3547
3611
  apiKey: config.apiKey,
@@ -3603,7 +3667,7 @@ var SmartEngineClient = class _SmartEngineClient {
3603
3667
  const timeoutRaw = env["REQUEST_TIMEOUT"];
3604
3668
  const timeout = timeoutRaw ? Number.parseInt(timeoutRaw, 10) : void 0;
3605
3669
  return new _SmartEngineClient({
3606
- baseUrl,
3670
+ validatorBaseUrl: baseUrl,
3607
3671
  apiKey: env["VALIDATOR_API_KEY"],
3608
3672
  authToken: env["APP_TOKEN"],
3609
3673
  allowInsecure: env["ALLOW_INSECURE"] === "true",
@@ -3651,90 +3715,21 @@ var SmartEngineClient = class _SmartEngineClient {
3651
3715
  config.metadata
3652
3716
  );
3653
3717
  const client = new _SmartEngineClient({
3654
- baseUrl: validatorUrl,
3718
+ validatorBaseUrl: validatorUrl,
3655
3719
  authToken: session.token,
3656
3720
  allowInsecure
3657
3721
  });
3658
3722
  return { client, validator, session };
3659
3723
  }
3660
- /**
3661
- * Connect to the smart-engines network via the **service-registry**.
3662
- * Preferred over {@link connectToNetwork} once the validator pods in the
3663
- * target network have published their cluster endpoints the SDK
3664
- * auto-balances across the active cluster set and rides permissionless
3665
- * cluster join/leave without code edits.
3666
- *
3667
- * Resolution ladder:
3668
- * 1. HTTP fetch `/api/v3/discovery/clusters` from each bootstrap seed.
3669
- * 2. (Optional) HCS trust-anchor membership cross-check.
3670
- * 3. Random-pick over the verified set.
3671
- *
3672
- * @param config - Seed + auth config. See {@link ClusterConnectionConfig}.
3673
- * @returns The configured client, the selected cluster, and the auth session.
3674
- * @throws SmartEngineError 400 if neither `bootstrap` nor `network` is given.
3675
- * @throws SmartEngineError 503 if no active cluster can be reached.
3676
- *
3677
- * @example Zero-config (recommended for smart-app callers)
3678
- * ```ts
3679
- * const { client, cluster, session } = await SmartEngineClient.connectToCluster({
3680
- * network: 'testnet', // resolves canonical gateway entrypoint
3681
- * chain: 'xrpl',
3682
- * address: '...',
3683
- * publicKey: '...',
3684
- * signFn: async (challenge) => sign(challenge),
3685
- * });
3686
- * ```
3687
- *
3688
- * @example Custom seeds (private deployments / local dev)
3689
- * ```ts
3690
- * const { client, cluster, session } = await SmartEngineClient.connectToCluster({
3691
- * bootstrap: ['https://sn1.testnet.hsuite.network', 'https://sn2.testnet.hsuite.network'],
3692
- * chain: 'xrpl',
3693
- * address: '...',
3694
- * publicKey: '...',
3695
- * signFn: async (challenge) => sign(challenge),
3696
- * });
3697
- * ```
3698
- */
3699
- static async connectToCluster(config) {
3700
- const allowInsecure = config.allowInsecure ?? false;
3701
- const resolved = await resolveClusterEndpoint({
3702
- bootstrap: config.bootstrap,
3703
- network: config.network,
3704
- allowInsecure,
3705
- trustAnchor: config.trustAnchor
3706
- });
3707
- if (!resolved.ok) {
3708
- if (resolved.reason === "no-seeds") {
3709
- throw new SmartEngineError(
3710
- "connectToCluster requires either a non-empty `bootstrap` list or a known `network` name.",
3711
- 400
3712
- );
3713
- }
3714
- throw new SmartEngineError(
3715
- "No active clusters available via bootstrap seeds. Check bootstrap URLs and network reachability.",
3716
- 503
3717
- );
3718
- }
3719
- const cluster = resolved.cluster;
3720
- const gatewayUrl = cluster.endpoints.gatewayUrl;
3721
- validateClientUrl(gatewayUrl, allowInsecure);
3722
- const auth = new ValidatorAuthClient({ security: { allowInsecure } });
3723
- const session = await auth.authenticateWithSigner(
3724
- gatewayUrl,
3725
- config.chain,
3726
- config.address,
3727
- config.publicKey,
3728
- config.signFn,
3729
- config.metadata
3730
- );
3731
- const client = new _SmartEngineClient({
3732
- baseUrl: gatewayUrl,
3733
- authToken: session.token,
3734
- allowInsecure
3735
- });
3736
- return { client, cluster, session };
3737
- }
3724
+ // NOTE (SDK 4.0 type-fence): the former `SmartEngineClient.connectToCluster`
3725
+ // was REMOVED. It resolved a cluster's `gatewayUrl` and fed it into
3726
+ // `new SmartEngineClient({ baseUrl: gatewayUrl })` a gateway-pointed
3727
+ // validator-direct client whose raw `/api/v3/*` calls 404 (the raw tier is
3728
+ // un-ingressed at the gateway). That was the footgun. To reach web3 through a
3729
+ // cluster use `BaasClient.connectToCluster({ network })` (the host BaaS tier);
3730
+ // for an explicit in-cluster validator origin use `new SmartEngineClient({
3731
+ // validatorBaseUrl })` or `connectToNetwork` (which resolves a real validator
3732
+ // `apiEndpoint` from the HCS registry, never a gateway URL).
3738
3733
  /** Get the current validator URL */
3739
3734
  getBaseUrl() {
3740
3735
  return this.baseUrl;
@@ -4406,6 +4401,20 @@ var StorageClient = class {
4406
4401
  const appId = this.getAppId();
4407
4402
  return this.http.getBinary(`/api/v3/baas/storage/${encodePathParam(appId)}/download/${encodePathParam(cid)}`, opts);
4408
4403
  }
4404
+ /**
4405
+ * Download a file by CID WITH its response metadata — the raw bytes plus the
4406
+ * host-supplied `contentType` (derived from the stored file's metadata) and,
4407
+ * when present, the `filename`. Use this instead of {@link download} when the
4408
+ * caller must echo the content-type back to its own client; a bytes-only
4409
+ * download cannot recover it.
4410
+ */
4411
+ async downloadWithMeta(cid, opts) {
4412
+ const appId = this.getAppId();
4413
+ return this.http.getBinaryWithMeta(
4414
+ `/api/v3/baas/storage/${encodePathParam(appId)}/download/${encodePathParam(cid)}`,
4415
+ opts
4416
+ );
4417
+ }
4409
4418
  /**
4410
4419
  * Get file metadata
4411
4420
  */
@@ -4528,6 +4537,16 @@ var FunctionsClient = class {
4528
4537
  opts
4529
4538
  );
4530
4539
  }
4540
+ /**
4541
+ * Get a function's source code
4542
+ */
4543
+ async getCode(functionId, opts) {
4544
+ const appId = this.getAppId();
4545
+ return this.http.get(
4546
+ `/api/v3/baas/functions/${encodePathParam(appId)}/${encodePathParam(functionId)}/code`,
4547
+ opts
4548
+ );
4549
+ }
4531
4550
  /**
4532
4551
  * Update a function
4533
4552
  */
@@ -5109,6 +5128,44 @@ var EntitiesClient = class _EntitiesClient {
5109
5128
  async createAgent(req) {
5110
5129
  return this.http.post("/api/v3/baas/entities/createAgent", req);
5111
5130
  }
5131
+ /**
5132
+ * PREPARE half of the payer-funded agent-create flow.
5133
+ *
5134
+ * POSTs `/api/v3/baas/entities/prepare-create` with `entityType: 'agent'`. The cluster
5135
+ * runs the per-entity DKG (persists the binding, submits nothing on-chain) and
5136
+ * returns the unsigned payer-funding `Payment`(s) the caller signs + submits with
5137
+ * their own wallet — mirroring `prepareCreateAccount`. The agent's primary chain
5138
+ * is relayed as `chain` (the generic prepare/execute DTO key) so the host's
5139
+ * chain-bound preparer runs; `name` / `agentType` / `ruleRef` ride along.
5140
+ */
5141
+ async prepareCreateAgent(req) {
5142
+ const { primaryChain, ...rest } = req;
5143
+ return this.http.post("/api/v3/baas/entities/prepare-create", {
5144
+ entityType: "agent",
5145
+ chain: primaryChain,
5146
+ ...rest
5147
+ });
5148
+ }
5149
+ /**
5150
+ * EXECUTE half of the payer-funded agent-create flow.
5151
+ *
5152
+ * POSTs `/api/v3/baas/entities/execute-create` with `entityType: 'agent'`. The entity
5153
+ * already exists (its DKG ran during prepare); pass `signedFundingBlob` for the
5154
+ * validator to submit the payer's signed funding tx (XRPL/Stellar account-model
5155
+ * relay), or omit it when the caller already submitted the funding tx themselves.
5156
+ * `createTxId` is the Hedera receipt thread (the prepared create's
5157
+ * `transactionId`); ignored for non-Hedera chains. Mirrors
5158
+ * `executeCreateAccount` but tags `entityType: 'agent'`.
5159
+ */
5160
+ async executeCreateAgent(req) {
5161
+ const { createTxId, signedFundingBlob, ...rest } = req;
5162
+ return this.http.post("/api/v3/baas/entities/execute-create", {
5163
+ ...rest,
5164
+ ...createTxId !== void 0 ? { createTxId } : {},
5165
+ ...signedFundingBlob !== void 0 ? { signedFundingBlob } : {},
5166
+ entityType: "agent"
5167
+ });
5168
+ }
5112
5169
  /**
5113
5170
  * Mega-helper: build a token rule with a launchpad ModuleEntry attached,
5114
5171
  * publish it, create the token, and return the combined result in one HTTP
@@ -5126,6 +5183,96 @@ var EntitiesClient = class _EntitiesClient {
5126
5183
  const path = filter?.type ? `/api/v3/baas/entities?type=${encodeURIComponent(filter.type)}` : "/api/v3/baas/entities";
5127
5184
  return this.http.get(path);
5128
5185
  }
5186
+ // ─── Value-movement (prepare-bytes only) ──────────────────────────────────
5187
+ //
5188
+ // Each method POSTs the host's entity-scoped value-movement route. The entity
5189
+ // is the source / treasury / authority + fee-payer (resolved server-side from
5190
+ // the entity record — never the body), so a caller can never name a foreign
5191
+ // payer or drain another account. The host authorises the call (session
5192
+ // caller identity + `loadOwnedEntity` ownership), delegates to the validator
5193
+ // preparer, and returns prepared bytes for the caller to sign + submit; the
5194
+ // host never submits and never pays. A rule-deny surfaces as an HTTP 403
5195
+ // `rule_rejected` (use `isRuleRejected`), never as signed bytes.
5196
+ //
5197
+ // `opts` threads {@link HttpCallOptions} (`onBehalfOf` / `customerToken` /
5198
+ // `headers`) so an app-as-proxy can act on behalf of an owner — the owner's
5199
+ // Mode-1 customer-session JWT rides as both `Authorization: Bearer` and
5200
+ // `X-Customer-Session-Claim`, exactly as `agents.execute` does.
5201
+ /**
5202
+ * Prepare a native or token transfer FROM an account entity.
5203
+ *
5204
+ * `POST /api/v3/baas/entities/:entityId/transfer`.
5205
+ */
5206
+ async transfer(entityId, body, opts) {
5207
+ return this.http.post(
5208
+ `/api/v3/baas/entities/${encodePathParam(entityId)}/transfer`,
5209
+ body,
5210
+ opts
5211
+ );
5212
+ }
5213
+ /**
5214
+ * Prepare a withdrawal FROM an account entity to a destination.
5215
+ *
5216
+ * `POST /api/v3/baas/entities/:entityId/withdraw`.
5217
+ */
5218
+ async withdraw(entityId, body, opts) {
5219
+ return this.http.post(
5220
+ `/api/v3/baas/entities/${encodePathParam(entityId)}/withdraw`,
5221
+ body,
5222
+ opts
5223
+ );
5224
+ }
5225
+ /**
5226
+ * Prepare a token/NFT mint whose supply authority is the account entity.
5227
+ *
5228
+ * `POST /api/v3/baas/entities/:entityId/mint`.
5229
+ */
5230
+ async mint(entityId, body, opts) {
5231
+ return this.http.post(
5232
+ `/api/v3/baas/entities/${encodePathParam(entityId)}/mint`,
5233
+ body,
5234
+ opts
5235
+ );
5236
+ }
5237
+ /**
5238
+ * Prepare a token/NFT burn from the account entity's treasury.
5239
+ *
5240
+ * `POST /api/v3/baas/entities/:entityId/burn`.
5241
+ */
5242
+ async burn(entityId, body, opts) {
5243
+ return this.http.post(
5244
+ `/api/v3/baas/entities/${encodePathParam(entityId)}/burn`,
5245
+ body,
5246
+ opts
5247
+ );
5248
+ }
5249
+ /**
5250
+ * Prepare a compliance action (pause / restrict / wipe) on a token whose
5251
+ * compliance authority is the account entity. The body `account` is the
5252
+ * per-account subject for restrict/wipe — never the payer.
5253
+ *
5254
+ * `POST /api/v3/baas/entities/:entityId/compliance`.
5255
+ */
5256
+ async compliance(entityId, body, opts) {
5257
+ return this.http.post(
5258
+ `/api/v3/baas/entities/${encodePathParam(entityId)}/compliance`,
5259
+ body,
5260
+ opts
5261
+ );
5262
+ }
5263
+ /**
5264
+ * Prepare an XRPL TrustSet authorising the account entity to hold a currency
5265
+ * from an issuer.
5266
+ *
5267
+ * `POST /api/v3/baas/entities/:entityId/trustline`.
5268
+ */
5269
+ async trustline(entityId, body, opts) {
5270
+ return this.http.post(
5271
+ `/api/v3/baas/entities/${encodePathParam(entityId)}/trustline`,
5272
+ body,
5273
+ opts
5274
+ );
5275
+ }
5129
5276
  };
5130
5277
 
5131
5278
  // src/baas/client.ts
@@ -5136,13 +5283,6 @@ var BaasClient = class _BaasClient {
5136
5283
  timeout;
5137
5284
  allowInsecure;
5138
5285
  http;
5139
- /**
5140
- * Validator-routed HTTP client for the `/api/v3/transactions/*` prepare/execute
5141
- * surface — a SIBLING of `/host`, NOT under the `pathPrefix`. Rooted at the
5142
- * raw gateway/ingress origin (`hostUrl`) so transactions reach the validator
5143
- * even when BaaS traffic is gateway-routed at `/host/*`.
5144
- */
5145
- txHttp;
5146
5286
  /** Last HTTP error (for getHttpHealth) */
5147
5287
  lastHttpError;
5148
5288
  /**
@@ -5171,14 +5311,6 @@ var BaasClient = class _BaasClient {
5171
5311
  rules;
5172
5312
  /** Canonical entity authoring surface (token/account/topic/agent + launchpad). */
5173
5313
  entities;
5174
- /**
5175
- * Validator-routed transaction prepare/execute (sovereignty model). The
5176
- * prepare endpoints accept an explicit `payerAccountId` for the session-less
5177
- * payer path, OR carry the web3-auth session token for the JWT-wallet payer
5178
- * path (kept in sync with the main client's token — see {@link authenticate}).
5179
- * Targets `/api/v3/transactions/*`, a sibling of the `/host` BaaS surface.
5180
- */
5181
- transactions;
5182
5314
  constructor(config) {
5183
5315
  this.allowInsecure = config.allowInsecure ?? false;
5184
5316
  this.hostUrl = validateUrl2(config.hostUrl, this.allowInsecure);
@@ -5195,11 +5327,6 @@ var BaasClient = class _BaasClient {
5195
5327
  // been called (authContext set). Excludes /api/v3/{,baas/}auth/* (see http client).
5196
5328
  onUnauthorized: () => this.reauthenticate()
5197
5329
  });
5198
- this.txHttp = createHttpClient({
5199
- baseUrl: `${this.hostUrl.replace(/\/$/, "")}/api/v3/transactions`,
5200
- timeout: this.timeout,
5201
- onUnauthorized: () => this.reauthenticate()
5202
- });
5203
5330
  const getAppId = () => this.requireAppId();
5204
5331
  this.db = new DatabaseClient(this.http, getAppId);
5205
5332
  this.storage = new StorageClient(this.http, getAppId);
@@ -5210,7 +5337,6 @@ var BaasClient = class _BaasClient {
5210
5337
  this.customerSession = new CustomerSessionClient(baseUrlWithPrefix, this.timeout);
5211
5338
  this.rules = new RulesClient(this.http);
5212
5339
  this.entities = new EntitiesClient(this.http);
5213
- this.transactions = new TransactionsClient(this.txHttp);
5214
5340
  }
5215
5341
  /**
5216
5342
  * Connect to the Smart Engines BaaS via cluster auto-discovery.
@@ -5358,7 +5484,6 @@ var BaasClient = class _BaasClient {
5358
5484
  throw asBaasError(err);
5359
5485
  }
5360
5486
  this.http.setAuthToken(result.token);
5361
- this.txHttp.setAuthToken(result.token);
5362
5487
  return result;
5363
5488
  }
5364
5489
  /**
@@ -5384,7 +5509,6 @@ var BaasClient = class _BaasClient {
5384
5509
  publicKey: ctx.publicKey
5385
5510
  });
5386
5511
  this.http.setAuthToken(result.token);
5387
- this.txHttp.setAuthToken(result.token);
5388
5512
  }
5389
5513
  /** Validate the current session */
5390
5514
  async validateSession() {
@@ -5404,7 +5528,6 @@ var BaasClient = class _BaasClient {
5404
5528
  }
5405
5529
  }
5406
5530
  this.http.setAuthToken(void 0);
5407
- this.txHttp.setAuthToken(void 0);
5408
5531
  }
5409
5532
  // ========== HTTP Helpers ==========
5410
5533
  requireAuth() {
@@ -5493,10 +5616,12 @@ exports.SmartEngineService = class SmartEngineService {
5493
5616
  * Can be called manually if not using DI configuration
5494
5617
  */
5495
5618
  async initialize(config) {
5496
- this.logger.log(`Initializing SmartEngineService for ${config.baseUrl}`);
5619
+ this.logger.log(`Initializing SmartEngineService for ${config.validatorBaseUrl}`);
5497
5620
  try {
5498
5621
  this.client = new SmartEngineClient({
5499
- baseUrl: config.baseUrl,
5622
+ // SDK 4.0 validator-origin type-fence: the service config extends
5623
+ // SmartEngineClientConfig, so it carries `validatorBaseUrl` directly.
5624
+ validatorBaseUrl: config.validatorBaseUrl,
5500
5625
  apiKey: config.apiKey,
5501
5626
  authToken: config.authToken,
5502
5627
  timeout: config.timeout,
@@ -5725,7 +5850,10 @@ exports.SmartEngineModule = class SmartEngineModule {
5725
5850
  {
5726
5851
  provide: SDK_BAAS_CLIENT,
5727
5852
  useFactory: (config) => new BaasClient({
5728
- hostUrl: config.baseUrl,
5853
+ // SDK 4.0: the service config carries a single origin field
5854
+ // (`validatorBaseUrl`); the BaaS client uses it as its `hostUrl`,
5855
+ // preserving the prior single-URL wiring.
5856
+ hostUrl: config.validatorBaseUrl,
5729
5857
  timeout: config.timeout,
5730
5858
  allowInsecure: config.allowInsecure
5731
5859
  }),