@hsuite/smart-engines-sdk 3.14.0 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1619,19 +1619,6 @@ export interface ValidatorInfo {
1619
1619
  registeredAt: string;
1620
1620
  messageType?: "validator.join" | "validator.leave" | "validator.update";
1621
1621
  }
1622
- export interface ClusterEndpointsView {
1623
- clusterId: string;
1624
- gatewayUrl: string;
1625
- harborUrl?: string;
1626
- natsUrl?: string;
1627
- publicIp?: string;
1628
- region?: string;
1629
- }
1630
- export interface ClusterInfo {
1631
- clusterId: string;
1632
- endpoints: ClusterEndpointsView;
1633
- nodeIds: string[];
1634
- }
1635
1622
  export type HttpCallOptions = {
1636
1623
  customerToken?: string;
1637
1624
  onBehalfOf?: string;
@@ -3353,6 +3340,7 @@ export type AgentRegisterRequest = {
3353
3340
  description?: string;
3354
3341
  capabilities: string[];
3355
3342
  rules: AgentRules;
3343
+ primaryChain?: string;
3356
3344
  fundingConfig?: {
3357
3345
  chain: string;
3358
3346
  maxAmount: string;
@@ -4168,7 +4156,7 @@ declare class OperatorClient {
4168
4156
  getTopup(chain: OperatorChain, accountId: string): Promise<OperatorTopUpResponse>;
4169
4157
  }
4170
4158
  export interface SmartEngineClientConfig {
4171
- baseUrl: string;
4159
+ validatorBaseUrl: string;
4172
4160
  apiKey?: string;
4173
4161
  authToken?: string;
4174
4162
  timeout?: number;
@@ -4188,35 +4176,6 @@ export interface NetworkConnectionConfig {
4188
4176
  mirrorNodeUrl?: string;
4189
4177
  allowInsecure?: boolean;
4190
4178
  }
4191
- export interface ClusterConnectionAuth {
4192
- chain: AuthChain;
4193
- address: string;
4194
- publicKey: string;
4195
- signFn: (challenge: string) => string | Promise<string>;
4196
- metadata?: {
4197
- appId?: string;
4198
- appName?: string;
4199
- };
4200
- trustAnchor?: {
4201
- network: "mainnet" | "testnet" | "previewnet";
4202
- registryTopicId: string;
4203
- mirrorNodeUrl?: string;
4204
- };
4205
- allowInsecure?: boolean;
4206
- }
4207
- export type ClusterConnectionSeed = {
4208
- bootstrap: string[];
4209
- network?: never;
4210
- } | {
4211
- bootstrap?: never;
4212
- network: NetworkName;
4213
- };
4214
- export type ClusterConnectionConfig = ClusterConnectionSeed & ClusterConnectionAuth;
4215
- export interface ClusterConnectionResult {
4216
- client: SmartEngineClient;
4217
- cluster: ClusterInfo;
4218
- session: AuthenticateResponse;
4219
- }
4220
4179
  export interface NetworkConnectionResult {
4221
4180
  client: SmartEngineClient;
4222
4181
  validator: ValidatorInfo;
@@ -4254,7 +4213,6 @@ declare class SmartEngineClient {
4254
4213
  constructor(config: SmartEngineClientConfig);
4255
4214
  static fromEnv(env: Record<string, string | undefined>): SmartEngineClient;
4256
4215
  static connectToNetwork(config: NetworkConnectionConfig): Promise<NetworkConnectionResult>;
4257
- static connectToCluster(config: ClusterConnectionConfig): Promise<ClusterConnectionResult>;
4258
4216
  getBaseUrl(): string;
4259
4217
  isAuthenticated(): boolean;
4260
4218
  getHttpHealth(): {
@@ -12477,6 +12435,56 @@ export type LaunchpadEntityResult = {
12477
12435
  tokenId: string;
12478
12436
  chainAccounts: Record<string, string>;
12479
12437
  };
12438
+ export type TransferEntityRequest = {
12439
+ chain: ChainType;
12440
+ to: string;
12441
+ amount: string;
12442
+ tokenId?: string;
12443
+ memo?: string;
12444
+ };
12445
+ export type WithdrawEntityRequest = {
12446
+ chain: ChainType;
12447
+ destination: string;
12448
+ amount: string;
12449
+ tokenId?: string;
12450
+ memo?: string;
12451
+ };
12452
+ export type MintEntityRequest = {
12453
+ chain: ChainType;
12454
+ tokenId: string;
12455
+ amount: string;
12456
+ memo?: string;
12457
+ };
12458
+ export type BurnEntityRequest = {
12459
+ chain: ChainType;
12460
+ tokenId: string;
12461
+ amount: string;
12462
+ memo?: string;
12463
+ };
12464
+ export type ComplianceAction = "pause" | "restrict" | "wipe";
12465
+ export type ComplianceEntityRequest = {
12466
+ action: ComplianceAction;
12467
+ chain: ChainType;
12468
+ tokenId: string;
12469
+ account?: string;
12470
+ amount?: string;
12471
+ memo?: string;
12472
+ };
12473
+ export type TrustlineEntityRequest = {
12474
+ chain: ChainType;
12475
+ currency: string;
12476
+ issuerAddress: string;
12477
+ limit?: string;
12478
+ };
12479
+ export type PreparedEntityTransactionResult = {
12480
+ chain: string;
12481
+ transactionId: string;
12482
+ transactionBytes: string;
12483
+ transactionType?: string;
12484
+ payerAccountId?: string;
12485
+ expiresAt?: string;
12486
+ metadata?: Record<string, unknown>;
12487
+ };
12480
12488
  export declare class EntitiesClient {
12481
12489
  private readonly http;
12482
12490
  constructor(http: HttpClient);
@@ -12521,6 +12529,12 @@ export declare class EntitiesClient {
12521
12529
  launchpad(req: LaunchpadEntityRequest): Promise<LaunchpadEntityResult>;
12522
12530
  get(entityId: string): Promise<EntityInfo>;
12523
12531
  listByOwner(filter?: ListEntitiesFilter): Promise<ListEntitiesResponse>;
12532
+ transfer(entityId: string, body: TransferEntityRequest, opts?: HttpCallOptions): Promise<PreparedEntityTransactionResult>;
12533
+ withdraw(entityId: string, body: WithdrawEntityRequest, opts?: HttpCallOptions): Promise<PreparedEntityTransactionResult>;
12534
+ mint(entityId: string, body: MintEntityRequest, opts?: HttpCallOptions): Promise<PreparedEntityTransactionResult>;
12535
+ burn(entityId: string, body: BurnEntityRequest, opts?: HttpCallOptions): Promise<PreparedEntityTransactionResult>;
12536
+ compliance(entityId: string, body: ComplianceEntityRequest, opts?: HttpCallOptions): Promise<PreparedEntityTransactionResult>;
12537
+ trustline(entityId: string, body: TrustlineEntityRequest, opts?: HttpCallOptions): Promise<PreparedEntityTransactionResult>;
12524
12538
  }
12525
12539
  export type AuthenticateOptions = {
12526
12540
  chain: BaasSupportedChain;
@@ -12554,7 +12568,6 @@ declare class BaasClient {
12554
12568
  private readonly timeout;
12555
12569
  private readonly allowInsecure;
12556
12570
  private readonly http;
12557
- private readonly txHttp;
12558
12571
  private lastHttpError?;
12559
12572
  private authContext?;
12560
12573
  readonly db: DatabaseClient;
@@ -12566,7 +12579,6 @@ declare class BaasClient {
12566
12579
  readonly customerSession: CustomerSessionClient;
12567
12580
  readonly rules: RulesClient;
12568
12581
  readonly entities: EntitiesClient;
12569
- readonly transactions: TransactionsClient;
12570
12582
  constructor(config: BaasClientConfig);
12571
12583
  static connectToCluster(config: BaasConnectToClusterConfig): Promise<BaasClient>;
12572
12584
  setAppId(appId: string): void;
@@ -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);
@@ -3603,7 +3605,7 @@ var SmartEngineClient = class _SmartEngineClient {
3603
3605
  discovery;
3604
3606
  constructor(config) {
3605
3607
  this.allowInsecure = config.allowInsecure ?? false;
3606
- this.baseUrl = validateClientUrl(config.baseUrl, this.allowInsecure);
3608
+ this.baseUrl = validateClientUrl(config.validatorBaseUrl, this.allowInsecure);
3607
3609
  this.http = createHttpClient({
3608
3610
  baseUrl: `${this.baseUrl}/api/v3`,
3609
3611
  apiKey: config.apiKey,
@@ -3665,7 +3667,7 @@ var SmartEngineClient = class _SmartEngineClient {
3665
3667
  const timeoutRaw = env["REQUEST_TIMEOUT"];
3666
3668
  const timeout = timeoutRaw ? Number.parseInt(timeoutRaw, 10) : void 0;
3667
3669
  return new _SmartEngineClient({
3668
- baseUrl,
3670
+ validatorBaseUrl: baseUrl,
3669
3671
  apiKey: env["VALIDATOR_API_KEY"],
3670
3672
  authToken: env["APP_TOKEN"],
3671
3673
  allowInsecure: env["ALLOW_INSECURE"] === "true",
@@ -3713,90 +3715,21 @@ var SmartEngineClient = class _SmartEngineClient {
3713
3715
  config.metadata
3714
3716
  );
3715
3717
  const client = new _SmartEngineClient({
3716
- baseUrl: validatorUrl,
3718
+ validatorBaseUrl: validatorUrl,
3717
3719
  authToken: session.token,
3718
3720
  allowInsecure
3719
3721
  });
3720
3722
  return { client, validator, session };
3721
3723
  }
3722
- /**
3723
- * Connect to the smart-engines network via the **service-registry**.
3724
- * Preferred over {@link connectToNetwork} once the validator pods in the
3725
- * target network have published their cluster endpoints the SDK
3726
- * auto-balances across the active cluster set and rides permissionless
3727
- * cluster join/leave without code edits.
3728
- *
3729
- * Resolution ladder:
3730
- * 1. HTTP fetch `/api/v3/discovery/clusters` from each bootstrap seed.
3731
- * 2. (Optional) HCS trust-anchor membership cross-check.
3732
- * 3. Random-pick over the verified set.
3733
- *
3734
- * @param config - Seed + auth config. See {@link ClusterConnectionConfig}.
3735
- * @returns The configured client, the selected cluster, and the auth session.
3736
- * @throws SmartEngineError 400 if neither `bootstrap` nor `network` is given.
3737
- * @throws SmartEngineError 503 if no active cluster can be reached.
3738
- *
3739
- * @example Zero-config (recommended for smart-app callers)
3740
- * ```ts
3741
- * const { client, cluster, session } = await SmartEngineClient.connectToCluster({
3742
- * network: 'testnet', // resolves canonical gateway entrypoint
3743
- * chain: 'xrpl',
3744
- * address: '...',
3745
- * publicKey: '...',
3746
- * signFn: async (challenge) => sign(challenge),
3747
- * });
3748
- * ```
3749
- *
3750
- * @example Custom seeds (private deployments / local dev)
3751
- * ```ts
3752
- * const { client, cluster, session } = await SmartEngineClient.connectToCluster({
3753
- * bootstrap: ['https://sn1.testnet.hsuite.network', 'https://sn2.testnet.hsuite.network'],
3754
- * chain: 'xrpl',
3755
- * address: '...',
3756
- * publicKey: '...',
3757
- * signFn: async (challenge) => sign(challenge),
3758
- * });
3759
- * ```
3760
- */
3761
- static async connectToCluster(config) {
3762
- const allowInsecure = config.allowInsecure ?? false;
3763
- const resolved = await resolveClusterEndpoint({
3764
- bootstrap: config.bootstrap,
3765
- network: config.network,
3766
- allowInsecure,
3767
- trustAnchor: config.trustAnchor
3768
- });
3769
- if (!resolved.ok) {
3770
- if (resolved.reason === "no-seeds") {
3771
- throw new SmartEngineError(
3772
- "connectToCluster requires either a non-empty `bootstrap` list or a known `network` name.",
3773
- 400
3774
- );
3775
- }
3776
- throw new SmartEngineError(
3777
- "No active clusters available via bootstrap seeds. Check bootstrap URLs and network reachability.",
3778
- 503
3779
- );
3780
- }
3781
- const cluster = resolved.cluster;
3782
- const gatewayUrl = cluster.endpoints.gatewayUrl;
3783
- validateClientUrl(gatewayUrl, allowInsecure);
3784
- const auth = new ValidatorAuthClient({ security: { allowInsecure } });
3785
- const session = await auth.authenticateWithSigner(
3786
- gatewayUrl,
3787
- config.chain,
3788
- config.address,
3789
- config.publicKey,
3790
- config.signFn,
3791
- config.metadata
3792
- );
3793
- const client = new _SmartEngineClient({
3794
- baseUrl: gatewayUrl,
3795
- authToken: session.token,
3796
- allowInsecure
3797
- });
3798
- return { client, cluster, session };
3799
- }
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).
3800
3733
  /** Get the current validator URL */
3801
3734
  getBaseUrl() {
3802
3735
  return this.baseUrl;
@@ -5250,6 +5183,96 @@ var EntitiesClient = class _EntitiesClient {
5250
5183
  const path = filter?.type ? `/api/v3/baas/entities?type=${encodeURIComponent(filter.type)}` : "/api/v3/baas/entities";
5251
5184
  return this.http.get(path);
5252
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
+ }
5253
5276
  };
5254
5277
 
5255
5278
  // src/baas/client.ts
@@ -5260,13 +5283,6 @@ var BaasClient = class _BaasClient {
5260
5283
  timeout;
5261
5284
  allowInsecure;
5262
5285
  http;
5263
- /**
5264
- * Validator-routed HTTP client for the `/api/v3/transactions/*` prepare/execute
5265
- * surface — a SIBLING of `/host`, NOT under the `pathPrefix`. Rooted at the
5266
- * raw gateway/ingress origin (`hostUrl`) so transactions reach the validator
5267
- * even when BaaS traffic is gateway-routed at `/host/*`.
5268
- */
5269
- txHttp;
5270
5286
  /** Last HTTP error (for getHttpHealth) */
5271
5287
  lastHttpError;
5272
5288
  /**
@@ -5295,14 +5311,6 @@ var BaasClient = class _BaasClient {
5295
5311
  rules;
5296
5312
  /** Canonical entity authoring surface (token/account/topic/agent + launchpad). */
5297
5313
  entities;
5298
- /**
5299
- * Validator-routed transaction prepare/execute (sovereignty model). The
5300
- * prepare endpoints accept an explicit `payerAccountId` for the session-less
5301
- * payer path, OR carry the web3-auth session token for the JWT-wallet payer
5302
- * path (kept in sync with the main client's token — see {@link authenticate}).
5303
- * Targets `/api/v3/transactions/*`, a sibling of the `/host` BaaS surface.
5304
- */
5305
- transactions;
5306
5314
  constructor(config) {
5307
5315
  this.allowInsecure = config.allowInsecure ?? false;
5308
5316
  this.hostUrl = validateUrl2(config.hostUrl, this.allowInsecure);
@@ -5319,11 +5327,6 @@ var BaasClient = class _BaasClient {
5319
5327
  // been called (authContext set). Excludes /api/v3/{,baas/}auth/* (see http client).
5320
5328
  onUnauthorized: () => this.reauthenticate()
5321
5329
  });
5322
- this.txHttp = createHttpClient({
5323
- baseUrl: `${this.hostUrl.replace(/\/$/, "")}/api/v3/transactions`,
5324
- timeout: this.timeout,
5325
- onUnauthorized: () => this.reauthenticate()
5326
- });
5327
5330
  const getAppId = () => this.requireAppId();
5328
5331
  this.db = new DatabaseClient(this.http, getAppId);
5329
5332
  this.storage = new StorageClient(this.http, getAppId);
@@ -5334,7 +5337,6 @@ var BaasClient = class _BaasClient {
5334
5337
  this.customerSession = new CustomerSessionClient(baseUrlWithPrefix, this.timeout);
5335
5338
  this.rules = new RulesClient(this.http);
5336
5339
  this.entities = new EntitiesClient(this.http);
5337
- this.transactions = new TransactionsClient(this.txHttp);
5338
5340
  }
5339
5341
  /**
5340
5342
  * Connect to the Smart Engines BaaS via cluster auto-discovery.
@@ -5482,7 +5484,6 @@ var BaasClient = class _BaasClient {
5482
5484
  throw asBaasError(err);
5483
5485
  }
5484
5486
  this.http.setAuthToken(result.token);
5485
- this.txHttp.setAuthToken(result.token);
5486
5487
  return result;
5487
5488
  }
5488
5489
  /**
@@ -5508,7 +5509,6 @@ var BaasClient = class _BaasClient {
5508
5509
  publicKey: ctx.publicKey
5509
5510
  });
5510
5511
  this.http.setAuthToken(result.token);
5511
- this.txHttp.setAuthToken(result.token);
5512
5512
  }
5513
5513
  /** Validate the current session */
5514
5514
  async validateSession() {
@@ -5528,7 +5528,6 @@ var BaasClient = class _BaasClient {
5528
5528
  }
5529
5529
  }
5530
5530
  this.http.setAuthToken(void 0);
5531
- this.txHttp.setAuthToken(void 0);
5532
5531
  }
5533
5532
  // ========== HTTP Helpers ==========
5534
5533
  requireAuth() {
@@ -5617,10 +5616,12 @@ exports.SmartEngineService = class SmartEngineService {
5617
5616
  * Can be called manually if not using DI configuration
5618
5617
  */
5619
5618
  async initialize(config) {
5620
- this.logger.log(`Initializing SmartEngineService for ${config.baseUrl}`);
5619
+ this.logger.log(`Initializing SmartEngineService for ${config.validatorBaseUrl}`);
5621
5620
  try {
5622
5621
  this.client = new SmartEngineClient({
5623
- 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,
5624
5625
  apiKey: config.apiKey,
5625
5626
  authToken: config.authToken,
5626
5627
  timeout: config.timeout,
@@ -5849,7 +5850,10 @@ exports.SmartEngineModule = class SmartEngineModule {
5849
5850
  {
5850
5851
  provide: SDK_BAAS_CLIENT,
5851
5852
  useFactory: (config) => new BaasClient({
5852
- 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,
5853
5857
  timeout: config.timeout,
5854
5858
  allowInsecure: config.allowInsecure
5855
5859
  }),