@hsuite/smart-engines-sdk 3.0.2 → 3.0.3

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.
@@ -710,7 +710,7 @@ export type HttpClient = {
710
710
  get<T = any>(path: string): Promise<T>;
711
711
  put<T = any>(path: string, body: unknown): Promise<T>;
712
712
  delete<T = any>(path: string): Promise<T>;
713
- upload<T = any>(path: string, file: Blob | Buffer, filename: string, metadata?: Record<string, string>): Promise<T>;
713
+ upload<T = any>(path: string, file: Blob | Buffer, filename: string, metadata?: Record<string, string>, fieldName?: string): Promise<T>;
714
714
  };
715
715
  export type SubscriptionTierName = "free_testnet" | "starter" | "professional" | "enterprise";
716
716
  export type SubscriptionStatus = "pending_deposit" | "deposit_confirmed" | "active" | "expired" | "cancelled";
@@ -839,7 +839,6 @@ export type EntityCreationResponse = {
839
839
  success: boolean;
840
840
  entityId: string;
841
841
  publicKeys: string[];
842
- signerIndices: number[];
843
842
  threshold: number;
844
843
  ceremonyIds: string[];
845
844
  };
@@ -859,7 +858,6 @@ export type ReshareResponse = {
859
858
  export type EntityDetails = {
860
859
  success: boolean;
861
860
  payload?: unknown;
862
- signerIndices?: number[];
863
861
  validators?: string[];
864
862
  publicKeys?: string[];
865
863
  error?: string;
@@ -1708,7 +1706,7 @@ declare class SmartGatewayClient {
1708
1706
  getMetrics(refresh?: boolean): Promise<GatewayMetricsResponse>;
1709
1707
  getMetricsSummary(): Promise<GatewayMetricsSummaryResponse>;
1710
1708
  }
1711
- export type BaasService = "auth" | "database" | "storage" | "functions" | "messaging";
1709
+ export type BaasService = "auth" | "database" | "storage" | "functions" | "messaging" | "customer-session";
1712
1710
  export type BaasSupportedChain = "hedera" | "xrpl" | "polkadot" | "solana";
1713
1711
  export type BaasEndpoints = {
1714
1712
  auth: string;
@@ -1717,7 +1715,6 @@ export type BaasEndpoints = {
1717
1715
  functions: string;
1718
1716
  messaging: string;
1719
1717
  };
1720
- export type DeployedAppStatus = "pending" | "deploying" | "active" | "suspended" | "deleted";
1721
1718
  export type DeployedAppInfo = {
1722
1719
  appId: string;
1723
1720
  name: string;
@@ -1761,24 +1758,6 @@ export type BaasSessionInfo = {
1761
1758
  expiresAt?: number;
1762
1759
  error?: string;
1763
1760
  };
1764
- export type BaasRegisterRequest = {
1765
- name: string;
1766
- services: BaasService[];
1767
- environment?: Record<string, string>;
1768
- limits?: {
1769
- storage?: string;
1770
- functions?: number;
1771
- channels?: number;
1772
- };
1773
- };
1774
- export type BaasRegisterResponse = {
1775
- appId: string;
1776
- name: string;
1777
- status: DeployedAppStatus;
1778
- services: string[];
1779
- endpoints: BaasEndpoints;
1780
- createdAt: string;
1781
- };
1782
1761
  export type BaasDocument = {
1783
1762
  _id: string;
1784
1763
  data: Record<string, unknown>;
@@ -1956,18 +1935,56 @@ export type BaasPublishResult = {
1956
1935
  channel: string;
1957
1936
  timestamp: string;
1958
1937
  };
1959
- export type BaasDeployRequest = {
1938
+ export type BaasInitRequest = {
1960
1939
  name: string;
1940
+ port: number;
1961
1941
  services: BaasService[];
1962
- config?: Record<string, unknown>;
1942
+ limits?: {
1943
+ cpu?: string;
1944
+ memory?: string;
1945
+ };
1963
1946
  };
1964
- export type BaasDeployResult = {
1947
+ export type BaasInitResponse = {
1965
1948
  appId: string;
1966
- name: string;
1967
- status: "active" | "deploying" | "error";
1968
- services: string[];
1969
- endpoints: BaasEndpoints;
1970
- createdAt: string;
1949
+ registry: {
1950
+ server: string;
1951
+ username: string;
1952
+ password: string;
1953
+ repository: string;
1954
+ };
1955
+ };
1956
+ export type BaasDeployRequest = {
1957
+ tag: string;
1958
+ replicas?: number;
1959
+ env?: Record<string, string>;
1960
+ resources?: {
1961
+ cpu?: string;
1962
+ memory?: string;
1963
+ };
1964
+ strategy?: "rolling" | "recreate";
1965
+ };
1966
+ export type BaasDeployResponse = {
1967
+ appId: string;
1968
+ status: string;
1969
+ url: string;
1970
+ };
1971
+ export type BaasUploadFrontendResponse = {
1972
+ bundleSha256: string;
1973
+ bundleSizeBytes: number;
1974
+ };
1975
+ export type BaasRollbackRequest = {
1976
+ toTag: string;
1977
+ };
1978
+ export type BaasRuntimeStatus = {
1979
+ appId: string;
1980
+ state: "PENDING_SUBSCRIPTION" | "ACTIVE" | "SUSPENDED" | "RETIRED";
1981
+ runtime?: {
1982
+ image: string;
1983
+ runtimeState: "NOT_DEPLOYED" | "DEPLOYING" | "RUNNING" | "FAILED" | "DEGRADED";
1984
+ replicas: number;
1985
+ lastReconciledAt?: string;
1986
+ lastError?: string;
1987
+ };
1971
1988
  };
1972
1989
  export type BaasAppListResponse = {
1973
1990
  apps: DeployedAppInfo[];
@@ -2100,7 +2117,11 @@ declare class MessagingClient {
2100
2117
  declare class DeploymentClient {
2101
2118
  private readonly http;
2102
2119
  constructor(http: HttpClient);
2103
- create(request: BaasDeployRequest): Promise<BaasDeployResult>;
2120
+ init(request: BaasInitRequest): Promise<BaasInitResponse>;
2121
+ uploadFrontend(appId: string, bundle: Blob | Buffer, filename?: string): Promise<BaasUploadFrontendResponse>;
2122
+ deploy(appId: string, request: BaasDeployRequest): Promise<BaasDeployResponse>;
2123
+ rollback(appId: string, request: BaasRollbackRequest): Promise<BaasDeployResponse>;
2124
+ status(appId: string): Promise<BaasRuntimeStatus>;
2104
2125
  list(): Promise<BaasAppListResponse>;
2105
2126
  get(appId: string): Promise<DeployedAppInfo>;
2106
2127
  update(appId: string, updates: Partial<BaasDeployRequest>): Promise<DeployedAppInfo>;
@@ -2115,7 +2136,11 @@ declare class DeploymentClient {
2115
2136
  success: boolean;
2116
2137
  status: string;
2117
2138
  }>;
2118
- getStats(): Promise<any>;
2139
+ getStats(): Promise<{
2140
+ totalApps: number;
2141
+ activeApps: number;
2142
+ totalOwners: number;
2143
+ }>;
2119
2144
  }
2120
2145
  export type AgentStatus = "active" | "paused" | "revoked" | "pending";
2121
2146
  export type AgentRegisterRequest = {
@@ -2226,6 +2251,55 @@ declare class AgentsClient {
2226
2251
  success: boolean;
2227
2252
  }>;
2228
2253
  }
2254
+ export type CustomerSessionChallenge = {
2255
+ challenge: string;
2256
+ };
2257
+ export type CustomerSessionVerifyRequest = {
2258
+ appId: string;
2259
+ chain: string;
2260
+ address: string;
2261
+ publicKey?: string;
2262
+ signature: string;
2263
+ challenge: string;
2264
+ };
2265
+ export type CustomerSessionToken = {
2266
+ token: string;
2267
+ sessionId: string;
2268
+ validatorId: string;
2269
+ expiresAt: string;
2270
+ sessionSecret: string;
2271
+ };
2272
+ export type CustomerSessionInfo = {
2273
+ sessionId: string;
2274
+ appId: string;
2275
+ customerChain: string;
2276
+ customerAddress: string;
2277
+ subscriptionContext?: {
2278
+ nftSerial: number;
2279
+ tier: "free_testnet" | "starter" | "professional" | "enterprise";
2280
+ expiresAt: string;
2281
+ allowedAutomations?: string[];
2282
+ };
2283
+ createdAt: string;
2284
+ expiresAt: string;
2285
+ lastActivityAt: string;
2286
+ };
2287
+ declare class CustomerSessionClient {
2288
+ private readonly baseUrl;
2289
+ private readonly timeoutMs;
2290
+ constructor(baseUrl: string, timeoutMs?: number);
2291
+ challenge(input: {
2292
+ chain: string;
2293
+ address: string;
2294
+ }): Promise<CustomerSessionChallenge>;
2295
+ verify(req: CustomerSessionVerifyRequest): Promise<CustomerSessionToken>;
2296
+ validate(bearer: string): Promise<CustomerSessionInfo>;
2297
+ end(bearer: string): Promise<{
2298
+ revoked: boolean;
2299
+ sessionId: string;
2300
+ }>;
2301
+ private fetch;
2302
+ }
2229
2303
  export type AuthenticateOptions = {
2230
2304
  chain: BaasSupportedChain;
2231
2305
  walletAddress: string;
@@ -2247,6 +2321,7 @@ declare class BaasClient {
2247
2321
  readonly messaging: MessagingClient;
2248
2322
  readonly deployment: DeploymentClient;
2249
2323
  readonly agents: AgentsClient;
2324
+ readonly customerSession: CustomerSessionClient;
2250
2325
  constructor(config: BaasClientConfig);
2251
2326
  setAppId(appId: string): void;
2252
2327
  isAuthenticated(): boolean;
@@ -2259,7 +2334,6 @@ declare class BaasClient {
2259
2334
  authenticate(options: AuthenticateOptions): Promise<BaasAuthResult>;
2260
2335
  validateSession(): Promise<BaasSessionInfo>;
2261
2336
  logout(): Promise<void>;
2262
- register(request: BaasRegisterRequest): Promise<BaasRegisterResponse>;
2263
2337
  private requireAuth;
2264
2338
  private getHeaders;
2265
2339
  private post;
@@ -1354,14 +1354,14 @@ function createHttpClient(config) {
1354
1354
  throw new SdkHttpError(`Network error: ${err.message}`, 0, error);
1355
1355
  }
1356
1356
  }
1357
- async function upload(path, file, filename, metadata) {
1357
+ async function upload(path, file, filename, metadata, fieldName = "file") {
1358
1358
  const url = `${config.baseUrl}${path}`;
1359
1359
  const controller = new AbortController();
1360
1360
  const timeoutId = setTimeout(() => controller.abort(), timeout * 2);
1361
1361
  try {
1362
1362
  const formData = new FormData();
1363
1363
  const blob = file instanceof Blob ? file : new Blob([new Uint8Array(file)]);
1364
- formData.append("file", blob, filename);
1364
+ formData.append(fieldName, blob, filename);
1365
1365
  if (metadata) {
1366
1366
  for (const [key, value] of Object.entries(metadata)) {
1367
1367
  formData.append(key, value);
@@ -1405,7 +1405,7 @@ function createHttpClient(config) {
1405
1405
  get: (path) => request("GET", path),
1406
1406
  put: (path, body) => request("PUT", path, body),
1407
1407
  delete: (path) => request("DELETE", path),
1408
- upload,
1408
+ upload: ((path, file, filename, metadata, fieldName) => upload(path, file, filename, metadata, fieldName)),
1409
1409
  setAuthToken
1410
1410
  };
1411
1411
  return client;
@@ -2730,49 +2730,101 @@ var DeploymentClient = class {
2730
2730
  }
2731
2731
  http;
2732
2732
  /**
2733
- * Create (deploy) a new app
2733
+ * Step 1 allocate appId + receive ephemeral push credentials for
2734
+ * the cluster's per-tenant Harbor project.
2735
+ *
2736
+ * Each app gets its own Harbor project (`hsuite-customers-<appId>`)
2737
+ * isolated by Harbor's RBAC. The push robot returned in
2738
+ * `registry.{username, password}` is scoped to that project only —
2739
+ * it cannot read or write any other tenant's images.
2740
+ *
2741
+ * **Single-use secret discipline:** `registry.password` is returned
2742
+ * exactly once and is NOT persisted server-side. Store it locally
2743
+ * for the `docker push` and discard. To rotate, call `init` again
2744
+ * (issues a new robot under the same project).
2745
+ *
2746
+ * Use the credentials to `docker login` + `docker push`, then call
2747
+ * {@link deploy} with the pushed image tag.
2748
+ */
2749
+ async init(request) {
2750
+ return this.http.post("/api/deployment/apps/init", request);
2751
+ }
2752
+ /**
2753
+ * Step 3 (optional) — upload the SPA tarball.
2754
+ *
2755
+ * The tarball is content-addressed (SHA-256) and mounted read-only
2756
+ * into the customer's pod alongside the backend container. Returns
2757
+ * the hash + size so the caller can verify the upload.
2758
+ */
2759
+ async uploadFrontend(appId, bundle, filename = "bundle.tar.gz") {
2760
+ return this.http.upload(
2761
+ `/api/deployment/apps/${encodeURIComponent(appId)}/frontend`,
2762
+ bundle,
2763
+ filename,
2764
+ void 0,
2765
+ "bundle"
2766
+ );
2767
+ }
2768
+ /**
2769
+ * Step 4 — reconcile the runtime to k8s.
2770
+ *
2771
+ * Returns immediately with `status: 'deploying'`. Poll {@link status}
2772
+ * until `runtime.runtimeState === 'RUNNING'` for the URL to be live.
2773
+ */
2774
+ async deploy(appId, request) {
2775
+ return this.http.post(`/api/deployment/apps/${encodeURIComponent(appId)}/deploy`, request);
2776
+ }
2777
+ /**
2778
+ * Roll back to a previously-deployed image tag (must exist in
2779
+ * `runtime.deploymentHistory[]`).
2734
2780
  */
2735
- async create(request) {
2736
- return this.http.post("/api/deployment/apps", request);
2781
+ async rollback(appId, request) {
2782
+ return this.http.post(`/api/deployment/apps/${encodeURIComponent(appId)}/rollback`, request);
2737
2783
  }
2738
2784
  /**
2739
- * List all deployed apps
2785
+ * Live combined lifecycle + runtime status of an app.
2786
+ */
2787
+ async status(appId) {
2788
+ return this.http.get(`/api/deployment/apps/${encodeURIComponent(appId)}/status`);
2789
+ }
2790
+ /**
2791
+ * List all deployed apps for the authenticated developer.
2740
2792
  */
2741
2793
  async list() {
2742
2794
  return this.http.get("/api/deployment/apps");
2743
2795
  }
2744
2796
  /**
2745
- * Get app details
2797
+ * Get app details.
2746
2798
  */
2747
2799
  async get(appId) {
2748
2800
  return this.http.get(`/api/deployment/apps/${encodeURIComponent(appId)}`);
2749
2801
  }
2750
2802
  /**
2751
- * Update app configuration
2803
+ * Update app configuration. Runtime effect lands in PR-H.
2752
2804
  */
2753
2805
  async update(appId, updates) {
2754
2806
  return this.http.put(`/api/deployment/apps/${encodeURIComponent(appId)}`, updates);
2755
2807
  }
2756
2808
  /**
2757
- * Delete an app
2809
+ * Delete an app. Runtime effect (namespace teardown) lands in PR-H.
2758
2810
  */
2759
2811
  async delete(appId) {
2760
2812
  return this.http.delete(`/api/deployment/apps/${encodeURIComponent(appId)}`);
2761
2813
  }
2762
2814
  /**
2763
- * Suspend an app
2815
+ * Suspend an app. Runtime effect (scale to zero) lands in PR-H.
2764
2816
  */
2765
2817
  async suspend(appId) {
2766
2818
  return this.http.post(`/api/deployment/apps/${encodeURIComponent(appId)}/suspend`, {});
2767
2819
  }
2768
2820
  /**
2769
- * Resume a suspended app
2821
+ * Resume a suspended app. Runtime effect (scale back up) lands in PR-H.
2770
2822
  */
2771
2823
  async resume(appId) {
2772
2824
  return this.http.post(`/api/deployment/apps/${encodeURIComponent(appId)}/resume`, {});
2773
2825
  }
2774
2826
  /**
2775
- * Get deployment statistics
2827
+ * Get deployment statistics.
2776
2828
  */
2777
2829
  async getStats() {
2778
2830
  return this.http.get("/api/deployment/stats");
@@ -2843,6 +2895,78 @@ var AgentsClient = class {
2843
2895
  }
2844
2896
  };
2845
2897
 
2898
+ // src/baas/customer-session/index.ts
2899
+ var CustomerSessionClient = class {
2900
+ constructor(baseUrl, timeoutMs = 3e4) {
2901
+ this.baseUrl = baseUrl;
2902
+ this.timeoutMs = timeoutMs;
2903
+ }
2904
+ baseUrl;
2905
+ timeoutMs;
2906
+ /**
2907
+ * Step 1: ask the host to issue a fresh challenge for the customer to sign.
2908
+ */
2909
+ async challenge(input) {
2910
+ return this.fetch("POST", "/api/customer-session/challenge", input);
2911
+ }
2912
+ /**
2913
+ * Step 2: submit the customer's signed challenge. On success returns a
2914
+ * short-lived bearer JWT scoped to {appId, chain, address}.
2915
+ */
2916
+ async verify(req) {
2917
+ return this.fetch("POST", "/api/customer-session/verify", req);
2918
+ }
2919
+ /**
2920
+ * Validate a customer bearer + return the decoded session info. Used by
2921
+ * smart-app backends to authorise incoming customer requests.
2922
+ */
2923
+ async validate(bearer) {
2924
+ return this.fetch("GET", "/api/customer-session/validate", void 0, bearer);
2925
+ }
2926
+ /**
2927
+ * Revoke a customer session. Idempotent.
2928
+ */
2929
+ async end(bearer) {
2930
+ return this.fetch(
2931
+ "POST",
2932
+ "/api/customer-session/end",
2933
+ void 0,
2934
+ bearer
2935
+ );
2936
+ }
2937
+ async fetch(method, path, body, bearer) {
2938
+ const url = `${this.baseUrl}${path}`;
2939
+ const controller = new AbortController();
2940
+ const timeoutId = setTimeout(() => controller.abort(), this.timeoutMs);
2941
+ try {
2942
+ const headers = { "Content-Type": "application/json" };
2943
+ if (bearer) headers["Authorization"] = `Bearer ${bearer}`;
2944
+ const init = { method, headers, signal: controller.signal };
2945
+ if (body !== void 0) init.body = JSON.stringify(body);
2946
+ const response = await fetch(url, init);
2947
+ clearTimeout(timeoutId);
2948
+ if (!response.ok) {
2949
+ const errBody = await response.json().catch(() => ({}));
2950
+ const err = new Error(
2951
+ errBody.message ?? `customer-session ${path} failed: ${response.status} ${response.statusText}`
2952
+ );
2953
+ err.status = response.status;
2954
+ throw err;
2955
+ }
2956
+ const text = await response.text();
2957
+ if (!text) return void 0;
2958
+ return JSON.parse(text);
2959
+ } catch (error) {
2960
+ clearTimeout(timeoutId);
2961
+ const e = error;
2962
+ if (e.name === "AbortError") {
2963
+ throw new Error(`customer-session ${path} timeout`);
2964
+ }
2965
+ throw error;
2966
+ }
2967
+ }
2968
+ };
2969
+
2846
2970
  // src/baas/client.ts
2847
2971
  var BaasClient = class {
2848
2972
  hostUrl;
@@ -2867,6 +2991,8 @@ var BaasClient = class {
2867
2991
  deployment;
2868
2992
  /** Autonomous smart agent management */
2869
2993
  agents;
2994
+ /** Customer→smart-app session bridge (TokenGate Face B). */
2995
+ customerSession;
2870
2996
  constructor(config) {
2871
2997
  this.allowInsecure = config.allowInsecure ?? false;
2872
2998
  this.hostUrl = validateUrl2(config.hostUrl, this.allowInsecure);
@@ -2886,6 +3012,7 @@ var BaasClient = class {
2886
3012
  this.messaging = new MessagingClient(this.http, getAppId);
2887
3013
  this.deployment = new DeploymentClient(this.http);
2888
3014
  this.agents = new AgentsClient(this.http);
3015
+ this.customerSession = new CustomerSessionClient(baseUrlWithPrefix, this.timeout);
2889
3016
  }
2890
3017
  /** Set the app ID (for newly registered apps) */
2891
3018
  setAppId(appId) {
@@ -2912,7 +3039,7 @@ var BaasClient = class {
2912
3039
  requireAppId() {
2913
3040
  if (!this.appId) {
2914
3041
  throw new BaasError(
2915
- "App ID required. Either provide appId in config or call register() first.",
3042
+ "App ID required. Provide appId in config (e.g. from a prior deployment.init() call).",
2916
3043
  400
2917
3044
  );
2918
3045
  }
@@ -2959,12 +3086,6 @@ var BaasClient = class {
2959
3086
  }
2960
3087
  this.authToken = null;
2961
3088
  }
2962
- // ========== App Registration ==========
2963
- /** Register a new app on the BaaS host */
2964
- async register(request) {
2965
- this.requireAuth();
2966
- return this.post("/api/deployment/apps", request);
2967
- }
2968
3089
  // ========== HTTP Helpers ==========
2969
3090
  requireAuth() {
2970
3091
  if (!this.authToken) {