@hsuite/smart-engines-sdk 3.3.0 → 3.4.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
@@ -6003,9 +6003,11 @@ zod.z.object({
6003
6003
  var discovery_exports = {};
6004
6004
  __export(discovery_exports, {
6005
6005
  ClusterDiscoveryClient: () => ClusterDiscoveryClient,
6006
+ DiscoveryClient: () => DiscoveryClient,
6006
6007
  MIRROR_NODE_URLS: () => MIRROR_NODE_URLS,
6007
6008
  MirrorNodeClient: () => MirrorNodeClient,
6008
6009
  MirrorNodeError: () => MirrorNodeError,
6010
+ PlatformImagesClient: () => PlatformImagesClient,
6009
6011
  ValidatorDiscoveryClient: () => ValidatorDiscoveryClient
6010
6012
  });
6011
6013
 
@@ -6554,6 +6556,99 @@ var ClusterDiscoveryClient = class {
6554
6556
  }
6555
6557
  };
6556
6558
 
6559
+ // src/discovery/discovery-client.ts
6560
+ var DiscoveryClient = class {
6561
+ constructor(http) {
6562
+ this.http = http;
6563
+ this.platformImages = new PlatformImagesClient(http);
6564
+ }
6565
+ http;
6566
+ /** Platform-image manifest discovery endpoints. */
6567
+ platformImages;
6568
+ /**
6569
+ * `GET /api/v3/discovery/clusters` — active-set cluster registry,
6570
+ * grouped by `clusterId`. This is the same data the bootstrap-seed
6571
+ * flow consumes for random-pick connect.
6572
+ */
6573
+ async listClusters() {
6574
+ return this.http.get("/discovery/clusters");
6575
+ }
6576
+ /**
6577
+ * `GET /api/v3/discovery/clusters/all` — every node-level record
6578
+ * (debug / audit view). Includes nodes that the active-set filter
6579
+ * dropped (e.g. recently-departed validators still in the registry's
6580
+ * eventual-consistency window).
6581
+ */
6582
+ async listAllClusters() {
6583
+ return this.http.get("/discovery/clusters/all");
6584
+ }
6585
+ /**
6586
+ * `GET /api/v3/discovery/clusters/:nodeId` — per-nodeId registry row.
6587
+ * Returns `{ record: null }` (not 404) when the nodeId is unknown to
6588
+ * this validator's registry view, so callers can branch without
6589
+ * try/catch.
6590
+ */
6591
+ async getClusterByNode(nodeId) {
6592
+ return this.http.get(`/discovery/clusters/${encodeURIComponent(nodeId)}`);
6593
+ }
6594
+ };
6595
+ var PlatformImagesClient = class {
6596
+ constructor(http) {
6597
+ this.http = http;
6598
+ }
6599
+ http;
6600
+ /**
6601
+ * `GET /api/v3/discovery/platform-images` — every signed manifest the
6602
+ * cluster has on record. One row per `(imageName, version)` pair.
6603
+ */
6604
+ async list() {
6605
+ return this.http.get("/discovery/platform-images");
6606
+ }
6607
+ /**
6608
+ * `GET /api/v3/discovery/platform-images/envelopes` — full signed
6609
+ * envelopes (manifest + signature + publicKey). Heavier payload than
6610
+ * {@link list}; for external re-verifiers that want to independently
6611
+ * confirm authenticity.
6612
+ */
6613
+ async listEnvelopes() {
6614
+ return this.http.get("/discovery/platform-images/envelopes");
6615
+ }
6616
+ /**
6617
+ * `GET /api/v3/discovery/platform-images/:imageName` — every version
6618
+ * of a single image. Useful for "which tags has the cluster
6619
+ * authorized?" queries.
6620
+ */
6621
+ async get(imageName) {
6622
+ return this.http.get(`/discovery/platform-images/${encodeURIComponent(imageName)}`);
6623
+ }
6624
+ /**
6625
+ * `GET /api/v3/discovery/platform-images/:imageName/:version` —
6626
+ * single signed manifest. Returns `{ manifest: null }` when the
6627
+ * `(imageName, version)` pair is unknown.
6628
+ */
6629
+ async getVersion(imageName, version) {
6630
+ return this.http.get(
6631
+ `/discovery/platform-images/${encodeURIComponent(imageName)}/${encodeURIComponent(version)}`
6632
+ );
6633
+ }
6634
+ /**
6635
+ * `GET /api/v3/discovery/platform-images/:imageName/:version/verify?digest=...`
6636
+ * — content-addressed verify gate. Returns `{ verified: true }` only
6637
+ * when the supplied SHA-256 digest matches the on-record manifest.
6638
+ *
6639
+ * Use before pulling an image off a registry to make sure you're
6640
+ * about to run cluster-signed bits and not whatever drifted into
6641
+ * the registry namespace.
6642
+ */
6643
+ async verify(imageName, version, digest) {
6644
+ return this.http.get(
6645
+ `/discovery/platform-images/${encodeURIComponent(imageName)}/${encodeURIComponent(
6646
+ version
6647
+ )}/verify?digest=${encodeURIComponent(digest)}`
6648
+ );
6649
+ }
6650
+ };
6651
+
6557
6652
  // src/auth/index.ts
6558
6653
  var auth_exports = {};
6559
6654
  __export(auth_exports, {
@@ -6858,7 +6953,7 @@ function createHttpClient(config) {
6858
6953
  const timeout = config.timeout ?? 3e4;
6859
6954
  function getHeaders(contentType) {
6860
6955
  const headers = {};
6861
- {
6956
+ if (contentType) {
6862
6957
  headers["Content-Type"] = contentType;
6863
6958
  }
6864
6959
  if (config.authToken) {
@@ -6908,6 +7003,36 @@ function createHttpClient(config) {
6908
7003
  throw new SdkHttpError(`Network error: ${err.message}`, 0, error);
6909
7004
  }
6910
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
+ }
6911
7036
  async function upload(path, file, filename, metadata, fieldName = "file") {
6912
7037
  const url = `${config.baseUrl}${path}`;
6913
7038
  const controller = new AbortController();
@@ -6958,7 +7083,9 @@ function createHttpClient(config) {
6958
7083
  post: (path, body) => request("POST", path, body),
6959
7084
  get: (path) => request("GET", path),
6960
7085
  put: (path, body) => request("PUT", path, body),
7086
+ patch: (path, body) => request("PATCH", path, body),
6961
7087
  delete: (path) => request("DELETE", path),
7088
+ getText,
6962
7089
  upload: ((path, file, filename, metadata, fieldName) => upload(path, file, filename, metadata, fieldName)),
6963
7090
  setAuthToken
6964
7091
  };
@@ -7112,6 +7239,80 @@ var SubscriptionClient = class {
7112
7239
  async getBalance(appId) {
7113
7240
  return this.http.get(`/subscription/balance/${encodeURIComponent(appId)}`);
7114
7241
  }
7242
+ // ─── Tier-Change Endpoints ────────────────────────────────────────────────
7243
+ /**
7244
+ * Schedule a tier downgrade. The downgrade takes effect at the next
7245
+ * renewal — the deposit is NOT partially refunded mid-lock. Excess
7246
+ * collateral returns on eventual cancel.
7247
+ */
7248
+ async downgrade(request) {
7249
+ return this.http.post("/subscription/downgrade", request);
7250
+ }
7251
+ /**
7252
+ * Request a tier upgrade. The server records the upgrade and returns
7253
+ * top-up deposit instructions for the price delta. The new tier flips
7254
+ * only once the on-chain top-up is confirmed by the deposit monitor.
7255
+ */
7256
+ async upgrade(request) {
7257
+ return this.http.post("/subscription/upgrade", request);
7258
+ }
7259
+ /** Cancel a pending (not-yet-applied) tier change. */
7260
+ async cancelTierChange(request) {
7261
+ return this.http.post("/subscription/tier-change/cancel", request);
7262
+ }
7263
+ // ─── Internal / Usage / Billing ───────────────────────────────────────────
7264
+ /**
7265
+ * Check whether a developer wallet has any active subscription. Used by
7266
+ * smart-host's deploy gate via the cluster-internal API-key path; smart-app
7267
+ * callers should not rely on this endpoint (server-side it requires the
7268
+ * `INTERNAL_SERVICE_MESH_ROUTES` allowlist + an `X-API-Key` header).
7269
+ */
7270
+ async getActiveFor(walletAddress) {
7271
+ return this.http.get(
7272
+ `/subscription/active-for/${encodeURIComponent(walletAddress)}`
7273
+ );
7274
+ }
7275
+ /** Today's consumption breakdown by category for an app. Owner-only. */
7276
+ async getUsage(appId) {
7277
+ return this.http.get(`/subscription/usage/${encodeURIComponent(appId)}`);
7278
+ }
7279
+ /**
7280
+ * Current usage with overage info: usage percent, grace status,
7281
+ * upgrade suggestion, projected days until limit. Owner-only.
7282
+ */
7283
+ async getUsageStatus(appId) {
7284
+ return this.http.get(`/subscription/usage/status/${encodeURIComponent(appId)}`);
7285
+ }
7286
+ /**
7287
+ * Subscription balance deduction history. Pagination + ISO-8601 range
7288
+ * filtering supported. Owner-only.
7289
+ */
7290
+ async getBilling(appId, options) {
7291
+ const params = new URLSearchParams();
7292
+ if (options?.limit !== void 0) params.append("limit", String(options.limit));
7293
+ if (options?.offset !== void 0) params.append("offset", String(options.offset));
7294
+ if (options?.from) params.append("from", options.from);
7295
+ if (options?.to) params.append("to", options.to);
7296
+ const qs = params.toString();
7297
+ return this.http.get(
7298
+ `/subscription/billing/${encodeURIComponent(appId)}${qs ? `?${qs}` : ""}`
7299
+ );
7300
+ }
7301
+ /**
7302
+ * Mint a customer-subscription NFT on behalf of a smart-app.
7303
+ *
7304
+ * Distinct from `mintNft(appId)`, which mints the smart-app's own
7305
+ * developer-level subscription NFT. This endpoint mints a *customer*
7306
+ * NFT held by an end-user wallet — used by smart-host's
7307
+ * `XrplCustomerNftIssuerAdapter` when an app calls
7308
+ * `SubscriptionService.issueCustomerSubscription()` from the sandbox.
7309
+ *
7310
+ * v1 is XRPL-only (the `customerChain` field is a literal `'xrpl'`).
7311
+ * Internal-by-design — server-side gated by `X-API-Key`.
7312
+ */
7313
+ async mintCustomer(request) {
7314
+ return this.http.post("/subscription/customer/mint", request);
7315
+ }
7115
7316
  };
7116
7317
 
7117
7318
  // src/tss/index.ts
@@ -7140,14 +7341,19 @@ var TSSClient = class {
7140
7341
  return this.http.get(`/tss/entity/${encodeURIComponent(entityId)}`);
7141
7342
  }
7142
7343
  /**
7143
- * Sign a transaction using MPC — chain-agnostic.
7144
- * Routes to the correct chain backend based on the `chain` parameter.
7344
+ * Sign a transaction using MPC.
7145
7345
  *
7146
- * @param request - MPC signing request with chain, entityId, and transaction bytes
7346
+ * Routes to `POST /api/v3/tss/hedera/sign-mpc`. Only `'hedera'` is wired
7347
+ * server-side today (see
7348
+ * `apps/smart-validator/src/tss/tss.controller.ts:279`); other chain
7349
+ * signing paths run via their own controllers (XRPL multisig, Polkadot
7350
+ * MPC) and are not exposed through this sub-client. The `chain` field is
7351
+ * carried into the request body so the validator can log + route, but
7352
+ * any non-`'hedera'` value will 404.
7147
7353
  */
7148
7354
  async signMPC(request) {
7149
- const chain = request.chain || "hedera";
7150
- return this.http.post(`/tss/${encodeURIComponent(chain)}/sign-mpc`, request);
7355
+ const chain = "hedera";
7356
+ return this.http.post(`/tss/${chain}/sign-mpc`, { ...request, chain });
7151
7357
  }
7152
7358
  /**
7153
7359
  * Get known validators and their public keys
@@ -7191,6 +7397,42 @@ var TSSClient = class {
7191
7397
  async getMultiSigStatus(txId) {
7192
7398
  return this.http.get(`/tss/multisig/transactions/${encodeURIComponent(txId)}`);
7193
7399
  }
7400
+ /**
7401
+ * Async-job variant of {@link createEntity}.
7402
+ *
7403
+ * Server returns 202 + `{ jobId, statusUrl, status: 'pending' }` immediately;
7404
+ * the DKG ceremony runs in the background. Poll {@link getJob} until the
7405
+ * status reaches `'success'` or `'failed'`.
7406
+ */
7407
+ async createEntityAsync(options) {
7408
+ return this.http.post("/tss/entity/create/async", options);
7409
+ }
7410
+ /**
7411
+ * Async-job variant of {@link reshareCluster}. Returns 202 + a polling
7412
+ * descriptor; resharing runs in the background.
7413
+ */
7414
+ async reshareClusterAsync(request) {
7415
+ return this.http.post("/tss/cluster/reshare/async", request);
7416
+ }
7417
+ /**
7418
+ * Poll the status of an async TSS-ceremony job kicked off via
7419
+ * {@link createEntityAsync} or {@link reshareClusterAsync}.
7420
+ */
7421
+ async getJob(jobId) {
7422
+ return this.http.get(`/tss/jobs/${encodeURIComponent(jobId)}`);
7423
+ }
7424
+ /**
7425
+ * Sign a hex payload as smart-app entity `appId` via the cluster's TSS
7426
+ * quorum. Used by smart-deployer for per-entity BLS12-381 signatures over
7427
+ * deployment-context payloads (trustless APP_TOKEN replacement).
7428
+ *
7429
+ * Payload constraints (enforced server-side):
7430
+ * - even-length lowercase hex
7431
+ * - ≥32 bytes, ≤8KB
7432
+ */
7433
+ async signForApp(appId, request) {
7434
+ return this.http.post(`/tss/entity/${encodeURIComponent(appId)}/sign`, request);
7435
+ }
7194
7436
  };
7195
7437
 
7196
7438
  // src/ipfs/index.ts
@@ -7260,12 +7502,59 @@ var IPFSClient = class {
7260
7502
  }
7261
7503
  };
7262
7504
 
7505
+ // src/hedera-tss/index.ts
7506
+ var HederaTssClient = class {
7507
+ constructor(http) {
7508
+ this.http = http;
7509
+ }
7510
+ http;
7511
+ /** Create a Hedera account whose keys are controlled by the TSS cluster. */
7512
+ async createAccount(request) {
7513
+ return this.http.post("/hedera/tss/create-account", request);
7514
+ }
7515
+ /** Update an existing account's memo via TSS-signed transaction. */
7516
+ async updateMemo(request) {
7517
+ return this.http.post("/hedera/tss/update-memo", request);
7518
+ }
7519
+ /** Create a TSS-controlled HCS topic. */
7520
+ async createTopic(request) {
7521
+ return this.http.post("/hedera/tss/create-topic", request);
7522
+ }
7523
+ /** Submit a message to an HCS topic via TSS signing. */
7524
+ async submitMessage(request) {
7525
+ return this.http.post("/hedera/tss/submit-message", request);
7526
+ }
7527
+ /** Create an HTS token with TSS-controlled admin/supply/freeze/pause/wipe keys. */
7528
+ async createToken(request) {
7529
+ return this.http.post("/hedera/tss/create-token", request);
7530
+ }
7531
+ /** Mint tokens via TSS signing — optionally rule-validated via `validatorTopicId`. */
7532
+ async mintToken(request) {
7533
+ return this.http.post("/hedera/tss/mint-token", request);
7534
+ }
7535
+ };
7536
+
7263
7537
  // src/transactions/chains/hedera.ts
7264
7538
  var HederaTransactionsClient = class {
7265
- constructor(http) {
7539
+ constructor(http, tssHttp) {
7266
7540
  this.http = http;
7541
+ this.tss = new HederaTssClient(tssHttp ?? http);
7267
7542
  }
7268
7543
  http;
7544
+ /**
7545
+ * TSS-signed Hedera operations (`/api/v3/hedera/tss/*`).
7546
+ *
7547
+ * Distinct from the prepare-only routes on this class:
7548
+ * - `client.hedera.prepareTopicCreate(...)` returns bytes for local sign+submit.
7549
+ * - `client.hedera.tss.createTopic(...)` makes the cluster sign+submit in one call.
7550
+ *
7551
+ * `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.
7556
+ */
7557
+ tss;
7269
7558
  /** Prepare an HCS topic creation transaction. */
7270
7559
  async prepareTopicCreate(request) {
7271
7560
  return this.http.post("/topic/create/prepare", { ...request, chain: "hedera" });
@@ -7298,6 +7587,16 @@ var XrplTransactionsClient = class {
7298
7587
  async prepareTrustLine(request) {
7299
7588
  return this.http.post("/trustline/prepare", { ...request, chain: "xrpl" });
7300
7589
  }
7590
+ /**
7591
+ * Prepare the ordered XRPL account-setup transaction set
7592
+ * (SignerListSet + AccountSet DisableMaster) for sovereignty mode.
7593
+ *
7594
+ * Returns `{ steps, sovereignty }`. Caller signs + submits each step in
7595
+ * order; the master key remains usable until the final AccountSet lands.
7596
+ */
7597
+ async prepareAccountSetup(request) {
7598
+ return this.http.post("/xrpl/account-setup/prepare", { ...request, chain: "xrpl" });
7599
+ }
7301
7600
  };
7302
7601
 
7303
7602
  // src/transactions/chains/solana.ts
@@ -7354,6 +7653,28 @@ var TransactionsClient = class {
7354
7653
  async prepareNftTransfer(request) {
7355
7654
  return this.http.post("/nft/transfer/prepare", request);
7356
7655
  }
7656
+ /**
7657
+ * Prepare an NFT collection-create transaction (Polkadot pallet-nfts /
7658
+ * Solana Metaplex master-edition).
7659
+ */
7660
+ async prepareNftCollectionCreate(request) {
7661
+ return this.http.post("/nft/collection/create/prepare", request);
7662
+ }
7663
+ /** Prepare an NFT item set-metadata transaction (Polkadot pallet-nfts/uniques). */
7664
+ async prepareNftSetMetadata(request) {
7665
+ return this.http.post("/nft/set-metadata/prepare", request);
7666
+ }
7667
+ /** Prepare an NFT collection set-metadata transaction (Polkadot pallet-nfts/uniques). */
7668
+ async prepareNftCollectionSetMetadata(request) {
7669
+ return this.http.post("/nft/collection/set-metadata/prepare", request);
7670
+ }
7671
+ /**
7672
+ * Prepare an NFT collection-lock transaction (Polkadot pallet-nfts only).
7673
+ * Asset Hub runtimes on pallet-uniques fallback will reject with a 4xx.
7674
+ */
7675
+ async prepareNftCollectionLock(request) {
7676
+ return this.http.post("/nft/collection/lock/prepare", request);
7677
+ }
7357
7678
  /** Prepare a token creation transaction (Hedera, Solana, Polkadot, Cardano). */
7358
7679
  async prepareTokenCreate(request) {
7359
7680
  return this.http.post("/token/create/prepare", request);
@@ -7674,6 +7995,253 @@ var GovernanceClient = class {
7674
7995
  }
7675
7996
  };
7676
7997
 
7998
+ // src/dao/index.ts
7999
+ var dao_exports = {};
8000
+ __export(dao_exports, {
8001
+ DaoClient: () => DaoClient,
8002
+ DaoDashboardClient: () => DaoDashboardClient
8003
+ });
8004
+
8005
+ // src/dao/dashboard-client.ts
8006
+ function buildQuery(params) {
8007
+ const search = new URLSearchParams();
8008
+ for (const [key, value] of Object.entries(params)) {
8009
+ if (value === void 0) continue;
8010
+ search.set(key, String(value));
8011
+ }
8012
+ const qs = search.toString();
8013
+ return qs ? `?${qs}` : "";
8014
+ }
8015
+ var DaoDashboardClient = class {
8016
+ constructor(http) {
8017
+ this.http = http;
8018
+ }
8019
+ http;
8020
+ /** Aggregated dashboard counters for a user's governance home screen. */
8021
+ async getStats(userAddress) {
8022
+ return this.http.get(
8023
+ `/dao/dashboard/stats/${encodeURIComponent(userAddress)}`
8024
+ );
8025
+ }
8026
+ /** Active proposals across every DAO the user belongs to, with vote state. */
8027
+ async getActiveProposals(userAddress) {
8028
+ return this.http.get(
8029
+ `/dao/dashboard/active-proposals/${encodeURIComponent(userAddress)}`
8030
+ );
8031
+ }
8032
+ /** Paginated vote history across DAOs. */
8033
+ async getVoteHistory(userAddress, opts = {}) {
8034
+ const qs = buildQuery({ limit: opts.limit, offset: opts.offset });
8035
+ return this.http.get(
8036
+ `/dao/dashboard/vote-history/${encodeURIComponent(userAddress)}${qs}`
8037
+ );
8038
+ }
8039
+ /** Activity feed (proposal-created/vote-cast/etc.) across user's DAOs. */
8040
+ async getActivity(userAddress, opts = {}) {
8041
+ const qs = buildQuery({ limit: opts.limit, daoId: opts.daoId });
8042
+ return this.http.get(
8043
+ `/dao/dashboard/activity/${encodeURIComponent(userAddress)}${qs}`
8044
+ );
8045
+ }
8046
+ /** Items the user must act on (sign prepared messages, claim NFTs, …). */
8047
+ async getPendingActions(userAddress) {
8048
+ return this.http.get(
8049
+ `/dao/dashboard/pending-actions/${encodeURIComponent(userAddress)}`
8050
+ );
8051
+ }
8052
+ /** Governance impact metrics — weight delivered, success rate, streak. */
8053
+ async getImpact(userAddress) {
8054
+ return this.http.get(
8055
+ `/dao/dashboard/impact/${encodeURIComponent(userAddress)}`
8056
+ );
8057
+ }
8058
+ };
8059
+
8060
+ // src/dao/dao-client.ts
8061
+ function buildQuery2(params) {
8062
+ const search = new URLSearchParams();
8063
+ for (const [key, value] of Object.entries(params)) {
8064
+ if (value === void 0) continue;
8065
+ search.set(key, String(value));
8066
+ }
8067
+ const qs = search.toString();
8068
+ return qs ? `?${qs}` : "";
8069
+ }
8070
+ function encodeDaoId(daoId) {
8071
+ return encodeURIComponent(daoId);
8072
+ }
8073
+ function encodeProposalId(proposalId) {
8074
+ return encodeURIComponent(proposalId);
8075
+ }
8076
+ function encodeAddress(address) {
8077
+ return encodeURIComponent(address);
8078
+ }
8079
+ var DaoClient = class {
8080
+ constructor(http) {
8081
+ this.http = http;
8082
+ this.dashboard = new DaoDashboardClient(http);
8083
+ }
8084
+ http;
8085
+ /** Per-user rollups for the smart-app's governance home screen. */
8086
+ dashboard;
8087
+ // ─── Lifecycle ────────────────────────────────────────────────────────────
8088
+ /** Create a new DAO. */
8089
+ async create(request) {
8090
+ return this.http.post("/dao/create", request);
8091
+ }
8092
+ /** List DAOs with optional status / creator filters. */
8093
+ async list(opts = {}) {
8094
+ const qs = buildQuery2({ status: opts.status, createdBy: opts.createdBy });
8095
+ return this.http.get(`/dao/list${qs}`);
8096
+ }
8097
+ /** Fetch a single DAO by ID. */
8098
+ async get(daoId) {
8099
+ return this.http.get(`/dao/${encodeDaoId(daoId)}`);
8100
+ }
8101
+ /** Fetch a DAO together with its proposals (single round-trip). */
8102
+ async getWithProposals(daoId) {
8103
+ return this.http.get(`/dao/${encodeDaoId(daoId)}/with-proposals`);
8104
+ }
8105
+ // ─── Proposals ────────────────────────────────────────────────────────────
8106
+ /** List proposals for a DAO, optionally filtered by status / proposer. */
8107
+ async listProposals(daoId, opts = {}) {
8108
+ const qs = buildQuery2({ status: opts.status, proposer: opts.proposer });
8109
+ return this.http.get(`/dao/${encodeDaoId(daoId)}/proposals${qs}`);
8110
+ }
8111
+ /** Create a proposal (server activates the proposal immediately). */
8112
+ async createProposal(daoId, request) {
8113
+ return this.http.post(`/dao/${encodeDaoId(daoId)}/proposals`, request);
8114
+ }
8115
+ /**
8116
+ * Prepare a proposal for off-chain signing (returns the message to sign).
8117
+ * Use {@link signProposal} to submit the signature once captured.
8118
+ */
8119
+ async prepareProposal(daoId, request) {
8120
+ return this.http.post(
8121
+ `/dao/${encodeDaoId(daoId)}/proposals/prepare`,
8122
+ request
8123
+ );
8124
+ }
8125
+ /** Submit the signed prepared-proposal payload. */
8126
+ async signProposal(daoId, proposalId, request) {
8127
+ return this.http.post(
8128
+ `/dao/${encodeDaoId(daoId)}/proposals/${encodeProposalId(proposalId)}/sign`,
8129
+ request
8130
+ );
8131
+ }
8132
+ /** Prepare a vote message for off-chain signing. */
8133
+ async prepareVote(daoId, proposalId, request) {
8134
+ return this.http.post(
8135
+ `/dao/${encodeDaoId(daoId)}/proposals/${encodeProposalId(proposalId)}/prepare-vote`,
8136
+ request
8137
+ );
8138
+ }
8139
+ /** Submit the signed prepared-vote payload. */
8140
+ async submitVote(daoId, proposalId, request) {
8141
+ return this.http.post(
8142
+ `/dao/${encodeDaoId(daoId)}/proposals/${encodeProposalId(proposalId)}/submit-vote`,
8143
+ request
8144
+ );
8145
+ }
8146
+ /**
8147
+ * Cast a vote directly (no separate prepare/sign hop — server records the
8148
+ * vote on the caller's behalf). Use {@link prepareVote} + {@link submitVote}
8149
+ * when the smart-app's signing model requires client-side signing.
8150
+ */
8151
+ async vote(daoId, proposalId, request) {
8152
+ return this.http.post(
8153
+ `/dao/${encodeDaoId(daoId)}/proposals/${encodeProposalId(proposalId)}/vote`,
8154
+ request
8155
+ );
8156
+ }
8157
+ /**
8158
+ * Manually execute a passed proposal via TSS. Proposals auto-execute after
8159
+ * the execution delay; this endpoint is for the governance-admin override
8160
+ * path.
8161
+ */
8162
+ async execute(daoId, proposalId) {
8163
+ return this.http.post(
8164
+ `/dao/${encodeDaoId(daoId)}/proposals/${encodeProposalId(proposalId)}/execute`,
8165
+ {}
8166
+ );
8167
+ }
8168
+ /** Paginated vote list for a proposal. */
8169
+ async getVotes(daoId, proposalId, opts = {}) {
8170
+ const qs = buildQuery2({ limit: opts.limit, offset: opts.offset });
8171
+ return this.http.get(
8172
+ `/dao/${encodeDaoId(daoId)}/proposals/${encodeProposalId(proposalId)}/votes${qs}`
8173
+ );
8174
+ }
8175
+ /** Resolved tally / quorum / pass-fail for a proposal. */
8176
+ async getResults(daoId, proposalId) {
8177
+ return this.http.get(
8178
+ `/dao/${encodeDaoId(daoId)}/proposals/${encodeProposalId(proposalId)}/results`
8179
+ );
8180
+ }
8181
+ /** Raw vote counts by option ID (no quorum / pass logic). */
8182
+ async getVoteCounts(daoId, proposalId) {
8183
+ return this.http.get(
8184
+ `/dao/${encodeDaoId(daoId)}/proposals/${encodeProposalId(proposalId)}/vote-counts`
8185
+ );
8186
+ }
8187
+ /** Fetch a single voter's vote on a proposal. */
8188
+ async getVoterRecord(daoId, proposalId, voterAddress) {
8189
+ return this.http.get(
8190
+ `/dao/${encodeDaoId(daoId)}/proposals/${encodeProposalId(proposalId)}/voter/${encodeAddress(voterAddress)}`
8191
+ );
8192
+ }
8193
+ /** Fetch a single proposal by ID. */
8194
+ async getProposal(daoId, proposalId) {
8195
+ return this.http.get(
8196
+ `/dao/${encodeDaoId(daoId)}/proposals/${encodeProposalId(proposalId)}`
8197
+ );
8198
+ }
8199
+ // ─── Treasury ─────────────────────────────────────────────────────────────
8200
+ /** Per-chain treasury balances for a DAO. */
8201
+ async getTreasury(daoId, chain) {
8202
+ const qs = buildQuery2({ chain });
8203
+ return this.http.get(`/dao/${encodeDaoId(daoId)}/treasury${qs}`);
8204
+ }
8205
+ /** Paginated treasury transaction history (in/out/swap). */
8206
+ async getTreasuryHistory(daoId, opts = {}) {
8207
+ const qs = buildQuery2({
8208
+ chain: opts.chain,
8209
+ limit: opts.limit,
8210
+ offset: opts.offset
8211
+ });
8212
+ return this.http.get(`/dao/${encodeDaoId(daoId)}/treasury/history${qs}`);
8213
+ }
8214
+ // ─── Members ──────────────────────────────────────────────────────────────
8215
+ /** List a DAO's members, optionally filtered by status. */
8216
+ async listMembers(daoId, opts = {}) {
8217
+ const qs = buildQuery2({ status: opts.status });
8218
+ return this.http.get(`/dao/${encodeDaoId(daoId)}/members${qs}`);
8219
+ }
8220
+ /** Add a member to a DAO. */
8221
+ async addMember(daoId, request) {
8222
+ return this.http.post(`/dao/${encodeDaoId(daoId)}/members`, request);
8223
+ }
8224
+ /** Remove a member from a DAO. */
8225
+ async removeMember(daoId, address) {
8226
+ return this.http.delete(
8227
+ `/dao/${encodeDaoId(daoId)}/members/${encodeAddress(address)}`
8228
+ );
8229
+ }
8230
+ /** Bind a held membership NFT serial to a member record. */
8231
+ async claimMemberNft(daoId, address, request) {
8232
+ return this.http.post(
8233
+ `/dao/${encodeDaoId(daoId)}/members/${encodeAddress(address)}/claim-nft`,
8234
+ request
8235
+ );
8236
+ }
8237
+ /** Fetch the NFT serials + status for a member. */
8238
+ async getMemberNft(daoId, address) {
8239
+ return this.http.get(
8240
+ `/dao/${encodeDaoId(daoId)}/members/${encodeAddress(address)}/nft`
8241
+ );
8242
+ }
8243
+ };
8244
+
7677
8245
  // src/personhood/index.ts
7678
8246
  var personhood_exports = {};
7679
8247
  __export(personhood_exports, {
@@ -7793,15 +8361,25 @@ var AgentsClient = class {
7793
8361
  async list() {
7794
8362
  return this.http.get("/api/agents");
7795
8363
  }
7796
- /** Fund an agent */
8364
+ /**
8365
+ * Fund agent treasury (owner-only). Returns a
8366
+ * `PreparedTransactionResponse` wrapped in a `success: true` envelope —
8367
+ * the caller is expected to sign and submit the prepared bytes.
8368
+ */
7797
8369
  async fund(agentId, request) {
7798
8370
  return this.http.post(`/api/agents/${encodeURIComponent(agentId)}/fund`, request);
7799
8371
  }
7800
- /** Execute a trade */
8372
+ /**
8373
+ * Execute a trade (agent-wallet OR owner). Returns a
8374
+ * `PreparedTransactionResponse` wrapped in a `success: true` envelope.
8375
+ */
7801
8376
  async trade(agentId, request) {
7802
8377
  return this.http.post(`/api/agents/${encodeURIComponent(agentId)}/trade`, request);
7803
8378
  }
7804
- /** Withdraw funds from agent */
8379
+ /**
8380
+ * Withdraw from agent treasury (owner-only). Returns a
8381
+ * `PreparedTransactionResponse` wrapped in a `success: true` envelope.
8382
+ */
7805
8383
  async withdraw(agentId, request) {
7806
8384
  return this.http.post(`/api/agents/${encodeURIComponent(agentId)}/withdraw`, request);
7807
8385
  }
@@ -7817,9 +8395,16 @@ var AgentsClient = class {
7817
8395
  async revoke(agentId) {
7818
8396
  return this.http.post(`/api/agents/${encodeURIComponent(agentId)}/revoke`, {});
7819
8397
  }
7820
- /** Update agent rules */
8398
+ /**
8399
+ * Update agent rules.
8400
+ *
8401
+ * Server route is PATCH `/api/agents/:agentId/rules`
8402
+ * (`agents.controller.ts:375`). The previous PUT variant 404'd because
8403
+ * Nest matched the dynamic `:agentId` GET/POST handlers and rejected
8404
+ * the verb mismatch.
8405
+ */
7821
8406
  async updateRules(agentId, rules) {
7822
- return this.http.put(`/api/agents/${encodeURIComponent(agentId)}/rules`, rules);
8407
+ return this.http.patch(`/api/agents/${encodeURIComponent(agentId)}/rules`, rules);
7823
8408
  }
7824
8409
  /** Get agent events */
7825
8410
  async getEvents(agentId) {
@@ -7945,16 +8530,316 @@ var DeploymentClient = class {
7945
8530
  async getStats() {
7946
8531
  return this.http.get("/api/deployment/stats");
7947
8532
  }
7948
- };
7949
-
7950
- // src/client.ts
7951
- var SmartEngineClient = class _SmartEngineClient {
7952
- baseUrl;
7953
- allowInsecure;
7954
- http;
7955
- /** Separate HTTP client for /api/transactions (non-v3 base path) */
7956
- txHttp;
7957
- /** Last HTTP error (for getHttpHealth) */
8533
+ /**
8534
+ * Register or update the developer-facing webhook URL for runtime
8535
+ * lifecycle events (`runtime.deploying` / `running` / `failed` /
8536
+ * `suspended` / `resumed` / `retired`).
8537
+ *
8538
+ * The host's `DeployWebhookDispatcher` POSTs to this URL whenever the
8539
+ * smart-deployer reconciler emits a `runtime.*` NATS event, signed with
8540
+ * the returned `webhookSecret`:
8541
+ *
8542
+ * `X-HSuite-Signature: sha256=<hmac-sha256(secret, raw-body)>`
8543
+ *
8544
+ * Store `webhookSecret` server-side and re-compute the signature over
8545
+ * the raw delivery body to verify authenticity. The secret is surfaced
8546
+ * only on PUT — re-call this method to rotate.
8547
+ *
8548
+ * Server validates: HTTPS only, no loopback / RFC1918 / link-local /
8549
+ * CGNAT / cloud metadata destinations (SSRF guard).
8550
+ */
8551
+ async setWebhook(appId, webhookUrl) {
8552
+ return this.http.put(`/api/deployment/apps/${encodeURIComponent(appId)}/webhook`, {
8553
+ webhookUrl
8554
+ });
8555
+ }
8556
+ /**
8557
+ * Per-app Prometheus metrics in the standard exposition format
8558
+ * (text/plain; version=0.0.4). The server filters smart-deployer's
8559
+ * `/metrics` to lines that mention this app's `appId` label, while
8560
+ * preserving HELP / TYPE comment lines and cluster-wide metrics.
8561
+ *
8562
+ * Returned as a raw string so callers can pipe directly into a
8563
+ * Prometheus parser (`prom-client`, `parse-prometheus-text-format`,
8564
+ * etc.) without an intermediate JSON decode that would corrupt the
8565
+ * exposition format.
8566
+ */
8567
+ async getMetrics(appId) {
8568
+ return this.http.getText(`/api/deployment/apps/${encodeURIComponent(appId)}/metrics`);
8569
+ }
8570
+ /**
8571
+ * Rotate the smart-app's tenant-secret KEK (ADR-011 Phase 6).
8572
+ *
8573
+ * Re-encrypts every `runtime.env` envelope at the new KEK version
8574
+ * transparently. Previous versions remain valid until explicitly
8575
+ * revoked via {@link revokeKek}. Owner-only.
8576
+ */
8577
+ async rotateKek(appId) {
8578
+ return this.http.post(
8579
+ `/api/deployment/apps/${encodeURIComponent(appId)}/credentials/rotate-kek`,
8580
+ {}
8581
+ );
8582
+ }
8583
+ /**
8584
+ * Revoke a tenant-secret KEK version (ADR-011 Phase 6 emergency burn).
8585
+ *
8586
+ * Envelopes at the revoked version become operationally dead —
8587
+ * decryption inside the smart-app pod fails. Owner-only and
8588
+ * **irreversible**. Returns the cumulative list of revoked versions
8589
+ * for this app.
8590
+ */
8591
+ async revokeKek(appId, version) {
8592
+ return this.http.post(
8593
+ `/api/deployment/apps/${encodeURIComponent(appId)}/credentials/revoke-kek`,
8594
+ { version }
8595
+ );
8596
+ }
8597
+ };
8598
+
8599
+ // src/bridge/index.ts
8600
+ var bridge_exports = {};
8601
+ __export(bridge_exports, {
8602
+ BridgeClient: () => BridgeClient
8603
+ });
8604
+
8605
+ // src/bridge/bridge-client.ts
8606
+ var BridgeClient = class {
8607
+ constructor(http) {
8608
+ this.http = http;
8609
+ }
8610
+ http;
8611
+ /** Create a new bridge instance — triggers DKG + TSS entity creation server-side. */
8612
+ async create(request) {
8613
+ return this.http.post("/bridge/create", request);
8614
+ }
8615
+ /** List bridges. Both filters are optional. */
8616
+ async list(options) {
8617
+ const params = new URLSearchParams();
8618
+ if (options?.status) params.append("status", options.status);
8619
+ if (options?.sourceChain) params.append("sourceChain", options.sourceChain);
8620
+ const qs = params.toString();
8621
+ return this.http.get(`/bridge/list${qs ? `?${qs}` : ""}`);
8622
+ }
8623
+ /** Get bridge configuration. */
8624
+ async get(bridgeId) {
8625
+ return this.http.get(`/bridge/${encodePathParam(bridgeId)}`);
8626
+ }
8627
+ /** Port tokens from source → destination. */
8628
+ async port(bridgeId, request) {
8629
+ return this.http.post(`/bridge/${encodePathParam(bridgeId)}/port`, request);
8630
+ }
8631
+ /**
8632
+ * Return tokens from destination → source. Only meaningful on two-way
8633
+ * bridges; the validator rejects the call on one-way bridges with a 400.
8634
+ *
8635
+ * Method name is `return_` to avoid colliding with the reserved JS
8636
+ * keyword in some downstream codegen. Prefer `client.bridge.return(...)`
8637
+ * via the named alias below.
8638
+ */
8639
+ async return(bridgeId, request) {
8640
+ return this.http.post(`/bridge/${encodePathParam(bridgeId)}/return`, request);
8641
+ }
8642
+ /** Get claim status by claim ID under a given bridge. */
8643
+ async getStatus(bridgeId, claimId) {
8644
+ return this.http.get(
8645
+ `/bridge/${encodePathParam(bridgeId)}/status/${encodePathParam(claimId)}`
8646
+ );
8647
+ }
8648
+ /** Get aggregate supply view for a bridge. */
8649
+ async getSupply(bridgeId) {
8650
+ return this.http.get(`/bridge/${encodePathParam(bridgeId)}/supply`);
8651
+ }
8652
+ /** List bridge claims with optional pagination. */
8653
+ async listClaims(bridgeId, options) {
8654
+ const params = new URLSearchParams();
8655
+ if (options?.limit !== void 0) params.append("limit", String(options.limit));
8656
+ if (options?.offset !== void 0) params.append("offset", String(options.offset));
8657
+ const qs = params.toString();
8658
+ return this.http.get(
8659
+ `/bridge/${encodePathParam(bridgeId)}/claims${qs ? `?${qs}` : ""}`
8660
+ );
8661
+ }
8662
+ };
8663
+
8664
+ // src/resources/index.ts
8665
+ var resources_exports = {};
8666
+ __export(resources_exports, {
8667
+ ResourcesClient: () => ResourcesClient
8668
+ });
8669
+
8670
+ // src/resources/resources-client.ts
8671
+ var ResourcesClient = class {
8672
+ constructor(http) {
8673
+ this.http = http;
8674
+ }
8675
+ http;
8676
+ /** Network-wide consumption summary across all nodes. */
8677
+ async getSummary() {
8678
+ return this.http.get("/resources/summary");
8679
+ }
8680
+ /** Current-day consumption breakdown for an app. */
8681
+ async getConsumption(appId) {
8682
+ return this.http.get(`/resources/consumption/${encodePathParam(appId)}`);
8683
+ }
8684
+ /** Daily usage history from the persistent store. `days` defaults to 30 server-side. */
8685
+ async getHistory(appId, days) {
8686
+ const qs = days !== void 0 ? `?days=${days}` : "";
8687
+ return this.http.get(
8688
+ `/resources/consumption/${encodePathParam(appId)}/history${qs}`
8689
+ );
8690
+ }
8691
+ /** Paginated billing ledger. All filters optional. */
8692
+ async getLedger(appId, options) {
8693
+ const params = new URLSearchParams();
8694
+ if (options?.limit !== void 0) params.append("limit", String(options.limit));
8695
+ if (options?.offset !== void 0) params.append("offset", String(options.offset));
8696
+ if (options?.since) params.append("since", options.since);
8697
+ if (options?.until) params.append("until", options.until);
8698
+ if (options?.category) params.append("category", options.category);
8699
+ const qs = params.toString();
8700
+ return this.http.get(
8701
+ `/resources/consumption/${encodePathParam(appId)}/ledger${qs ? `?${qs}` : ""}`
8702
+ );
8703
+ }
8704
+ /**
8705
+ * Current consumption status with threshold warnings and upgrade hints.
8706
+ * `dailyLimit` overrides the per-app tier default and is rare —
8707
+ * smart-app callers should leave it unset.
8708
+ */
8709
+ async getStatus(appId, dailyLimit) {
8710
+ const qs = dailyLimit !== void 0 ? `?dailyLimit=${dailyLimit}` : "";
8711
+ return this.http.get(
8712
+ `/resources/consumption/${encodePathParam(appId)}/status${qs}`
8713
+ );
8714
+ }
8715
+ /** Consumption aggregated by category over the supplied window. */
8716
+ async getBreakdown(appId, options) {
8717
+ const params = new URLSearchParams();
8718
+ if (options?.since) params.append("since", options.since);
8719
+ if (options?.until) params.append("until", options.until);
8720
+ const qs = params.toString();
8721
+ return this.http.get(
8722
+ `/resources/consumption/${encodePathParam(appId)}/breakdown${qs ? `?${qs}` : ""}`
8723
+ );
8724
+ }
8725
+ /** Per-node consumption reports. */
8726
+ async listNodes() {
8727
+ return this.http.get("/resources/nodes");
8728
+ }
8729
+ /** Single node's report. */
8730
+ async getNode(nodeId) {
8731
+ return this.http.get(`/resources/nodes/${encodePathParam(nodeId)}`);
8732
+ }
8733
+ };
8734
+
8735
+ // src/envelope/index.ts
8736
+ var envelope_exports = {};
8737
+ __export(envelope_exports, {
8738
+ EnvelopeClient: () => EnvelopeClient
8739
+ });
8740
+
8741
+ // src/envelope/envelope-client.ts
8742
+ var EnvelopeClient = class {
8743
+ constructor(http) {
8744
+ this.http = http;
8745
+ }
8746
+ http;
8747
+ /**
8748
+ * Seal `plaintext` under the per-app KEK for `appId` at `kekVersion`.
8749
+ * Returns the canonical envelope shape suitable for persistence in
8750
+ * Mongo / NATS / on the EventBus.
8751
+ */
8752
+ async encrypt(request) {
8753
+ return this.http.post("/envelope/encrypt", request);
8754
+ }
8755
+ /**
8756
+ * Open `envelope` for `appId`. The plaintext is returned in the response
8757
+ * body — callers MUST treat it as ephemeral (no logs, no Mongo, no
8758
+ * NATS broadcast). The validator never persists or replays it.
8759
+ */
8760
+ async decrypt(request) {
8761
+ return this.http.post("/envelope/decrypt", request);
8762
+ }
8763
+ };
8764
+
8765
+ // src/tokens/index.ts
8766
+ var tokens_exports = {};
8767
+ __export(tokens_exports, {
8768
+ TokensClient: () => TokensClient
8769
+ });
8770
+
8771
+ // src/tokens/tokens-client.ts
8772
+ var TokensClient = class {
8773
+ constructor(http) {
8774
+ this.http = http;
8775
+ }
8776
+ http;
8777
+ /** Initiate a token migration to TSS-controlled keys. */
8778
+ async migrate(request) {
8779
+ return this.http.post("/tokens/migrate", request);
8780
+ }
8781
+ /** List all known migrations on this validator. */
8782
+ async listMigrations() {
8783
+ return this.http.get("/tokens/migrations");
8784
+ }
8785
+ /**
8786
+ * Get one migration's status by id. The server returns
8787
+ * `{ error: string }` (NOT a 404) when the migration is unknown, so the
8788
+ * union type makes the failure mode explicit.
8789
+ */
8790
+ async getMigration(migrationId) {
8791
+ return this.http.get(`/tokens/migrations/${encodePathParam(migrationId)}`);
8792
+ }
8793
+ /** All migrations recorded against a specific token id. */
8794
+ async getMigrationsForToken(tokenId) {
8795
+ return this.http.get(`/tokens/${encodePathParam(tokenId)}/migrations`);
8796
+ }
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
+ };
8808
+
8809
+ // src/operator/index.ts
8810
+ var operator_exports = {};
8811
+ __export(operator_exports, {
8812
+ OperatorClient: () => OperatorClient
8813
+ });
8814
+
8815
+ // src/operator/operator-client.ts
8816
+ var OperatorClient = class {
8817
+ constructor(http) {
8818
+ this.http = http;
8819
+ }
8820
+ http;
8821
+ /** Get the on-chain HBAR + token balance of an operator account. */
8822
+ async getBalance(chain, accountId) {
8823
+ return this.http.get(
8824
+ `/operator/balance/${encodePathParam(chain)}/${encodePathParam(accountId)}`
8825
+ );
8826
+ }
8827
+ /** Get top-up guidance for an operator account (recommended balance + status). */
8828
+ async getTopup(chain, accountId) {
8829
+ return this.http.get(
8830
+ `/operator/topup/${encodePathParam(chain)}/${encodePathParam(accountId)}`
8831
+ );
8832
+ }
8833
+ };
8834
+
8835
+ // src/client.ts
8836
+ var SmartEngineClient = class _SmartEngineClient {
8837
+ baseUrl;
8838
+ allowInsecure;
8839
+ http;
8840
+ /** Separate HTTP client for /api/transactions (non-v3 base path) */
8841
+ txHttp;
8842
+ /** Last HTTP error (for getHttpHealth) */
7958
8843
  lastHttpError;
7959
8844
  // ========== Sub-Clients ==========
7960
8845
  /** Application subscription management */
@@ -7981,12 +8866,26 @@ var SmartEngineClient = class _SmartEngineClient {
7981
8866
  settlement;
7982
8867
  /** Governance proposal dry-run (simulate-only) */
7983
8868
  governance;
8869
+ /** DAO governance — DAOs, proposals, votes, treasury, members, dashboard */
8870
+ dao;
7984
8871
  /** Personhood verification (HPP one-human-one-member) */
7985
8872
  personhood;
7986
8873
  /** BaaS smart-agent lifecycle (register/fund/trade/withdraw/pause/resume/revoke/...) */
7987
8874
  agents;
7988
8875
  /** BaaS smart-app deployment lifecycle (init/uploadFrontend/deploy/rollback/status/...) */
7989
8876
  deployments;
8877
+ /** Universal Token Bridge — port/return/claim across chains */
8878
+ bridge;
8879
+ /** Network + per-app resource consumption (summary, history, ledger, nodes) */
8880
+ resources;
8881
+ /** AES-256-GCM envelope encrypt/decrypt under the TSS-backed master KEK */
8882
+ envelope;
8883
+ /** Token migration — move existing tokens to TSS-controlled keys */
8884
+ tokens;
8885
+ /** Operator account funding helpers (balance + top-up guidance) */
8886
+ operator;
8887
+ /** Discovery endpoints — cluster registry + platform-image manifests */
8888
+ discovery;
7990
8889
  constructor(config) {
7991
8890
  this.allowInsecure = config.allowInsecure ?? false;
7992
8891
  this.baseUrl = validateClientUrl(config.baseUrl, this.allowInsecure);
@@ -8006,7 +8905,7 @@ var SmartEngineClient = class _SmartEngineClient {
8006
8905
  this.tss = new TSSClient(this.http);
8007
8906
  this.ipfs = new IPFSClient(this.http);
8008
8907
  this.transactions = new TransactionsClient(this.txHttp);
8009
- this.hedera = new HederaTransactionsClient(this.txHttp);
8908
+ this.hedera = new HederaTransactionsClient(this.txHttp, this.http);
8010
8909
  this.xrpl = new XrplTransactionsClient(this.txHttp);
8011
8910
  this.solana = new SolanaTransactionsClient(this.txHttp);
8012
8911
  this.polkadot = new PolkadotTransactionsClient(this.txHttp);
@@ -8014,6 +8913,7 @@ var SmartEngineClient = class _SmartEngineClient {
8014
8913
  this.historicalBalance = HistoricalBalanceClient.fromHttp(this.http);
8015
8914
  this.settlement = new SettlementClient(this.http);
8016
8915
  this.governance = new GovernanceClient(this.http);
8916
+ this.dao = new DaoClient(this.http);
8017
8917
  this.personhood = new PersonhoodClient(this.http);
8018
8918
  const rootHttp = createHttpClient({
8019
8919
  baseUrl: this.baseUrl,
@@ -8023,6 +8923,12 @@ var SmartEngineClient = class _SmartEngineClient {
8023
8923
  });
8024
8924
  this.agents = new AgentsClient(rootHttp);
8025
8925
  this.deployments = new DeploymentClient(rootHttp);
8926
+ this.bridge = new BridgeClient(this.http);
8927
+ this.resources = new ResourcesClient(this.http);
8928
+ this.envelope = new EnvelopeClient(this.http);
8929
+ this.tokens = new TokensClient(this.http);
8930
+ this.operator = new OperatorClient(this.http);
8931
+ this.discovery = new DiscoveryClient(this.http);
8026
8932
  }
8027
8933
  /**
8028
8934
  * Build a `SmartEngineClient` from a plain env object. Reads:
@@ -8238,7 +9144,19 @@ var SmartEngineClient = class _SmartEngineClient {
8238
9144
  const validated = MintTokenRequestSchema.parse(request);
8239
9145
  return this.http.post("/tokens/mint", validated);
8240
9146
  }
8241
- /** Get token information */
9147
+ /**
9148
+ * Get token information.
9149
+ *
9150
+ * Route `GET /api/v3/tokens/:chain/:tokenId` is registered twice on the
9151
+ * validator: by `ValidatorController` at
9152
+ * `apps/smart-validator/src/validator.controller.ts:497` and by
9153
+ * `TokenMigrationController` at
9154
+ * `apps/smart-validator/src/token-migration/token-migration.controller.ts:173`.
9155
+ * Nest resolves routes in `controllers: [...]` order — `ValidatorController`
9156
+ * is registered first (`apps/smart-validator/src/smart-validator.module.ts:1222`),
9157
+ * so `multiChain.getTokenInfo(chain, tokenId)` wins and the
9158
+ * token-migration handler is unreachable via this path.
9159
+ */
8242
9160
  async getTokenInfo(chain, tokenId) {
8243
9161
  return this.http.get(`/tokens/${encodePathParam(chain)}/${encodePathParam(tokenId)}`);
8244
9162
  }
@@ -8386,47 +9304,56 @@ var RoutingClient = class {
8386
9304
  this.http = http;
8387
9305
  }
8388
9306
  http;
8389
- /** Register a new host */
9307
+ /**
9308
+ * Register a new host. The server validates the payload via Zod (appId
9309
+ * pattern, IP/hostname format, port range) and kicks off async
9310
+ * verification. Response includes the registered host plus a status
9311
+ * message about verification.
9312
+ */
8390
9313
  async registerHost(request) {
8391
9314
  return this.http.post("/routing/hosts", request);
8392
9315
  }
8393
- /** Unregister a host */
9316
+ /** Unregister a host. */
8394
9317
  async unregisterHost(hostId) {
8395
9318
  return this.http.delete(`/routing/hosts/${encodeURIComponent(hostId)}`);
8396
9319
  }
8397
- /** Get all registered hosts */
9320
+ /** Get all registered hosts. */
8398
9321
  async getAllHosts() {
8399
9322
  return this.http.get("/routing/hosts");
8400
9323
  }
8401
- /** Get only verified hosts */
9324
+ /** Get only verified hosts. */
8402
9325
  async getVerifiedHosts() {
8403
9326
  return this.http.get("/routing/hosts/verified");
8404
9327
  }
8405
- /** Get a specific host by ID */
9328
+ /** Get a specific host by ID. */
8406
9329
  async getHost(hostId) {
8407
9330
  return this.http.get(`/routing/hosts/${encodeURIComponent(hostId)}`);
8408
9331
  }
8409
- /** Verify a host */
9332
+ /** Trigger host re-verification. */
8410
9333
  async verifyHost(hostId) {
8411
9334
  return this.http.post(`/routing/hosts/${encodeURIComponent(hostId)}/verify`, {});
8412
9335
  }
8413
- /** Set routing configuration for an app */
9336
+ /** Set routing configuration for an app. */
8414
9337
  async setRoutingConfig(appId, config) {
8415
9338
  return this.http.put(`/routing/config/${encodeURIComponent(appId)}`, config);
8416
9339
  }
8417
- /** Get routing configuration for an app */
9340
+ /** Get routing configuration for an app. */
8418
9341
  async getRoutingConfig(appId) {
8419
9342
  return this.http.get(`/routing/config/${encodeURIComponent(appId)}`);
8420
9343
  }
8421
- /** Proxy a request through the gateway */
9344
+ /** Proxy a request through the gateway. */
8422
9345
  async proxyRequest(request) {
8423
9346
  return this.http.post("/routing/proxy", request);
8424
9347
  }
8425
- /** Get routing statistics */
9348
+ /** Get routing statistics. */
8426
9349
  async getStats() {
8427
9350
  return this.http.get("/routing/stats");
8428
9351
  }
8429
- /** Map a domain to an application */
9352
+ /**
9353
+ * Map a domain/subdomain to an application for hostname-based routing.
9354
+ * The server returns `{ domain, appId, message }` — there is no `success`
9355
+ * field; treat `appId` as the success signal.
9356
+ */
8430
9357
  async mapDomainToApp(domain, appId) {
8431
9358
  return this.http.post(`/routing/domains/${encodeURIComponent(domain)}/map`, { appId });
8432
9359
  }
@@ -8455,7 +9382,11 @@ var DomainsClient = class {
8455
9382
  const params = owner ? `?owner=${encodeURIComponent(owner)}` : "";
8456
9383
  return this.http.get(`/domains${params}`);
8457
9384
  }
8458
- /** Generate a verification token */
9385
+ /**
9386
+ * Generate a verification token. Server accepts one of `dns-txt`,
9387
+ * `dns-cname`, `http-file`, `email` (see controller Swagger enum at
9388
+ * `apps/smart-gateway/src/domains/domains.controller.ts:226-234`).
9389
+ */
8459
9390
  async generateVerificationToken(domain, method) {
8460
9391
  return this.http.post(`/domains/${encodeURIComponent(domain)}/verification`, { method });
8461
9392
  }
@@ -8571,6 +9502,23 @@ var DnsClient = class {
8571
9502
  }
8572
9503
  };
8573
9504
 
9505
+ // src/gateway/health/index.ts
9506
+ var HealthClient = class {
9507
+ constructor(http) {
9508
+ this.http = http;
9509
+ }
9510
+ http;
9511
+ /**
9512
+ * Per-cluster aggregate health probe. Wraps
9513
+ * `GET /api/v3/cluster/health` — see
9514
+ * `apps/smart-gateway/src/health/health.controller.ts:213-263`. Returns
9515
+ * local validator + host + genesis state in a single payload.
9516
+ */
9517
+ async getCluster() {
9518
+ return this.http.get("/cluster/health");
9519
+ }
9520
+ };
9521
+
8574
9522
  // src/gateway/client.ts
8575
9523
  var SmartGatewayClient = class {
8576
9524
  http;
@@ -8580,6 +9528,8 @@ var SmartGatewayClient = class {
8580
9528
  domains;
8581
9529
  /** DNS resolution and zone management */
8582
9530
  dns;
9531
+ /** Per-cluster aggregate health probe (validator + host + genesis state) */
9532
+ health;
8583
9533
  constructor(config) {
8584
9534
  const baseUrl = config.baseUrl.replace(/\/+$/, "");
8585
9535
  this.http = createHttpClient({
@@ -8591,30 +9541,41 @@ var SmartGatewayClient = class {
8591
9541
  this.routing = new RoutingClient(this.http);
8592
9542
  this.domains = new DomainsClient(this.http);
8593
9543
  this.dns = new DnsClient(this.http);
9544
+ this.health = new HealthClient(this.http);
8594
9545
  }
8595
9546
  // ========== Health & Metrics ==========
8596
- /** Get gateway health status */
9547
+ /** Get gateway-only health status (binary `status: 'ok'` snapshot). */
8597
9548
  async getHealth() {
8598
9549
  return this.http.get("/health");
8599
9550
  }
8600
- /** Get gateway status with host and domain counts */
9551
+ /**
9552
+ * Get detailed gateway status — `subsystems` tree (dns/routing/verification)
9553
+ * plus the operating `mode` snapshot. Aggregated counts live on `getMetrics()`.
9554
+ */
8601
9555
  async getStatus() {
8602
9556
  return this.http.get("/status");
8603
9557
  }
8604
- /** Check gateway readiness */
9558
+ /**
9559
+ * Check gateway readiness. Returns either `{ status: 'ready', ... }` with
9560
+ * a verified host count or `{ status: 'not_ready', reason, ... }`.
9561
+ */
8605
9562
  async getReadiness() {
8606
9563
  return this.http.get("/ready");
8607
9564
  }
8608
- /** Check gateway liveness */
9565
+ /** Check gateway liveness. */
8609
9566
  async getLiveness() {
8610
9567
  return this.http.get("/live");
8611
9568
  }
8612
- /** Get detailed gateway metrics */
9569
+ /**
9570
+ * Get aggregated network metrics across all clusters — per-cluster health,
9571
+ * chain connectivity, gateway counts, and genesis state. Server caches the
9572
+ * payload (default 30s); pass `refresh=true` to force a fresh fetch.
9573
+ */
8613
9574
  async getMetrics(refresh) {
8614
9575
  const params = refresh ? "?refresh=true" : "";
8615
9576
  return this.http.get(`/metrics${params}`);
8616
9577
  }
8617
- /** Get metrics summary */
9578
+ /** Get lightweight network summary (status-badge-friendly). */
8618
9579
  async getMetricsSummary() {
8619
9580
  return this.http.get("/metrics/summary");
8620
9581
  }
@@ -9187,11 +10148,37 @@ var DatabaseClient = class {
9187
10148
  );
9188
10149
  }
9189
10150
  /**
9190
- * List collections for the app
10151
+ * List collections for the app.
10152
+ *
10153
+ * Server route is `/api/db/:appId/collections`
10154
+ * (`database.controller.ts:106`). The previous bare-`:appId` GET 404'd
10155
+ * — Nest reserves that pattern for the document-find router below.
9191
10156
  */
9192
10157
  async listCollections() {
9193
10158
  const appId = this.getAppId();
9194
- return this.http.get(`/api/db/${encodeURIComponent(appId)}`);
10159
+ return this.http.get(`/api/db/${encodeURIComponent(appId)}/collections`);
10160
+ }
10161
+ /**
10162
+ * Create a new collection in the database.
10163
+ *
10164
+ * Server returns `{ success: true; collection: string }`
10165
+ * (`database.controller.ts:96`).
10166
+ */
10167
+ async createCollection(name) {
10168
+ const appId = this.getAppId();
10169
+ return this.http.post(`/api/db/${encodeURIComponent(appId)}/collections`, { name });
10170
+ }
10171
+ /**
10172
+ * Drop a collection and all its documents.
10173
+ *
10174
+ * Server returns `{ success: true }`
10175
+ * (`database.controller.ts:133`).
10176
+ */
10177
+ async dropCollection(name) {
10178
+ const appId = this.getAppId();
10179
+ return this.http.delete(
10180
+ `/api/db/${encodeURIComponent(appId)}/collections/${encodeURIComponent(name)}`
10181
+ );
9195
10182
  }
9196
10183
  // ========== State Proofs ==========
9197
10184
  /**
@@ -9252,13 +10239,15 @@ var StorageClient = class {
9252
10239
  * Download a file by CID
9253
10240
  */
9254
10241
  async download(cid) {
9255
- return this.http.get(`/api/storage/download/${encodeURIComponent(cid)}`);
10242
+ const appId = this.getAppId();
10243
+ return this.http.get(`/api/storage/${encodeURIComponent(appId)}/download/${encodeURIComponent(cid)}`);
9256
10244
  }
9257
10245
  /**
9258
10246
  * Get file metadata
9259
10247
  */
9260
10248
  async getMetadata(cid) {
9261
- return this.http.get(`/api/storage/metadata/${encodeURIComponent(cid)}`);
10249
+ const appId = this.getAppId();
10250
+ return this.http.get(`/api/storage/${encodeURIComponent(appId)}/metadata/${encodeURIComponent(cid)}`);
9262
10251
  }
9263
10252
  /**
9264
10253
  * Delete a file
@@ -9268,20 +10257,29 @@ var StorageClient = class {
9268
10257
  return this.http.delete(`/api/storage/${encodeURIComponent(appId)}/${encodeURIComponent(cid)}`);
9269
10258
  }
9270
10259
  /**
9271
- * Get file info
10260
+ * Get file info.
10261
+ *
10262
+ * @deprecated The smart-host storage controller does not expose a
10263
+ * bare-CID metadata route — every metadata lookup must go through
10264
+ * `getMetadata(cid)` (`/api/storage/:appId/metadata/:cid`) or the
10265
+ * stream body via `download(cid)`. This alias forwards to `download`
10266
+ * for back-compat; remove in the next major SDK release.
9272
10267
  */
9273
10268
  async getFile(cid) {
9274
- const appId = this.getAppId();
9275
- return this.http.get(`/api/storage/${encodeURIComponent(appId)}/${encodeURIComponent(cid)}`);
10269
+ return this.download(cid);
9276
10270
  }
9277
10271
  /**
9278
10272
  * List all files for the app
10273
+ *
10274
+ * @param pagination.offset Server reads `offset`; the legacy `skip`
10275
+ * option was a client-only synonym that the server silently ignored.
10276
+ * Use `offset` going forward.
9279
10277
  */
9280
10278
  async listFiles(pagination) {
9281
10279
  const appId = this.getAppId();
9282
10280
  const params = new URLSearchParams();
9283
10281
  if (pagination?.limit !== void 0) params.set("limit", String(pagination.limit));
9284
- if (pagination?.skip !== void 0) params.set("skip", String(pagination.skip));
10282
+ if (pagination?.offset !== void 0) params.set("offset", String(pagination.offset));
9285
10283
  const qs = params.toString();
9286
10284
  return this.http.get(`/api/storage/${encodeURIComponent(appId)}/files${qs ? `?${qs}` : ""}`);
9287
10285
  }
@@ -9289,13 +10287,15 @@ var StorageClient = class {
9289
10287
  * Get storage usage for the current app
9290
10288
  */
9291
10289
  async getUsage() {
9292
- return this.http.get("/api/storage/usage");
10290
+ const appId = this.getAppId();
10291
+ return this.http.get(`/api/storage/${encodeURIComponent(appId)}/usage`);
9293
10292
  }
9294
10293
  /**
9295
10294
  * Check if a file exists
9296
10295
  */
9297
10296
  async exists(cid) {
9298
- return this.http.get(`/api/storage/exists/${encodeURIComponent(cid)}`);
10297
+ const appId = this.getAppId();
10298
+ return this.http.get(`/api/storage/${encodeURIComponent(appId)}/exists/${encodeURIComponent(cid)}`);
9299
10299
  }
9300
10300
  };
9301
10301
 
@@ -9318,42 +10318,60 @@ var FunctionsClient = class {
9318
10318
  * Invoke a function
9319
10319
  */
9320
10320
  async invoke(functionId, payload) {
9321
- return this.http.post(`/api/functions/${encodeURIComponent(functionId)}/invoke`, payload ?? {});
10321
+ const appId = this.getAppId();
10322
+ return this.http.post(
10323
+ `/api/functions/${encodeURIComponent(appId)}/${encodeURIComponent(functionId)}/invoke`,
10324
+ payload ?? {}
10325
+ );
9322
10326
  }
9323
10327
  /**
9324
- * List all functions
10328
+ * List all functions for the current app
9325
10329
  */
9326
10330
  async list() {
9327
- return this.http.get("/api/functions");
10331
+ const appId = this.getAppId();
10332
+ return this.http.get(`/api/functions/${encodeURIComponent(appId)}`);
9328
10333
  }
9329
10334
  /**
9330
10335
  * Get function details
9331
10336
  */
9332
10337
  async get(functionId) {
9333
- return this.http.get(`/api/functions/${encodeURIComponent(functionId)}`);
10338
+ const appId = this.getAppId();
10339
+ return this.http.get(
10340
+ `/api/functions/${encodeURIComponent(appId)}/${encodeURIComponent(functionId)}`
10341
+ );
9334
10342
  }
9335
10343
  /**
9336
10344
  * Update a function
9337
10345
  */
9338
10346
  async update(functionId, updates) {
9339
- return this.http.put(`/api/functions/${encodeURIComponent(functionId)}`, updates);
10347
+ const appId = this.getAppId();
10348
+ return this.http.put(
10349
+ `/api/functions/${encodeURIComponent(appId)}/${encodeURIComponent(functionId)}`,
10350
+ updates
10351
+ );
9340
10352
  }
9341
10353
  /**
9342
10354
  * Delete a function
9343
10355
  */
9344
10356
  async delete(functionId) {
9345
- return this.http.delete(`/api/functions/${encodeURIComponent(functionId)}`);
10357
+ const appId = this.getAppId();
10358
+ return this.http.delete(
10359
+ `/api/functions/${encodeURIComponent(appId)}/${encodeURIComponent(functionId)}`
10360
+ );
9346
10361
  }
9347
10362
  /**
9348
10363
  * Get function execution logs
9349
10364
  */
9350
10365
  async getLogs(functionId, options) {
10366
+ const appId = this.getAppId();
9351
10367
  const params = new URLSearchParams();
9352
10368
  if (options?.limit !== void 0) params.set("limit", String(options.limit));
9353
10369
  if (options?.startTime) params.set("startTime", options.startTime);
9354
10370
  if (options?.level) params.set("level", options.level);
9355
10371
  const qs = params.toString();
9356
- return this.http.get(`/api/functions/${encodeURIComponent(functionId)}/logs${qs ? `?${qs}` : ""}`);
10372
+ return this.http.get(
10373
+ `/api/functions/${encodeURIComponent(appId)}/${encodeURIComponent(functionId)}/logs${qs ? `?${qs}` : ""}`
10374
+ );
9357
10375
  }
9358
10376
  /**
9359
10377
  * Get function statistics for an app
@@ -9425,25 +10443,43 @@ var MessagingClient = class {
9425
10443
  );
9426
10444
  }
9427
10445
  /**
9428
- * Set presence for a member
10446
+ * Set presence for a member in a channel.
10447
+ *
10448
+ * BREAKING CHANGE (SDK 3.3.0): presence is channel-scoped on the server
10449
+ * (`messaging.controller.ts:312`). Previous signature
10450
+ * `setPresence(member)` hit a non-existent appId-scoped route and 404'd
10451
+ * in production. The channel is now the first argument.
9429
10452
  */
9430
- async setPresence(member) {
10453
+ async setPresence(channel, member) {
9431
10454
  const appId = this.getAppId();
9432
- return this.http.post(`/api/messaging/${encodeURIComponent(appId)}/presence`, member);
10455
+ return this.http.post(
10456
+ `/api/messaging/${encodeURIComponent(appId)}/channels/${encodeURIComponent(channel)}/presence`,
10457
+ member
10458
+ );
9433
10459
  }
9434
10460
  /**
9435
- * Remove presence for a member
10461
+ * Remove a member's presence from a channel.
10462
+ *
10463
+ * BREAKING CHANGE (SDK 3.3.0): server route is
10464
+ * `/api/messaging/:appId/channels/:channel/presence/:clientId`
10465
+ * (`messaging.controller.ts:352`). `channel` is now the first arg and
10466
+ * `clientId` (not `memberId`) the second — they're the same identifier
10467
+ * but renamed to match the server param.
9436
10468
  */
9437
- async removePresence(memberId) {
10469
+ async removePresence(channel, clientId) {
9438
10470
  const appId = this.getAppId();
9439
- return this.http.delete(`/api/messaging/${encodeURIComponent(appId)}/presence/${encodeURIComponent(memberId)}`);
10471
+ return this.http.delete(
10472
+ `/api/messaging/${encodeURIComponent(appId)}/channels/${encodeURIComponent(channel)}/presence/${encodeURIComponent(clientId)}`
10473
+ );
9440
10474
  }
9441
10475
  /**
9442
10476
  * Get presence info for a channel
9443
10477
  */
9444
10478
  async getPresence(channel) {
9445
10479
  const appId = this.getAppId();
9446
- return this.http.get(`/api/messaging/${encodeURIComponent(appId)}/presence/${encodeURIComponent(channel)}`);
10480
+ return this.http.get(
10481
+ `/api/messaging/${encodeURIComponent(appId)}/channels/${encodeURIComponent(channel)}/presence`
10482
+ );
9447
10483
  }
9448
10484
  /**
9449
10485
  * Get messaging statistics
@@ -10068,52 +11104,196 @@ async function verifyPqcAttestation(cert, payload, registrySnapshot) {
10068
11104
  };
10069
11105
  }
10070
11106
 
10071
- // src/rules/builders/base-builder.ts
10072
- var RuleBuildError = class extends Error {
10073
- errors;
10074
- constructor(message, errors) {
10075
- super(message);
10076
- this.name = "RuleBuildError";
10077
- this.errors = errors;
10078
- }
10079
- };
10080
- var BaseRuleBuilder = class {
10081
- state;
10082
- constructor(type, initial) {
10083
- this.state = initial ?? {};
10084
- this.state.version = "3.0";
10085
- this.state.type = type;
10086
- this.state.created = (/* @__PURE__ */ new Date()).toISOString();
10087
- if (!this.state.defaultSecurity) this.state.defaultSecurity = "full";
10088
- if (!this.state.defaultController) this.state.defaultController = "owner";
10089
- }
10090
- withSecurity(mode) {
10091
- this.state.defaultSecurity = mode;
10092
- return this;
10093
- }
10094
- withController(controller) {
10095
- this.state.defaultController = controller;
10096
- return this;
10097
- }
10098
- withGovernance(governance) {
10099
- this.state.governance = governance;
10100
- return this;
10101
- }
10102
- withTokenGates(tokenGates) {
10103
- this.state.tokenGates = tokenGates;
10104
- return this;
10105
- }
10106
- withTimeRange(timeRange) {
10107
- this.state.timeRange = timeRange;
10108
- return this;
10109
- }
10110
- withMetadata(metadata) {
10111
- this.state.metadata = metadata;
10112
- return this;
10113
- }
10114
- withModules(modules) {
10115
- this.state.modules = modules;
10116
- return this;
11107
+ // src/rules/atoms/index.ts
11108
+ var atom = {
11109
+ timeRange: (cfg) => ({
11110
+ inclusive: true,
11111
+ timezone: "UTC",
11112
+ ...cfg
11113
+ }),
11114
+ limits: (cfg) => ({
11115
+ decimals: 0,
11116
+ inclusive: true,
11117
+ ...cfg
11118
+ }),
11119
+ permissionList: (cfg) => ({
11120
+ mode: "whitelist",
11121
+ controller: "owner",
11122
+ allowSelfAdd: false,
11123
+ allowWildcards: false,
11124
+ requiredScope: "execute",
11125
+ entries: [],
11126
+ ...cfg
11127
+ }),
11128
+ rateLimiter: (cfg) => ({
11129
+ strategy: "all",
11130
+ includeCurrentOperation: true,
11131
+ ...cfg
11132
+ }),
11133
+ cooldown: (cfg) => ({ ...cfg }),
11134
+ approvalThreshold: (cfg) => ({
11135
+ decimals: 0,
11136
+ ...cfg
11137
+ }),
11138
+ approvedPairs: (cfg) => ({
11139
+ strictMode: true,
11140
+ ...cfg
11141
+ }),
11142
+ tradeLimit: (cfg) => ({
11143
+ periodMs: 864e5,
11144
+ decimals: 0,
11145
+ ...cfg
11146
+ }),
11147
+ snapshot: (cfg) => ({
11148
+ validationMode: "minimum",
11149
+ ...cfg
11150
+ }),
11151
+ cronSchedule: (cfg) => ({
11152
+ allowOutsideSchedule: false,
11153
+ toleranceMs: 0,
11154
+ ...cfg
11155
+ }),
11156
+ countApproval: (cfg) => ({
11157
+ maxCount: 0,
11158
+ allowDuplicates: false,
11159
+ maxApprovalAgeSec: 0,
11160
+ allowSelfApproval: false,
11161
+ ...cfg
11162
+ }),
11163
+ externalEvidence: (cfg) => ({
11164
+ requiredSignatures: 1,
11165
+ maxEvidenceAgeSec: 3600,
11166
+ verifyPayloadHash: true,
11167
+ ...cfg
11168
+ }),
11169
+ fieldValues: (cfg) => ({
11170
+ requireAll: true,
11171
+ ...cfg,
11172
+ constraints: cfg.constraints.map((c) => ({
11173
+ caseInsensitive: false,
11174
+ denyMode: false,
11175
+ ...c
11176
+ }))
11177
+ }),
11178
+ registryReference: (cfg) => ({
11179
+ requireAll: true,
11180
+ ...cfg,
11181
+ references: cfg.references.map((r) => ({ required: true, ...r }))
11182
+ }),
11183
+ schemaValidation: (cfg) => ({
11184
+ strict: false,
11185
+ allErrors: true,
11186
+ validateFormats: false,
11187
+ errorPrefix: "Schema validation failed",
11188
+ removeAdditional: false,
11189
+ useDefaults: false,
11190
+ coerceTypes: false,
11191
+ ...cfg
11192
+ }),
11193
+ stopLoss: (cfg) => ({ ...cfg }),
11194
+ workflowState: (cfg) => ({
11195
+ allowSelfTransition: false,
11196
+ ...cfg
11197
+ })
11198
+ };
11199
+
11200
+ // src/rules/molecules/index.ts
11201
+ var molecule = {
11202
+ tokenGate: (cfg) => ({
11203
+ overallOperator: "AND",
11204
+ allowDelegation: false,
11205
+ ...cfg,
11206
+ fungibles: cfg.fungibles ? { operator: "AND", ...cfg.fungibles } : void 0,
11207
+ nonFungibles: cfg.nonFungibles ? { operator: "OR", ...cfg.nonFungibles } : void 0
11208
+ }),
11209
+ airdrop: (cfg) => ({
11210
+ decimals: 0,
11211
+ claimMethod: "manual",
11212
+ ...cfg
11213
+ }),
11214
+ vesting: (cfg) => ({
11215
+ decimals: 0,
11216
+ cliffDurationMs: 0,
11217
+ initialUnlockPercent: 0,
11218
+ revocable: false,
11219
+ returnToTreasury: true,
11220
+ ...cfg
11221
+ }),
11222
+ governance: (cfg) => ({
11223
+ decimals: 0,
11224
+ votingPowerMethod: "token_balance",
11225
+ quorumPercent: 10,
11226
+ approvalThresholdPercent: 50,
11227
+ timeLockMs: 0,
11228
+ allowDelegation: true,
11229
+ allowVoteChange: false,
11230
+ maxActiveProposalsPerAccount: 3,
11231
+ proposalCooldownMs: 0,
11232
+ ...cfg
11233
+ }),
11234
+ streaming: (cfg) => ({
11235
+ decimals: 0,
11236
+ type: "linear",
11237
+ cancellable: true,
11238
+ pausable: false,
11239
+ cancelController: "sender",
11240
+ cliffDurationMs: 0,
11241
+ autoTopUp: false,
11242
+ ...cfg
11243
+ }),
11244
+ swap: (cfg = {}) => ({
11245
+ type: "atomic",
11246
+ requireAtomicity: true,
11247
+ ...cfg
11248
+ })
11249
+ };
11250
+
11251
+ // src/rules/builders/base-builder.ts
11252
+ var RuleBuildError = class extends Error {
11253
+ errors;
11254
+ constructor(message, errors) {
11255
+ super(message);
11256
+ this.name = "RuleBuildError";
11257
+ this.errors = errors;
11258
+ }
11259
+ };
11260
+ var BaseRuleBuilder = class {
11261
+ state;
11262
+ constructor(type, initial) {
11263
+ this.state = initial ?? {};
11264
+ this.state.version = "3.0";
11265
+ this.state.type = type;
11266
+ this.state.created = (/* @__PURE__ */ new Date()).toISOString();
11267
+ if (!this.state.defaultSecurity) this.state.defaultSecurity = "full";
11268
+ if (!this.state.defaultController) this.state.defaultController = "owner";
11269
+ }
11270
+ withSecurity(mode) {
11271
+ this.state.defaultSecurity = mode;
11272
+ return this;
11273
+ }
11274
+ withController(controller) {
11275
+ this.state.defaultController = controller;
11276
+ return this;
11277
+ }
11278
+ withGovernance(governance) {
11279
+ this.state.governance = governance;
11280
+ return this;
11281
+ }
11282
+ withTokenGates(tokenGates) {
11283
+ this.state.tokenGates = tokenGates;
11284
+ return this;
11285
+ }
11286
+ withTimeRange(timeRange) {
11287
+ this.state.timeRange = timeRange;
11288
+ return this;
11289
+ }
11290
+ withMetadata(metadata) {
11291
+ this.state.metadata = metadata;
11292
+ return this;
11293
+ }
11294
+ withModules(modules) {
11295
+ this.state.modules = modules;
11296
+ return this;
10117
11297
  }
10118
11298
  /** Add a single module entry on top of any previously set modules. */
10119
11299
  addModule(module) {
@@ -10124,6 +11304,108 @@ var BaseRuleBuilder = class {
10124
11304
  this.state.invariants = invariants;
10125
11305
  return this;
10126
11306
  }
11307
+ // ────────────────────────────────────────────────────────────────────────
11308
+ // PR F — first-class atom/molecule shortcuts (all arms)
11309
+ //
11310
+ // Each shortcut wraps the atom/molecule config as a canonical `ModuleEntry`
11311
+ // (lowercase-hyphenated type + `1.0.0` semver) and appends it to `modules`.
11312
+ // The cluster's organism registry maps `type → schema` at runtime; unknown
11313
+ // types fail-closed. These methods exist so smart-app authors can compose
11314
+ // atoms/molecules without hand-rolling `ModuleEntry` envelopes.
11315
+ // ────────────────────────────────────────────────────────────────────────
11316
+ /** Attach a per-tx + period + lifetime LimitsAtom config as a module. */
11317
+ withLimits(limits) {
11318
+ return this.addModule({
11319
+ type: "limits",
11320
+ version: "1.0.0",
11321
+ config: atom.limits(limits)
11322
+ });
11323
+ }
11324
+ /** Attach an operation-per-window RateLimiterAtom config as a module. */
11325
+ withRateLimiter(rateLimiter) {
11326
+ return this.addModule({
11327
+ type: "rate-limiter",
11328
+ version: "1.0.0",
11329
+ config: atom.rateLimiter(rateLimiter)
11330
+ });
11331
+ }
11332
+ /** Attach a pinned-state SnapshotAtom config as a module. */
11333
+ withSnapshot(snapshot) {
11334
+ return this.addModule({
11335
+ type: "snapshot",
11336
+ version: "1.0.0",
11337
+ config: atom.snapshot(snapshot)
11338
+ });
11339
+ }
11340
+ /** Attach a swap-molecule config as a module (atomic / pool / order / OTC). */
11341
+ withSwap(swap = {}) {
11342
+ return this.addModule({
11343
+ type: "swap",
11344
+ version: "1.0.0",
11345
+ config: molecule.swap(swap)
11346
+ });
11347
+ }
11348
+ /** Attach an airdrop-molecule config as a module. */
11349
+ withAirdrop(airdrop) {
11350
+ return this.addModule({
11351
+ type: "airdrop",
11352
+ version: "1.0.0",
11353
+ config: molecule.airdrop(airdrop)
11354
+ });
11355
+ }
11356
+ /** Attach a vesting-molecule config as a module (beneficiary-scoped lockup). */
11357
+ withVesting(vesting) {
11358
+ return this.addModule({
11359
+ type: "vesting",
11360
+ version: "1.0.0",
11361
+ config: molecule.vesting(vesting)
11362
+ });
11363
+ }
11364
+ /** Attach a streaming-molecule config as a module (continuous payment). */
11365
+ withStreaming(streaming) {
11366
+ return this.addModule({
11367
+ type: "streaming",
11368
+ version: "1.0.0",
11369
+ config: molecule.streaming(streaming)
11370
+ });
11371
+ }
11372
+ /**
11373
+ * Attach a rich `GovernanceMoleculeConfig` as a module. Distinct from
11374
+ * `withGovernance(GovernanceConfig)` — that one sets the canonical top-level
11375
+ * governance field (DAO token + quorum/timelock/threshold). The molecule
11376
+ * variant exposes the full proposal-lifecycle config (delegation, veto
11377
+ * council, voting eligibility, etc.).
11378
+ */
11379
+ withGovernanceModule(governance) {
11380
+ return this.addModule({
11381
+ type: "governance",
11382
+ version: "1.0.0",
11383
+ config: molecule.governance(governance)
11384
+ });
11385
+ }
11386
+ /**
11387
+ * Attach a CooldownAtom config as a module. Token/account/topic arms only —
11388
+ * the agent arm carries `cooldown` as a first-class canonical field.
11389
+ */
11390
+ withCooldown(cooldown) {
11391
+ return this.addModule({
11392
+ type: "cooldown",
11393
+ version: "1.0.0",
11394
+ config: atom.cooldown(cooldown)
11395
+ });
11396
+ }
11397
+ /**
11398
+ * Attach an ApprovalThresholdAtom config as a module. Token/account/topic
11399
+ * arms only — the agent arm carries `approvalThreshold` as a first-class
11400
+ * canonical field.
11401
+ */
11402
+ withApprovalThreshold(threshold) {
11403
+ return this.addModule({
11404
+ type: "approval-threshold",
11405
+ version: "1.0.0",
11406
+ config: atom.approvalThreshold(threshold)
11407
+ });
11408
+ }
10127
11409
  /** Validate + return the typed, schema-conformant rule. Throws on invalid. */
10128
11410
  build() {
10129
11411
  const result = this.schema().safeParse(this.state);
@@ -10635,6 +11917,42 @@ var AgentRulesBuilder = class extends BaseRuleBuilder {
10635
11917
  this.state.allocationLimits = allocationLimits;
10636
11918
  return this;
10637
11919
  }
11920
+ // ────────────────────────────────────────────────────────────────────────
11921
+ // PR F — Phase-6.6 AI atom shortcuts
11922
+ //
11923
+ // `MaxTradesPerWindow` and `RequireStructuredOutput` are optional atoms
11924
+ // (NOT registered as builtin organism modules) wired in the AI-inference
11925
+ // path of the smart-app's BaaS function. Attached here as canonical
11926
+ // `ModuleEntry`s so they ship inside the published rule and the cluster's
11927
+ // canonical evaluator can dispatch them.
11928
+ //
11929
+ // Atom sources:
11930
+ // libs/rules-engine/src/atoms/max-trades-per-window.atom.ts
11931
+ // libs/rules-engine/src/atoms/require-structured-output.atom.ts
11932
+ // ────────────────────────────────────────────────────────────────────────
11933
+ /**
11934
+ * Cap the agent at `maxTradesPerWindow` trades within a rolling `windowMs`
11935
+ * window. Count-based — orthogonal to `withTradeLimits` which is amount-based.
11936
+ */
11937
+ withMaxTradesPerWindow(config) {
11938
+ return this.addModule({
11939
+ type: "max-trades-per-window",
11940
+ version: "1.0.0",
11941
+ config: { ...config }
11942
+ });
11943
+ }
11944
+ /**
11945
+ * Pre-filter LLM responses against a JSON Schema (compiled by the cluster's
11946
+ * SchemaResolver via Ajv) before they are submitted to the agent's trade
11947
+ * endpoint. `outputName` is included in failure reasons for log triage.
11948
+ */
11949
+ withRequireStructuredOutput(config = {}) {
11950
+ return this.addModule({
11951
+ type: "require-structured-output",
11952
+ version: "1.0.0",
11953
+ config: { outputName: config.outputName ?? "LLM output" }
11954
+ });
11955
+ }
10638
11956
  };
10639
11957
  function forAgent() {
10640
11958
  return new AgentRulesBuilder();
@@ -10666,150 +11984,6 @@ function validate(rule) {
10666
11984
  };
10667
11985
  }
10668
11986
 
10669
- // src/rules/atoms/index.ts
10670
- var atom = {
10671
- timeRange: (cfg) => ({
10672
- inclusive: true,
10673
- timezone: "UTC",
10674
- ...cfg
10675
- }),
10676
- limits: (cfg) => ({
10677
- decimals: 0,
10678
- inclusive: true,
10679
- ...cfg
10680
- }),
10681
- permissionList: (cfg) => ({
10682
- mode: "whitelist",
10683
- controller: "owner",
10684
- allowSelfAdd: false,
10685
- allowWildcards: false,
10686
- requiredScope: "execute",
10687
- entries: [],
10688
- ...cfg
10689
- }),
10690
- rateLimiter: (cfg) => ({
10691
- strategy: "all",
10692
- includeCurrentOperation: true,
10693
- ...cfg
10694
- }),
10695
- cooldown: (cfg) => ({ ...cfg }),
10696
- approvalThreshold: (cfg) => ({
10697
- decimals: 0,
10698
- ...cfg
10699
- }),
10700
- approvedPairs: (cfg) => ({
10701
- strictMode: true,
10702
- ...cfg
10703
- }),
10704
- tradeLimit: (cfg) => ({
10705
- periodMs: 864e5,
10706
- decimals: 0,
10707
- ...cfg
10708
- }),
10709
- snapshot: (cfg) => ({
10710
- validationMode: "minimum",
10711
- ...cfg
10712
- }),
10713
- cronSchedule: (cfg) => ({
10714
- allowOutsideSchedule: false,
10715
- toleranceMs: 0,
10716
- ...cfg
10717
- }),
10718
- countApproval: (cfg) => ({
10719
- maxCount: 0,
10720
- allowDuplicates: false,
10721
- maxApprovalAgeSec: 0,
10722
- allowSelfApproval: false,
10723
- ...cfg
10724
- }),
10725
- externalEvidence: (cfg) => ({
10726
- requiredSignatures: 1,
10727
- maxEvidenceAgeSec: 3600,
10728
- verifyPayloadHash: true,
10729
- ...cfg
10730
- }),
10731
- fieldValues: (cfg) => ({
10732
- requireAll: true,
10733
- ...cfg,
10734
- constraints: cfg.constraints.map((c) => ({
10735
- caseInsensitive: false,
10736
- denyMode: false,
10737
- ...c
10738
- }))
10739
- }),
10740
- registryReference: (cfg) => ({
10741
- requireAll: true,
10742
- ...cfg,
10743
- references: cfg.references.map((r) => ({ required: true, ...r }))
10744
- }),
10745
- schemaValidation: (cfg) => ({
10746
- strict: false,
10747
- allErrors: true,
10748
- validateFormats: false,
10749
- errorPrefix: "Schema validation failed",
10750
- removeAdditional: false,
10751
- useDefaults: false,
10752
- coerceTypes: false,
10753
- ...cfg
10754
- }),
10755
- stopLoss: (cfg) => ({ ...cfg }),
10756
- workflowState: (cfg) => ({
10757
- allowSelfTransition: false,
10758
- ...cfg
10759
- })
10760
- };
10761
-
10762
- // src/rules/molecules/index.ts
10763
- var molecule = {
10764
- tokenGate: (cfg) => ({
10765
- overallOperator: "AND",
10766
- allowDelegation: false,
10767
- ...cfg,
10768
- fungibles: cfg.fungibles ? { operator: "AND", ...cfg.fungibles } : void 0,
10769
- nonFungibles: cfg.nonFungibles ? { operator: "OR", ...cfg.nonFungibles } : void 0
10770
- }),
10771
- airdrop: (cfg) => ({
10772
- decimals: 0,
10773
- claimMethod: "manual",
10774
- ...cfg
10775
- }),
10776
- vesting: (cfg) => ({
10777
- decimals: 0,
10778
- cliffDurationMs: 0,
10779
- initialUnlockPercent: 0,
10780
- revocable: false,
10781
- returnToTreasury: true,
10782
- ...cfg
10783
- }),
10784
- governance: (cfg) => ({
10785
- decimals: 0,
10786
- votingPowerMethod: "token_balance",
10787
- quorumPercent: 10,
10788
- approvalThresholdPercent: 50,
10789
- timeLockMs: 0,
10790
- allowDelegation: true,
10791
- allowVoteChange: false,
10792
- maxActiveProposalsPerAccount: 3,
10793
- proposalCooldownMs: 0,
10794
- ...cfg
10795
- }),
10796
- streaming: (cfg) => ({
10797
- decimals: 0,
10798
- type: "linear",
10799
- cancellable: true,
10800
- pausable: false,
10801
- cancelController: "sender",
10802
- cliffDurationMs: 0,
10803
- autoTopUp: false,
10804
- ...cfg
10805
- }),
10806
- swap: (cfg = {}) => ({
10807
- type: "atomic",
10808
- requireAtomicity: true,
10809
- ...cfg
10810
- })
10811
- };
10812
-
10813
11987
  // src/rules/modules/index.ts
10814
11988
  function withLaunchpadDefaults(c) {
10815
11989
  return {
@@ -10865,12 +12039,8 @@ var module_ = {
10865
12039
  type: "dex",
10866
12040
  version: "1.0.0",
10867
12041
  config: withDexDefaults(config)
10868
- }),
10869
- agent: (config) => ({
10870
- type: "agent",
10871
- version: "1.0.0",
10872
- config
10873
12042
  })
12043
+ // PR F — `agent` retired per Arc 6 Phase 6.5. Use `Rules.forAgent()` instead.
10874
12044
  };
10875
12045
 
10876
12046
  // src/rules/templates/index.ts
@@ -11117,6 +12287,145 @@ function tradingAgent(p) {
11117
12287
  threshold: p.approvalThreshold ?? "999999999"
11118
12288
  }).withMetadata(meta("tradingAgent", p.description)).build();
11119
12289
  }
12290
+ function utilityToken(p = {}) {
12291
+ return forToken().withSecurity("full").withController("owner").withOperations({
12292
+ mint: { enabled: true },
12293
+ burn: { enabled: true, allowHolderBurn: true },
12294
+ transfer: { enabled: true },
12295
+ update: { enabled: true, allowedFields: ["memo", "feeSchedule"] },
12296
+ pause: { enabled: true },
12297
+ freeze: { enabled: true }
12298
+ }).withKeys({
12299
+ admin: { enabled: true },
12300
+ supply: { enabled: true },
12301
+ freeze: { enabled: true },
12302
+ pause: { enabled: true }
12303
+ }).withMetadata(meta("utilityToken", p.description)).build();
12304
+ }
12305
+ function daoGovernedToken(p) {
12306
+ return forToken().withSecurity("partial").withController("dao").withOperations({
12307
+ mint: {
12308
+ enabled: true,
12309
+ controller: "dao",
12310
+ requiresApproval: true,
12311
+ limits: { maxPerTransaction: "1000000", cooldownSeconds: 86400 }
12312
+ },
12313
+ burn: { enabled: true, allowHolderBurn: true },
12314
+ transfer: { enabled: true },
12315
+ update: {
12316
+ enabled: true,
12317
+ controller: "dao",
12318
+ requiresApproval: true,
12319
+ allowedFields: ["memo", "feeSchedule"]
12320
+ },
12321
+ pause: { enabled: true, controller: "dao", requiresApproval: true },
12322
+ freeze: {
12323
+ enabled: true,
12324
+ controller: "dao",
12325
+ requiresApproval: true,
12326
+ requiresMultisig: true
12327
+ }
12328
+ }).withKeys({
12329
+ admin: { enabled: true, security: "full", controller: "dao", requiresApproval: true },
12330
+ supply: { enabled: true, security: "partial", controller: "dao", requiresApproval: true },
12331
+ freeze: { enabled: true, security: "partial", controller: "dao", requiresApproval: true },
12332
+ pause: { enabled: true, security: "full", controller: "dao", requiresApproval: true }
12333
+ }).withGovernance({
12334
+ daoTokenId: p.daoTokenId,
12335
+ quorumPercentage: 15,
12336
+ proposalThreshold: "1000",
12337
+ votingPeriodSeconds: 604800,
12338
+ timelockSeconds: 172800
12339
+ }).withMetadata(meta("daoGovernedToken", p.description)).build();
12340
+ }
12341
+ function soulboundNft(p = {}) {
12342
+ return forToken().withSecurity("partial").withController("dao").withOperations({
12343
+ mint: {
12344
+ enabled: true,
12345
+ controller: "dao",
12346
+ requiresApproval: true,
12347
+ limits: { maxPerTransaction: "1" }
12348
+ },
12349
+ burn: { enabled: false },
12350
+ transfer: { enabled: false },
12351
+ update: { enabled: true, allowedFields: [] },
12352
+ pause: { enabled: false },
12353
+ freeze: { enabled: false }
12354
+ }).withKeys({
12355
+ admin: { enabled: true, security: "full", controller: "dao" },
12356
+ supply: { enabled: true, security: "full", controller: "dao" }
12357
+ }).withSoulbound({ enforced: true, allowedActions: ["burn"] }).withMetadata(meta("soulboundNft", p.description)).build();
12358
+ }
12359
+ function subscriptionNft(p = {}) {
12360
+ return forToken().withSecurity("full").withController("owner").withOperations({
12361
+ mint: { enabled: true, limits: { maxPerTransaction: "1" } },
12362
+ burn: { enabled: true },
12363
+ transfer: { enabled: true },
12364
+ update: { enabled: true, allowedFields: ["memo"] },
12365
+ pause: { enabled: true, controller: "dao", requiresApproval: true },
12366
+ freeze: { enabled: true, controller: "dao", requiresMultisig: true }
12367
+ }).withKeys({
12368
+ admin: { enabled: true },
12369
+ supply: { enabled: true },
12370
+ freeze: { enabled: true, security: "partial", controller: "dao" },
12371
+ pause: { enabled: true, security: "partial", controller: "dao" }
12372
+ }).withMetadata(meta("subscriptionNft", p.description)).build();
12373
+ }
12374
+ function membershipNft(p = {}) {
12375
+ return forToken().withSecurity("full").withController("dao").withOperations({
12376
+ mint: {
12377
+ enabled: true,
12378
+ controller: "dao",
12379
+ requiresApproval: true,
12380
+ limits: { maxPerTransaction: "1" }
12381
+ },
12382
+ burn: { enabled: true, controller: "dao", requiresApproval: true },
12383
+ transfer: { enabled: false },
12384
+ update: { enabled: true, allowedFields: [] },
12385
+ pause: { enabled: false },
12386
+ freeze: { enabled: false }
12387
+ }).withKeys({
12388
+ admin: { enabled: true, security: "full", controller: "dao", requiresApproval: true },
12389
+ supply: { enabled: true, security: "full", controller: "dao", requiresApproval: true }
12390
+ }).withSoulbound({ enforced: true, allowedActions: ["burn"] }).withMetadata(meta("membershipNft", p.description)).build();
12391
+ }
12392
+ function managedAccount(p = {}) {
12393
+ return forAccount().withSecurity("partial").withController("dao").withOperations({
12394
+ transfer: { enabled: true, requiresKyc: true },
12395
+ update: { enabled: true, controller: "dao", allowedFields: ["memo"] },
12396
+ delete: { enabled: true, controller: "dao", requiresApproval: true },
12397
+ approveAllowance: { enabled: true, controller: "dao", requiresApproval: true },
12398
+ deleteAllowance: { enabled: true }
12399
+ }).withKeys({
12400
+ admin: { enabled: true, security: "partial", controller: "dao" },
12401
+ signing: { enabled: true, security: "full", controller: "owner" }
12402
+ }).withMetadata(meta("managedAccount", p.description)).build();
12403
+ }
12404
+ function systemTopic(p = {}) {
12405
+ return forTopic().withSecurity("full").withController("dao").withOperations({
12406
+ submit: {
12407
+ enabled: true,
12408
+ controller: "dao",
12409
+ requiresApproval: true,
12410
+ rateLimit: { maxMessages: 10, periodSeconds: 3600 }
12411
+ },
12412
+ update: { enabled: true, allowedFields: [] },
12413
+ delete: { enabled: false }
12414
+ }).withKeys({
12415
+ admin: { enabled: true, security: "full", controller: "dao", requiresApproval: true },
12416
+ submit: { enabled: true, security: "full", controller: "dao" }
12417
+ }).withMetadata(meta("systemTopic", p.description)).build();
12418
+ }
12419
+ function appTopic(p = {}) {
12420
+ return forTopic().withSecurity("partial").withController("owner").withOperations({
12421
+ submit: { enabled: true, rateLimit: { maxMessages: 100, periodSeconds: 3600 } },
12422
+ update: { enabled: true, allowedFields: ["memo"] },
12423
+ delete: { enabled: true }
12424
+ }).withKeys({
12425
+ admin: { enabled: true },
12426
+ submit: { enabled: true }
12427
+ }).withMetadata(meta("appTopic", p.description)).build();
12428
+ }
11120
12429
  var template = {
11121
12430
  fairLaunch,
11122
12431
  tieredIDO,
@@ -11125,7 +12434,16 @@ var template = {
11125
12434
  multisigDAO,
11126
12435
  simpleAMM,
11127
12436
  vestingSchedule,
11128
- tradingAgent
12437
+ tradingAgent,
12438
+ // PR F — canonical server-mirror templates
12439
+ utilityToken,
12440
+ daoGovernedToken,
12441
+ soulboundNft,
12442
+ subscriptionNft,
12443
+ membershipNft,
12444
+ managedAccount,
12445
+ systemTopic,
12446
+ appTopic
11129
12447
  };
11130
12448
 
11131
12449
  // src/rules/index.ts
@@ -11190,6 +12508,7 @@ exports.BaasClient = BaasClient;
11190
12508
  exports.BaasError = BaasError;
11191
12509
  exports.BaseOperationConfigSchema = BaseOperationConfigSchema;
11192
12510
  exports.BaseRuleBuilder = BaseRuleBuilder;
12511
+ exports.BridgeClient = BridgeClient;
11193
12512
  exports.BurnOperationConfigSchema = BurnOperationConfigSchema;
11194
12513
  exports.CapabilityNotEnabledError = CapabilityNotEnabledError;
11195
12514
  exports.CapabilityValidationError = CapabilityValidationError;
@@ -11199,11 +12518,15 @@ exports.ClusterDiscoveryClient = ClusterDiscoveryClient;
11199
12518
  exports.CustomerSessionClient = CustomerSessionClient;
11200
12519
  exports.DEFAULT_CIRCUIT_BREAKER_CONFIG = DEFAULT_CIRCUIT_BREAKER_CONFIG;
11201
12520
  exports.DEFAULT_RETRY_CONFIG = DEFAULT_RETRY_CONFIG;
12521
+ exports.DaoClient = DaoClient;
12522
+ exports.DaoDashboardClient = DaoDashboardClient;
11202
12523
  exports.DatabaseClient = DatabaseClient;
11203
12524
  exports.DeploymentClient = DeploymentClient;
12525
+ exports.DiscoveryClient = DiscoveryClient;
11204
12526
  exports.DnsClient = DnsClient;
11205
12527
  exports.DomainsClient = DomainsClient;
11206
12528
  exports.EntitiesClient = EntitiesClient;
12529
+ exports.EnvelopeClient = EnvelopeClient;
11207
12530
  exports.ErrorCode = ErrorCode;
11208
12531
  exports.FeeConditionsSchema = FeeConditionsSchema;
11209
12532
  exports.FixedFeeConditionSchema = FixedFeeConditionSchema;
@@ -11213,7 +12536,9 @@ exports.FunctionsClient = FunctionsClient;
11213
12536
  exports.FungibleTokenGateSchema = FungibleTokenGateSchema;
11214
12537
  exports.GovernanceClient = GovernanceClient;
11215
12538
  exports.GovernanceConfigSchema = GovernanceConfigSchema;
12539
+ exports.HealthClient = HealthClient;
11216
12540
  exports.HederaTransactionsClient = HederaTransactionsClient;
12541
+ exports.HederaTssClient = HederaTssClient;
11217
12542
  exports.HistoricalBalanceClient = HistoricalBalanceClient;
11218
12543
  exports.HistoricalBalanceClientError = HistoricalBalanceClientError;
11219
12544
  exports.IPFSClient = IPFSClient;
@@ -11228,13 +12553,16 @@ exports.ModuleEntrySchema = ModuleEntrySchema;
11228
12553
  exports.NonFungibleTokenGateSchema = NonFungibleTokenGateSchema;
11229
12554
  exports.OperationControllerSchema = OperationControllerSchema;
11230
12555
  exports.OperationLimitsSchema = OperationLimitsSchema;
12556
+ exports.OperatorClient = OperatorClient;
11231
12557
  exports.PERSONHOOD_VERIFIER_NOT_CONFIGURED = PERSONHOOD_VERIFIER_NOT_CONFIGURED;
11232
12558
  exports.PauseOperationConfigSchema = PauseOperationConfigSchema;
11233
12559
  exports.PayloadSchemaRefSchema = PayloadSchemaRefSchema;
11234
12560
  exports.PersonhoodClient = PersonhoodClient;
12561
+ exports.PlatformImagesClient = PlatformImagesClient;
11235
12562
  exports.PolkadotTransactionsClient = PolkadotTransactionsClient;
11236
12563
  exports.PqcCertV1Schema = PqcCertV1Schema;
11237
12564
  exports.RateLimiter = RateLimiter;
12565
+ exports.ResourcesClient = ResourcesClient;
11238
12566
  exports.RoutingClient = RoutingClient;
11239
12567
  exports.RoyaltyFeeConditionSchema = RoyaltyFeeConditionSchema;
11240
12568
  exports.RuleBuildError = RuleBuildError;
@@ -11261,6 +12589,7 @@ exports.TokenKeyConditionsSchema = TokenKeyConditionsSchema;
11261
12589
  exports.TokenOperationsConfigSchema = TokenOperationsConfigSchema;
11262
12590
  exports.TokenRulesBuilder = TokenRulesBuilder;
11263
12591
  exports.TokenValidatorRulesSchema = TokenValidatorRulesSchema;
12592
+ exports.TokensClient = TokensClient;
11264
12593
  exports.TopicKeyConditionsSchema = TopicKeyConditionsSchema;
11265
12594
  exports.TopicOperationsConfigSchema = TopicOperationsConfigSchema;
11266
12595
  exports.TopicRulesBuilder = TopicRulesBuilder;
@@ -11275,15 +12604,20 @@ exports.ValidatorDiscoveryClient = ValidatorDiscoveryClient;
11275
12604
  exports.ValidatorMetadataSchema = ValidatorMetadataSchema;
11276
12605
  exports.ValidatorRulesSchema = ValidatorRulesSchema;
11277
12606
  exports.XrplTransactionsClient = XrplTransactionsClient;
12607
+ exports.appTopic = appTopic;
11278
12608
  exports.atom = atom;
11279
12609
  exports.auth = auth_exports;
11280
12610
  exports.baas = baas_exports;
12611
+ exports.bridge = bridge_exports;
11281
12612
  exports.chains = chains_exports;
11282
12613
  exports.createHttpClient = createHttpClient;
11283
12614
  exports.createResilientFetchWithBreaker = createResilientFetchWithBreaker;
11284
12615
  exports.createXrplWeb3Signer = createXrplWeb3Signer;
12616
+ exports.dao = dao_exports;
12617
+ exports.daoGovernedToken = daoGovernedToken;
11285
12618
  exports.discovery = discovery_exports;
11286
12619
  exports.encodePathParam = encodePathParam;
12620
+ exports.envelope = envelope_exports;
11287
12621
  exports.fairLaunch = fairLaunch;
11288
12622
  exports.fetchRegistrySnapshot = fetchRegistrySnapshot;
11289
12623
  exports.forAccount = forAccount;
@@ -11294,22 +12628,31 @@ exports.governance = governance_exports;
11294
12628
  exports.isKnownNetwork = isKnownNetwork;
11295
12629
  exports.isPersonhoodVerifierNotConfigured = isPersonhoodVerifierNotConfigured;
11296
12630
  exports.isRuleRejected = isRuleRejected;
12631
+ exports.managedAccount = managedAccount;
12632
+ exports.membershipNft = membershipNft;
11297
12633
  exports.module_ = module_;
11298
12634
  exports.molecule = molecule;
11299
12635
  exports.multisigDAO = multisigDAO;
12636
+ exports.operator = operator_exports;
11300
12637
  exports.parsePqcCert = parsePqcCert;
11301
12638
  exports.personhood = personhood_exports;
11302
12639
  exports.pqcVerify = pqc_verify_exports;
11303
12640
  exports.resilientFetch = resilientFetch;
11304
12641
  exports.resolveNetwork = resolveNetwork;
12642
+ exports.resources = resources_exports;
11305
12643
  exports.settlement = settlement_exports;
11306
12644
  exports.simpleAMM = simpleAMM;
11307
12645
  exports.simpleStaking = simpleStaking;
12646
+ exports.soulboundNft = soulboundNft;
11308
12647
  exports.subscription = subscription_exports;
12648
+ exports.subscriptionNft = subscriptionNft;
12649
+ exports.systemTopic = systemTopic;
11309
12650
  exports.template = template;
11310
12651
  exports.tieredIDO = tieredIDO;
11311
12652
  exports.tokenDAO = tokenDAO;
12653
+ exports.tokens = tokens_exports;
11312
12654
  exports.tradingAgent = tradingAgent;
12655
+ exports.utilityToken = utilityToken;
11313
12656
  exports.validate = validate;
11314
12657
  exports.validateAgentRules = validateAgentRules;
11315
12658
  exports.verifyPqcAttestation = verifyPqcAttestation;