@hsuite/smart-engines-sdk 3.2.1 → 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/CHANGELOG.md +191 -0
- package/README.md +51 -0
- package/dist/index.d.ts +22112 -184
- package/dist/index.js +2850 -213
- package/dist/index.js.map +1 -1
- package/dist/nestjs/index.d.ts +9749 -104
- package/dist/nestjs/index.js +1405 -5332
- package/dist/nestjs/index.js.map +1 -1
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -5479,29 +5479,6 @@ zod.z.object({
|
|
|
5479
5479
|
blockTime: zod.z.number().optional(),
|
|
5480
5480
|
rpcEndpoint: zod.z.string().url().optional()
|
|
5481
5481
|
});
|
|
5482
|
-
var NetworkMembershipTypeSchema = zod.z.enum(["validator", "host", "gateway"]);
|
|
5483
|
-
var MembershipStatusSchema = zod.z.enum(["pending", "active", "exiting", "exited", "banned"]);
|
|
5484
|
-
zod.z.object({
|
|
5485
|
-
nodeId: zod.z.string().min(1),
|
|
5486
|
-
networkType: NetworkMembershipTypeSchema,
|
|
5487
|
-
chain: zod.z.enum(["hedera", "xrpl", "polkadot", "solana"]),
|
|
5488
|
-
endpoint: zod.z.string().url(),
|
|
5489
|
-
publicKey: zod.z.string().min(1),
|
|
5490
|
-
joinedAt: zod.z.string().datetime(),
|
|
5491
|
-
depositTxId: zod.z.string().min(1),
|
|
5492
|
-
status: MembershipStatusSchema,
|
|
5493
|
-
networkConfig: zod.z.record(zod.z.unknown()).optional()
|
|
5494
|
-
});
|
|
5495
|
-
var NetworkDepositRequirementsSchema = zod.z.object({
|
|
5496
|
-
depositAmount: zod.z.string().min(1),
|
|
5497
|
-
lockDurationDays: zod.z.number().int().positive(),
|
|
5498
|
-
renewalWindowDays: zod.z.number().int().positive().optional()
|
|
5499
|
-
});
|
|
5500
|
-
zod.z.object({
|
|
5501
|
-
validator: NetworkDepositRequirementsSchema,
|
|
5502
|
-
host: NetworkDepositRequirementsSchema,
|
|
5503
|
-
gateway: NetworkDepositRequirementsSchema
|
|
5504
|
-
});
|
|
5505
5482
|
var TokenCapabilitiesSchema = zod.z.object({
|
|
5506
5483
|
/**
|
|
5507
5484
|
* Pause all token operations globally
|
|
@@ -5666,74 +5643,6 @@ var PreparedTransactionSovereigntySchema = zod.z.discriminatedUnion("mode", [
|
|
|
5666
5643
|
authorizationSet: PreparedTransactionAuthorizationSetSchema.optional()
|
|
5667
5644
|
})
|
|
5668
5645
|
]);
|
|
5669
|
-
var TransactionStatusSchema = zod.z.enum(["pending", "success", "failed", "expired"]);
|
|
5670
|
-
var TransactionTypeSchema = zod.z.enum([
|
|
5671
|
-
"transfer",
|
|
5672
|
-
"token_transfer",
|
|
5673
|
-
"account_create",
|
|
5674
|
-
"token_create",
|
|
5675
|
-
"token_mint",
|
|
5676
|
-
"token_burn",
|
|
5677
|
-
"contract_call",
|
|
5678
|
-
"contract_create",
|
|
5679
|
-
"topic_message",
|
|
5680
|
-
"other"
|
|
5681
|
-
]);
|
|
5682
|
-
zod.z.object({
|
|
5683
|
-
id: zod.z.string(),
|
|
5684
|
-
chain: ChainTypeSchema,
|
|
5685
|
-
type: TransactionTypeSchema,
|
|
5686
|
-
status: TransactionStatusSchema,
|
|
5687
|
-
timestamp: zod.z.date(),
|
|
5688
|
-
from: AccountIdSchema,
|
|
5689
|
-
to: AccountIdSchema.optional(),
|
|
5690
|
-
amount: zod.z.string().optional(),
|
|
5691
|
-
fee: zod.z.string(),
|
|
5692
|
-
memo: zod.z.string().optional(),
|
|
5693
|
-
metadata: zod.z.record(zod.z.any()).optional()
|
|
5694
|
-
});
|
|
5695
|
-
zod.z.object({
|
|
5696
|
-
transactionId: zod.z.string(),
|
|
5697
|
-
chain: ChainTypeSchema,
|
|
5698
|
-
status: TransactionStatusSchema,
|
|
5699
|
-
blockNumber: zod.z.number().optional(),
|
|
5700
|
-
blockHash: zod.z.string().optional(),
|
|
5701
|
-
timestamp: zod.z.date(),
|
|
5702
|
-
gasUsed: zod.z.string().optional(),
|
|
5703
|
-
effectiveFee: zod.z.string(),
|
|
5704
|
-
logs: zod.z.array(zod.z.any()).optional(),
|
|
5705
|
-
metadata: zod.z.record(zod.z.any()).optional()
|
|
5706
|
-
});
|
|
5707
|
-
var TokenTypeSchema = zod.z.enum(["fungible", "nft", "semi_fungible"]);
|
|
5708
|
-
var TokenSchema = zod.z.object({
|
|
5709
|
-
tokenId: zod.z.string(),
|
|
5710
|
-
chain: ChainTypeSchema,
|
|
5711
|
-
name: zod.z.string(),
|
|
5712
|
-
symbol: zod.z.string(),
|
|
5713
|
-
decimals: zod.z.number().int().min(0),
|
|
5714
|
-
totalSupply: zod.z.string(),
|
|
5715
|
-
type: TokenTypeSchema,
|
|
5716
|
-
creator: AccountIdSchema.optional(),
|
|
5717
|
-
metadata: zod.z.record(zod.z.any()).optional(),
|
|
5718
|
-
createdAt: zod.z.date().optional()
|
|
5719
|
-
});
|
|
5720
|
-
zod.z.object({
|
|
5721
|
-
name: zod.z.string(),
|
|
5722
|
-
description: zod.z.string().optional(),
|
|
5723
|
-
image: zod.z.string().url().optional(),
|
|
5724
|
-
attributes: zod.z.array(
|
|
5725
|
-
zod.z.object({
|
|
5726
|
-
trait_type: zod.z.string(),
|
|
5727
|
-
value: zod.z.union([zod.z.string(), zod.z.number(), zod.z.boolean()])
|
|
5728
|
-
})
|
|
5729
|
-
).optional(),
|
|
5730
|
-
external_url: zod.z.string().url().optional()
|
|
5731
|
-
});
|
|
5732
|
-
TokenSchema.extend({
|
|
5733
|
-
holders: zod.z.number().optional(),
|
|
5734
|
-
transferCount: zod.z.number().optional(),
|
|
5735
|
-
circulatingSupply: zod.z.string().optional()
|
|
5736
|
-
});
|
|
5737
5646
|
var CreateAccountRequestSchema = zod.z.object({
|
|
5738
5647
|
chain: ChainTypeSchema,
|
|
5739
5648
|
initialBalance: zod.z.string(),
|
|
@@ -6094,9 +6003,11 @@ zod.z.object({
|
|
|
6094
6003
|
var discovery_exports = {};
|
|
6095
6004
|
__export(discovery_exports, {
|
|
6096
6005
|
ClusterDiscoveryClient: () => ClusterDiscoveryClient,
|
|
6006
|
+
DiscoveryClient: () => DiscoveryClient,
|
|
6097
6007
|
MIRROR_NODE_URLS: () => MIRROR_NODE_URLS,
|
|
6098
6008
|
MirrorNodeClient: () => MirrorNodeClient,
|
|
6099
6009
|
MirrorNodeError: () => MirrorNodeError,
|
|
6010
|
+
PlatformImagesClient: () => PlatformImagesClient,
|
|
6100
6011
|
ValidatorDiscoveryClient: () => ValidatorDiscoveryClient
|
|
6101
6012
|
});
|
|
6102
6013
|
|
|
@@ -6645,6 +6556,99 @@ var ClusterDiscoveryClient = class {
|
|
|
6645
6556
|
}
|
|
6646
6557
|
};
|
|
6647
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
|
+
|
|
6648
6652
|
// src/auth/index.ts
|
|
6649
6653
|
var auth_exports = {};
|
|
6650
6654
|
__export(auth_exports, {
|
|
@@ -6949,7 +6953,7 @@ function createHttpClient(config) {
|
|
|
6949
6953
|
const timeout = config.timeout ?? 3e4;
|
|
6950
6954
|
function getHeaders(contentType) {
|
|
6951
6955
|
const headers = {};
|
|
6952
|
-
{
|
|
6956
|
+
if (contentType) {
|
|
6953
6957
|
headers["Content-Type"] = contentType;
|
|
6954
6958
|
}
|
|
6955
6959
|
if (config.authToken) {
|
|
@@ -6999,6 +7003,36 @@ function createHttpClient(config) {
|
|
|
6999
7003
|
throw new SdkHttpError(`Network error: ${err.message}`, 0, error);
|
|
7000
7004
|
}
|
|
7001
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
|
+
}
|
|
7002
7036
|
async function upload(path, file, filename, metadata, fieldName = "file") {
|
|
7003
7037
|
const url = `${config.baseUrl}${path}`;
|
|
7004
7038
|
const controller = new AbortController();
|
|
@@ -7049,7 +7083,9 @@ function createHttpClient(config) {
|
|
|
7049
7083
|
post: (path, body) => request("POST", path, body),
|
|
7050
7084
|
get: (path) => request("GET", path),
|
|
7051
7085
|
put: (path, body) => request("PUT", path, body),
|
|
7086
|
+
patch: (path, body) => request("PATCH", path, body),
|
|
7052
7087
|
delete: (path) => request("DELETE", path),
|
|
7088
|
+
getText,
|
|
7053
7089
|
upload: ((path, file, filename, metadata, fieldName) => upload(path, file, filename, metadata, fieldName)),
|
|
7054
7090
|
setAuthToken
|
|
7055
7091
|
};
|
|
@@ -7070,6 +7106,35 @@ function isRuleRejected(err) {
|
|
|
7070
7106
|
return obj.ruleAtoms.every((a) => typeof a === "string");
|
|
7071
7107
|
}
|
|
7072
7108
|
|
|
7109
|
+
// src/network-presets.ts
|
|
7110
|
+
var KNOWN_NETWORKS = {
|
|
7111
|
+
testnet: {
|
|
7112
|
+
bootstrap: ["https://gateway.testnet.hsuite.network"]
|
|
7113
|
+
},
|
|
7114
|
+
mainnet: {
|
|
7115
|
+
// Mainnet entrypoint reserved. The SDK still resolves the name so
|
|
7116
|
+
// upgrade-by-flipping-NETWORK works; the bootstrap URL is the
|
|
7117
|
+
// pre-allocated DNS we own. If mainnet isn't deployed yet, the discovery
|
|
7118
|
+
// fetch will fail at runtime with the same "no seed reachable" error
|
|
7119
|
+
// any unreachable URL produces — the caller learns the network is not
|
|
7120
|
+
// live, rather than getting a baffling "unknown network" TypeScript
|
|
7121
|
+
// error at compile time.
|
|
7122
|
+
bootstrap: ["https://gateway.hsuite.network"]
|
|
7123
|
+
}
|
|
7124
|
+
};
|
|
7125
|
+
function resolveNetwork(name) {
|
|
7126
|
+
const preset = KNOWN_NETWORKS[name];
|
|
7127
|
+
if (!preset) {
|
|
7128
|
+
throw new Error(
|
|
7129
|
+
`Unknown network: "${name}". Known networks: ${Object.keys(KNOWN_NETWORKS).join(", ")}`
|
|
7130
|
+
);
|
|
7131
|
+
}
|
|
7132
|
+
return preset;
|
|
7133
|
+
}
|
|
7134
|
+
function isKnownNetwork(name) {
|
|
7135
|
+
return Object.prototype.hasOwnProperty.call(KNOWN_NETWORKS, name);
|
|
7136
|
+
}
|
|
7137
|
+
|
|
7073
7138
|
// src/subscription/index.ts
|
|
7074
7139
|
var subscription_exports = {};
|
|
7075
7140
|
__export(subscription_exports, {
|
|
@@ -7174,6 +7239,80 @@ var SubscriptionClient = class {
|
|
|
7174
7239
|
async getBalance(appId) {
|
|
7175
7240
|
return this.http.get(`/subscription/balance/${encodeURIComponent(appId)}`);
|
|
7176
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
|
+
}
|
|
7177
7316
|
};
|
|
7178
7317
|
|
|
7179
7318
|
// src/tss/index.ts
|
|
@@ -7202,14 +7341,19 @@ var TSSClient = class {
|
|
|
7202
7341
|
return this.http.get(`/tss/entity/${encodeURIComponent(entityId)}`);
|
|
7203
7342
|
}
|
|
7204
7343
|
/**
|
|
7205
|
-
* Sign a transaction using MPC
|
|
7206
|
-
* Routes to the correct chain backend based on the `chain` parameter.
|
|
7344
|
+
* Sign a transaction using MPC.
|
|
7207
7345
|
*
|
|
7208
|
-
*
|
|
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.
|
|
7209
7353
|
*/
|
|
7210
7354
|
async signMPC(request) {
|
|
7211
|
-
const chain =
|
|
7212
|
-
return this.http.post(`/tss/${
|
|
7355
|
+
const chain = "hedera";
|
|
7356
|
+
return this.http.post(`/tss/${chain}/sign-mpc`, { ...request, chain });
|
|
7213
7357
|
}
|
|
7214
7358
|
/**
|
|
7215
7359
|
* Get known validators and their public keys
|
|
@@ -7253,6 +7397,42 @@ var TSSClient = class {
|
|
|
7253
7397
|
async getMultiSigStatus(txId) {
|
|
7254
7398
|
return this.http.get(`/tss/multisig/transactions/${encodeURIComponent(txId)}`);
|
|
7255
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
|
+
}
|
|
7256
7436
|
};
|
|
7257
7437
|
|
|
7258
7438
|
// src/ipfs/index.ts
|
|
@@ -7322,12 +7502,59 @@ var IPFSClient = class {
|
|
|
7322
7502
|
}
|
|
7323
7503
|
};
|
|
7324
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
|
+
|
|
7325
7537
|
// src/transactions/chains/hedera.ts
|
|
7326
7538
|
var HederaTransactionsClient = class {
|
|
7327
|
-
constructor(http) {
|
|
7539
|
+
constructor(http, tssHttp) {
|
|
7328
7540
|
this.http = http;
|
|
7541
|
+
this.tss = new HederaTssClient(tssHttp ?? http);
|
|
7329
7542
|
}
|
|
7330
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;
|
|
7331
7558
|
/** Prepare an HCS topic creation transaction. */
|
|
7332
7559
|
async prepareTopicCreate(request) {
|
|
7333
7560
|
return this.http.post("/topic/create/prepare", { ...request, chain: "hedera" });
|
|
@@ -7360,6 +7587,16 @@ var XrplTransactionsClient = class {
|
|
|
7360
7587
|
async prepareTrustLine(request) {
|
|
7361
7588
|
return this.http.post("/trustline/prepare", { ...request, chain: "xrpl" });
|
|
7362
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
|
+
}
|
|
7363
7600
|
};
|
|
7364
7601
|
|
|
7365
7602
|
// src/transactions/chains/solana.ts
|
|
@@ -7416,6 +7653,28 @@ var TransactionsClient = class {
|
|
|
7416
7653
|
async prepareNftTransfer(request) {
|
|
7417
7654
|
return this.http.post("/nft/transfer/prepare", request);
|
|
7418
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
|
+
}
|
|
7419
7678
|
/** Prepare a token creation transaction (Hedera, Solana, Polkadot, Cardano). */
|
|
7420
7679
|
async prepareTokenCreate(request) {
|
|
7421
7680
|
return this.http.post("/token/create/prepare", request);
|
|
@@ -7736,72 +7995,319 @@ var GovernanceClient = class {
|
|
|
7736
7995
|
}
|
|
7737
7996
|
};
|
|
7738
7997
|
|
|
7739
|
-
// src/
|
|
7740
|
-
var
|
|
7741
|
-
__export(
|
|
7742
|
-
|
|
7743
|
-
|
|
7744
|
-
isPersonhoodVerifierNotConfigured: () => isPersonhoodVerifierNotConfigured
|
|
7998
|
+
// src/dao/index.ts
|
|
7999
|
+
var dao_exports = {};
|
|
8000
|
+
__export(dao_exports, {
|
|
8001
|
+
DaoClient: () => DaoClient,
|
|
8002
|
+
DaoDashboardClient: () => DaoDashboardClient
|
|
7745
8003
|
});
|
|
7746
8004
|
|
|
7747
|
-
// src/
|
|
7748
|
-
|
|
7749
|
-
|
|
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 {
|
|
7750
8016
|
constructor(http) {
|
|
7751
8017
|
this.http = http;
|
|
7752
8018
|
}
|
|
7753
8019
|
http;
|
|
7754
|
-
/**
|
|
7755
|
-
|
|
7756
|
-
|
|
7757
|
-
|
|
7758
|
-
|
|
7759
|
-
|
|
7760
|
-
|
|
7761
|
-
async
|
|
7762
|
-
|
|
7763
|
-
|
|
7764
|
-
|
|
7765
|
-
|
|
7766
|
-
|
|
7767
|
-
|
|
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)}`
|
|
7768
8056
|
);
|
|
7769
|
-
if (result === void 0) return null;
|
|
7770
|
-
return result;
|
|
7771
8057
|
}
|
|
7772
8058
|
};
|
|
7773
|
-
function isPersonhoodVerifierNotConfigured(err) {
|
|
7774
|
-
if (!(err instanceof SdkHttpError)) return false;
|
|
7775
|
-
if (err.statusCode !== 503) return false;
|
|
7776
|
-
const d = err.details;
|
|
7777
|
-
if (d === null || typeof d !== "object") return false;
|
|
7778
|
-
return d.error === PERSONHOOD_VERIFIER_NOT_CONFIGURED;
|
|
7779
|
-
}
|
|
7780
8059
|
|
|
7781
|
-
// src/
|
|
7782
|
-
|
|
7783
|
-
|
|
7784
|
-
|
|
7785
|
-
|
|
7786
|
-
|
|
7787
|
-
|
|
7788
|
-
|
|
7789
|
-
"
|
|
7790
|
-
|
|
7791
|
-
|
|
7792
|
-
|
|
7793
|
-
|
|
7794
|
-
|
|
7795
|
-
|
|
7796
|
-
|
|
7797
|
-
|
|
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);
|
|
7798
8083
|
}
|
|
7799
|
-
|
|
7800
|
-
|
|
7801
|
-
|
|
7802
|
-
|
|
7803
|
-
|
|
7804
|
-
|
|
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
|
+
|
|
8245
|
+
// src/personhood/index.ts
|
|
8246
|
+
var personhood_exports = {};
|
|
8247
|
+
__export(personhood_exports, {
|
|
8248
|
+
PERSONHOOD_VERIFIER_NOT_CONFIGURED: () => PERSONHOOD_VERIFIER_NOT_CONFIGURED,
|
|
8249
|
+
PersonhoodClient: () => PersonhoodClient,
|
|
8250
|
+
isPersonhoodVerifierNotConfigured: () => isPersonhoodVerifierNotConfigured
|
|
8251
|
+
});
|
|
8252
|
+
|
|
8253
|
+
// src/personhood/personhood-client.ts
|
|
8254
|
+
var PERSONHOOD_VERIFIER_NOT_CONFIGURED = "personhood_verifier_not_configured";
|
|
8255
|
+
var PersonhoodClient = class {
|
|
8256
|
+
constructor(http) {
|
|
8257
|
+
this.http = http;
|
|
8258
|
+
}
|
|
8259
|
+
http;
|
|
8260
|
+
/**
|
|
8261
|
+
* Verify a personhood proof for `candidate`.
|
|
8262
|
+
*
|
|
8263
|
+
* Returns the issued cert on accept, `null` on clean rejection. All
|
|
8264
|
+
* other failure modes (validation, transport, 5xx) propagate as
|
|
8265
|
+
* `SdkHttpError`.
|
|
8266
|
+
*/
|
|
8267
|
+
async verify(params) {
|
|
8268
|
+
const result = await this.http.post(
|
|
8269
|
+
"/personhood/verify",
|
|
8270
|
+
{
|
|
8271
|
+
candidate: params.candidate,
|
|
8272
|
+
proof: params.proof
|
|
8273
|
+
}
|
|
8274
|
+
);
|
|
8275
|
+
if (result === void 0) return null;
|
|
8276
|
+
return result;
|
|
8277
|
+
}
|
|
8278
|
+
};
|
|
8279
|
+
function isPersonhoodVerifierNotConfigured(err) {
|
|
8280
|
+
if (!(err instanceof SdkHttpError)) return false;
|
|
8281
|
+
if (err.statusCode !== 503) return false;
|
|
8282
|
+
const d = err.details;
|
|
8283
|
+
if (d === null || typeof d !== "object") return false;
|
|
8284
|
+
return d.error === PERSONHOOD_VERIFIER_NOT_CONFIGURED;
|
|
8285
|
+
}
|
|
8286
|
+
|
|
8287
|
+
// src/baas/agents/types.ts
|
|
8288
|
+
var VALID_CHAIN_NAMES = /* @__PURE__ */ new Set([
|
|
8289
|
+
"hedera",
|
|
8290
|
+
"xrpl",
|
|
8291
|
+
"polkadot",
|
|
8292
|
+
"solana",
|
|
8293
|
+
"stellar",
|
|
8294
|
+
"ethereum",
|
|
8295
|
+
"polygon",
|
|
8296
|
+
"bitcoin"
|
|
8297
|
+
]);
|
|
8298
|
+
function validateAgentRules(rules) {
|
|
8299
|
+
const errors = [];
|
|
8300
|
+
if (rules.maxTradeAmount !== void 0) {
|
|
8301
|
+
if (!isPositiveDecimalString(rules.maxTradeAmount)) {
|
|
8302
|
+
errors.push("maxTradeAmount must be a positive decimal string");
|
|
8303
|
+
}
|
|
8304
|
+
}
|
|
8305
|
+
if (rules.allowedPairs !== void 0) {
|
|
8306
|
+
if (!Array.isArray(rules.allowedPairs)) {
|
|
8307
|
+
errors.push("allowedPairs must be an array of strings");
|
|
8308
|
+
} else {
|
|
8309
|
+
for (const pair of rules.allowedPairs) {
|
|
8310
|
+
if (typeof pair !== "string" || pair.trim().length === 0) {
|
|
7805
8311
|
errors.push("allowedPairs contains an empty or non-string entry");
|
|
7806
8312
|
break;
|
|
7807
8313
|
}
|
|
@@ -7855,15 +8361,25 @@ var AgentsClient = class {
|
|
|
7855
8361
|
async list() {
|
|
7856
8362
|
return this.http.get("/api/agents");
|
|
7857
8363
|
}
|
|
7858
|
-
/**
|
|
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
|
+
*/
|
|
7859
8369
|
async fund(agentId, request) {
|
|
7860
8370
|
return this.http.post(`/api/agents/${encodeURIComponent(agentId)}/fund`, request);
|
|
7861
8371
|
}
|
|
7862
|
-
/**
|
|
8372
|
+
/**
|
|
8373
|
+
* Execute a trade (agent-wallet OR owner). Returns a
|
|
8374
|
+
* `PreparedTransactionResponse` wrapped in a `success: true` envelope.
|
|
8375
|
+
*/
|
|
7863
8376
|
async trade(agentId, request) {
|
|
7864
8377
|
return this.http.post(`/api/agents/${encodeURIComponent(agentId)}/trade`, request);
|
|
7865
8378
|
}
|
|
7866
|
-
/**
|
|
8379
|
+
/**
|
|
8380
|
+
* Withdraw from agent treasury (owner-only). Returns a
|
|
8381
|
+
* `PreparedTransactionResponse` wrapped in a `success: true` envelope.
|
|
8382
|
+
*/
|
|
7867
8383
|
async withdraw(agentId, request) {
|
|
7868
8384
|
return this.http.post(`/api/agents/${encodeURIComponent(agentId)}/withdraw`, request);
|
|
7869
8385
|
}
|
|
@@ -7879,9 +8395,16 @@ var AgentsClient = class {
|
|
|
7879
8395
|
async revoke(agentId) {
|
|
7880
8396
|
return this.http.post(`/api/agents/${encodeURIComponent(agentId)}/revoke`, {});
|
|
7881
8397
|
}
|
|
7882
|
-
/**
|
|
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
|
+
*/
|
|
7883
8406
|
async updateRules(agentId, rules) {
|
|
7884
|
-
return this.http.
|
|
8407
|
+
return this.http.patch(`/api/agents/${encodeURIComponent(agentId)}/rules`, rules);
|
|
7885
8408
|
}
|
|
7886
8409
|
/** Get agent events */
|
|
7887
8410
|
async getEvents(agentId) {
|
|
@@ -8007,6 +8530,306 @@ var DeploymentClient = class {
|
|
|
8007
8530
|
async getStats() {
|
|
8008
8531
|
return this.http.get("/api/deployment/stats");
|
|
8009
8532
|
}
|
|
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
|
+
}
|
|
8010
8833
|
};
|
|
8011
8834
|
|
|
8012
8835
|
// src/client.ts
|
|
@@ -8043,12 +8866,26 @@ var SmartEngineClient = class _SmartEngineClient {
|
|
|
8043
8866
|
settlement;
|
|
8044
8867
|
/** Governance proposal dry-run (simulate-only) */
|
|
8045
8868
|
governance;
|
|
8869
|
+
/** DAO governance — DAOs, proposals, votes, treasury, members, dashboard */
|
|
8870
|
+
dao;
|
|
8046
8871
|
/** Personhood verification (HPP one-human-one-member) */
|
|
8047
8872
|
personhood;
|
|
8048
8873
|
/** BaaS smart-agent lifecycle (register/fund/trade/withdraw/pause/resume/revoke/...) */
|
|
8049
8874
|
agents;
|
|
8050
8875
|
/** BaaS smart-app deployment lifecycle (init/uploadFrontend/deploy/rollback/status/...) */
|
|
8051
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;
|
|
8052
8889
|
constructor(config) {
|
|
8053
8890
|
this.allowInsecure = config.allowInsecure ?? false;
|
|
8054
8891
|
this.baseUrl = validateClientUrl(config.baseUrl, this.allowInsecure);
|
|
@@ -8068,7 +8905,7 @@ var SmartEngineClient = class _SmartEngineClient {
|
|
|
8068
8905
|
this.tss = new TSSClient(this.http);
|
|
8069
8906
|
this.ipfs = new IPFSClient(this.http);
|
|
8070
8907
|
this.transactions = new TransactionsClient(this.txHttp);
|
|
8071
|
-
this.hedera = new HederaTransactionsClient(this.txHttp);
|
|
8908
|
+
this.hedera = new HederaTransactionsClient(this.txHttp, this.http);
|
|
8072
8909
|
this.xrpl = new XrplTransactionsClient(this.txHttp);
|
|
8073
8910
|
this.solana = new SolanaTransactionsClient(this.txHttp);
|
|
8074
8911
|
this.polkadot = new PolkadotTransactionsClient(this.txHttp);
|
|
@@ -8076,6 +8913,7 @@ var SmartEngineClient = class _SmartEngineClient {
|
|
|
8076
8913
|
this.historicalBalance = HistoricalBalanceClient.fromHttp(this.http);
|
|
8077
8914
|
this.settlement = new SettlementClient(this.http);
|
|
8078
8915
|
this.governance = new GovernanceClient(this.http);
|
|
8916
|
+
this.dao = new DaoClient(this.http);
|
|
8079
8917
|
this.personhood = new PersonhoodClient(this.http);
|
|
8080
8918
|
const rootHttp = createHttpClient({
|
|
8081
8919
|
baseUrl: this.baseUrl,
|
|
@@ -8085,6 +8923,12 @@ var SmartEngineClient = class _SmartEngineClient {
|
|
|
8085
8923
|
});
|
|
8086
8924
|
this.agents = new AgentsClient(rootHttp);
|
|
8087
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);
|
|
8088
8932
|
}
|
|
8089
8933
|
/**
|
|
8090
8934
|
* Build a `SmartEngineClient` from a plain env object. Reads:
|
|
@@ -8168,7 +9012,18 @@ var SmartEngineClient = class _SmartEngineClient {
|
|
|
8168
9012
|
* 2. (Optional) HCS trust-anchor membership cross-check.
|
|
8169
9013
|
* 3. Random-pick over the verified set.
|
|
8170
9014
|
*
|
|
8171
|
-
* @example
|
|
9015
|
+
* @example Zero-config (recommended for smart-app callers)
|
|
9016
|
+
* ```ts
|
|
9017
|
+
* const { client, cluster, session } = await SmartEngineClient.connectToCluster({
|
|
9018
|
+
* network: 'testnet', // resolves canonical gateway entrypoint
|
|
9019
|
+
* chain: 'xrpl',
|
|
9020
|
+
* address: '...',
|
|
9021
|
+
* publicKey: '...',
|
|
9022
|
+
* signFn: async (challenge) => sign(challenge),
|
|
9023
|
+
* });
|
|
9024
|
+
* ```
|
|
9025
|
+
*
|
|
9026
|
+
* @example Custom seeds (private deployments / local dev)
|
|
8172
9027
|
* ```ts
|
|
8173
9028
|
* const { client, cluster, session } = await SmartEngineClient.connectToCluster({
|
|
8174
9029
|
* bootstrap: ['https://sn1.testnet.hsuite.network', 'https://sn2.testnet.hsuite.network'],
|
|
@@ -8181,8 +9036,15 @@ var SmartEngineClient = class _SmartEngineClient {
|
|
|
8181
9036
|
*/
|
|
8182
9037
|
static async connectToCluster(config) {
|
|
8183
9038
|
const allowInsecure = config.allowInsecure ?? false;
|
|
9039
|
+
const bootstrap = config.bootstrap ? [...config.bootstrap] : [...resolveNetwork(config.network).bootstrap];
|
|
9040
|
+
if (bootstrap.length === 0) {
|
|
9041
|
+
throw new SmartEngineError2(
|
|
9042
|
+
"connectToCluster requires either a non-empty `bootstrap` list or a known `network` name.",
|
|
9043
|
+
400
|
|
9044
|
+
);
|
|
9045
|
+
}
|
|
8184
9046
|
const discovery = new ClusterDiscoveryClient({
|
|
8185
|
-
bootstrap
|
|
9047
|
+
bootstrap,
|
|
8186
9048
|
allowInsecure,
|
|
8187
9049
|
trustAnchor: config.trustAnchor ? {
|
|
8188
9050
|
network: config.trustAnchor.network,
|
|
@@ -8282,7 +9144,19 @@ var SmartEngineClient = class _SmartEngineClient {
|
|
|
8282
9144
|
const validated = MintTokenRequestSchema.parse(request);
|
|
8283
9145
|
return this.http.post("/tokens/mint", validated);
|
|
8284
9146
|
}
|
|
8285
|
-
/**
|
|
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
|
+
*/
|
|
8286
9160
|
async getTokenInfo(chain, tokenId) {
|
|
8287
9161
|
return this.http.get(`/tokens/${encodePathParam(chain)}/${encodePathParam(tokenId)}`);
|
|
8288
9162
|
}
|
|
@@ -8430,47 +9304,56 @@ var RoutingClient = class {
|
|
|
8430
9304
|
this.http = http;
|
|
8431
9305
|
}
|
|
8432
9306
|
http;
|
|
8433
|
-
/**
|
|
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
|
+
*/
|
|
8434
9313
|
async registerHost(request) {
|
|
8435
9314
|
return this.http.post("/routing/hosts", request);
|
|
8436
9315
|
}
|
|
8437
|
-
/** Unregister a host */
|
|
9316
|
+
/** Unregister a host. */
|
|
8438
9317
|
async unregisterHost(hostId) {
|
|
8439
9318
|
return this.http.delete(`/routing/hosts/${encodeURIComponent(hostId)}`);
|
|
8440
9319
|
}
|
|
8441
|
-
/** Get all registered hosts */
|
|
9320
|
+
/** Get all registered hosts. */
|
|
8442
9321
|
async getAllHosts() {
|
|
8443
9322
|
return this.http.get("/routing/hosts");
|
|
8444
9323
|
}
|
|
8445
|
-
/** Get only verified hosts */
|
|
9324
|
+
/** Get only verified hosts. */
|
|
8446
9325
|
async getVerifiedHosts() {
|
|
8447
9326
|
return this.http.get("/routing/hosts/verified");
|
|
8448
9327
|
}
|
|
8449
|
-
/** Get a specific host by ID */
|
|
9328
|
+
/** Get a specific host by ID. */
|
|
8450
9329
|
async getHost(hostId) {
|
|
8451
9330
|
return this.http.get(`/routing/hosts/${encodeURIComponent(hostId)}`);
|
|
8452
9331
|
}
|
|
8453
|
-
/**
|
|
9332
|
+
/** Trigger host re-verification. */
|
|
8454
9333
|
async verifyHost(hostId) {
|
|
8455
9334
|
return this.http.post(`/routing/hosts/${encodeURIComponent(hostId)}/verify`, {});
|
|
8456
9335
|
}
|
|
8457
|
-
/** Set routing configuration for an app */
|
|
9336
|
+
/** Set routing configuration for an app. */
|
|
8458
9337
|
async setRoutingConfig(appId, config) {
|
|
8459
9338
|
return this.http.put(`/routing/config/${encodeURIComponent(appId)}`, config);
|
|
8460
9339
|
}
|
|
8461
|
-
/** Get routing configuration for an app */
|
|
9340
|
+
/** Get routing configuration for an app. */
|
|
8462
9341
|
async getRoutingConfig(appId) {
|
|
8463
9342
|
return this.http.get(`/routing/config/${encodeURIComponent(appId)}`);
|
|
8464
9343
|
}
|
|
8465
|
-
/** Proxy a request through the gateway */
|
|
9344
|
+
/** Proxy a request through the gateway. */
|
|
8466
9345
|
async proxyRequest(request) {
|
|
8467
9346
|
return this.http.post("/routing/proxy", request);
|
|
8468
9347
|
}
|
|
8469
|
-
/** Get routing statistics */
|
|
9348
|
+
/** Get routing statistics. */
|
|
8470
9349
|
async getStats() {
|
|
8471
9350
|
return this.http.get("/routing/stats");
|
|
8472
9351
|
}
|
|
8473
|
-
/**
|
|
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
|
+
*/
|
|
8474
9357
|
async mapDomainToApp(domain, appId) {
|
|
8475
9358
|
return this.http.post(`/routing/domains/${encodeURIComponent(domain)}/map`, { appId });
|
|
8476
9359
|
}
|
|
@@ -8499,7 +9382,11 @@ var DomainsClient = class {
|
|
|
8499
9382
|
const params = owner ? `?owner=${encodeURIComponent(owner)}` : "";
|
|
8500
9383
|
return this.http.get(`/domains${params}`);
|
|
8501
9384
|
}
|
|
8502
|
-
/**
|
|
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
|
+
*/
|
|
8503
9390
|
async generateVerificationToken(domain, method) {
|
|
8504
9391
|
return this.http.post(`/domains/${encodeURIComponent(domain)}/verification`, { method });
|
|
8505
9392
|
}
|
|
@@ -8615,6 +9502,23 @@ var DnsClient = class {
|
|
|
8615
9502
|
}
|
|
8616
9503
|
};
|
|
8617
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
|
+
|
|
8618
9522
|
// src/gateway/client.ts
|
|
8619
9523
|
var SmartGatewayClient = class {
|
|
8620
9524
|
http;
|
|
@@ -8624,6 +9528,8 @@ var SmartGatewayClient = class {
|
|
|
8624
9528
|
domains;
|
|
8625
9529
|
/** DNS resolution and zone management */
|
|
8626
9530
|
dns;
|
|
9531
|
+
/** Per-cluster aggregate health probe (validator + host + genesis state) */
|
|
9532
|
+
health;
|
|
8627
9533
|
constructor(config) {
|
|
8628
9534
|
const baseUrl = config.baseUrl.replace(/\/+$/, "");
|
|
8629
9535
|
this.http = createHttpClient({
|
|
@@ -8635,30 +9541,41 @@ var SmartGatewayClient = class {
|
|
|
8635
9541
|
this.routing = new RoutingClient(this.http);
|
|
8636
9542
|
this.domains = new DomainsClient(this.http);
|
|
8637
9543
|
this.dns = new DnsClient(this.http);
|
|
9544
|
+
this.health = new HealthClient(this.http);
|
|
8638
9545
|
}
|
|
8639
9546
|
// ========== Health & Metrics ==========
|
|
8640
|
-
/** Get gateway health status */
|
|
9547
|
+
/** Get gateway-only health status (binary `status: 'ok'` snapshot). */
|
|
8641
9548
|
async getHealth() {
|
|
8642
9549
|
return this.http.get("/health");
|
|
8643
9550
|
}
|
|
8644
|
-
/**
|
|
9551
|
+
/**
|
|
9552
|
+
* Get detailed gateway status — `subsystems` tree (dns/routing/verification)
|
|
9553
|
+
* plus the operating `mode` snapshot. Aggregated counts live on `getMetrics()`.
|
|
9554
|
+
*/
|
|
8645
9555
|
async getStatus() {
|
|
8646
9556
|
return this.http.get("/status");
|
|
8647
9557
|
}
|
|
8648
|
-
/**
|
|
9558
|
+
/**
|
|
9559
|
+
* Check gateway readiness. Returns either `{ status: 'ready', ... }` with
|
|
9560
|
+
* a verified host count or `{ status: 'not_ready', reason, ... }`.
|
|
9561
|
+
*/
|
|
8649
9562
|
async getReadiness() {
|
|
8650
9563
|
return this.http.get("/ready");
|
|
8651
9564
|
}
|
|
8652
|
-
/** Check gateway liveness */
|
|
9565
|
+
/** Check gateway liveness. */
|
|
8653
9566
|
async getLiveness() {
|
|
8654
9567
|
return this.http.get("/live");
|
|
8655
9568
|
}
|
|
8656
|
-
/**
|
|
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
|
+
*/
|
|
8657
9574
|
async getMetrics(refresh) {
|
|
8658
9575
|
const params = refresh ? "?refresh=true" : "";
|
|
8659
9576
|
return this.http.get(`/metrics${params}`);
|
|
8660
9577
|
}
|
|
8661
|
-
/** Get
|
|
9578
|
+
/** Get lightweight network summary (status-badge-friendly). */
|
|
8662
9579
|
async getMetricsSummary() {
|
|
8663
9580
|
return this.http.get("/metrics/summary");
|
|
8664
9581
|
}
|
|
@@ -9168,8 +10085,10 @@ __export(baas_exports, {
|
|
|
9168
10085
|
BaasError: () => BaasError,
|
|
9169
10086
|
DatabaseClient: () => DatabaseClient,
|
|
9170
10087
|
DeploymentClient: () => DeploymentClient,
|
|
10088
|
+
EntitiesClient: () => EntitiesClient,
|
|
9171
10089
|
FunctionsClient: () => FunctionsClient,
|
|
9172
10090
|
MessagingClient: () => MessagingClient,
|
|
10091
|
+
RulesClient: () => RulesClient,
|
|
9173
10092
|
StorageClient: () => StorageClient,
|
|
9174
10093
|
validateAgentRules: () => validateAgentRules
|
|
9175
10094
|
});
|
|
@@ -9229,11 +10148,37 @@ var DatabaseClient = class {
|
|
|
9229
10148
|
);
|
|
9230
10149
|
}
|
|
9231
10150
|
/**
|
|
9232
|
-
* 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.
|
|
9233
10156
|
*/
|
|
9234
10157
|
async listCollections() {
|
|
9235
10158
|
const appId = this.getAppId();
|
|
9236
|
-
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
|
+
);
|
|
9237
10182
|
}
|
|
9238
10183
|
// ========== State Proofs ==========
|
|
9239
10184
|
/**
|
|
@@ -9294,13 +10239,15 @@ var StorageClient = class {
|
|
|
9294
10239
|
* Download a file by CID
|
|
9295
10240
|
*/
|
|
9296
10241
|
async download(cid) {
|
|
9297
|
-
|
|
10242
|
+
const appId = this.getAppId();
|
|
10243
|
+
return this.http.get(`/api/storage/${encodeURIComponent(appId)}/download/${encodeURIComponent(cid)}`);
|
|
9298
10244
|
}
|
|
9299
10245
|
/**
|
|
9300
10246
|
* Get file metadata
|
|
9301
10247
|
*/
|
|
9302
10248
|
async getMetadata(cid) {
|
|
9303
|
-
|
|
10249
|
+
const appId = this.getAppId();
|
|
10250
|
+
return this.http.get(`/api/storage/${encodeURIComponent(appId)}/metadata/${encodeURIComponent(cid)}`);
|
|
9304
10251
|
}
|
|
9305
10252
|
/**
|
|
9306
10253
|
* Delete a file
|
|
@@ -9310,20 +10257,29 @@ var StorageClient = class {
|
|
|
9310
10257
|
return this.http.delete(`/api/storage/${encodeURIComponent(appId)}/${encodeURIComponent(cid)}`);
|
|
9311
10258
|
}
|
|
9312
10259
|
/**
|
|
9313
|
-
* 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.
|
|
9314
10267
|
*/
|
|
9315
10268
|
async getFile(cid) {
|
|
9316
|
-
|
|
9317
|
-
return this.http.get(`/api/storage/${encodeURIComponent(appId)}/${encodeURIComponent(cid)}`);
|
|
10269
|
+
return this.download(cid);
|
|
9318
10270
|
}
|
|
9319
10271
|
/**
|
|
9320
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.
|
|
9321
10277
|
*/
|
|
9322
10278
|
async listFiles(pagination) {
|
|
9323
10279
|
const appId = this.getAppId();
|
|
9324
10280
|
const params = new URLSearchParams();
|
|
9325
10281
|
if (pagination?.limit !== void 0) params.set("limit", String(pagination.limit));
|
|
9326
|
-
if (pagination?.
|
|
10282
|
+
if (pagination?.offset !== void 0) params.set("offset", String(pagination.offset));
|
|
9327
10283
|
const qs = params.toString();
|
|
9328
10284
|
return this.http.get(`/api/storage/${encodeURIComponent(appId)}/files${qs ? `?${qs}` : ""}`);
|
|
9329
10285
|
}
|
|
@@ -9331,13 +10287,15 @@ var StorageClient = class {
|
|
|
9331
10287
|
* Get storage usage for the current app
|
|
9332
10288
|
*/
|
|
9333
10289
|
async getUsage() {
|
|
9334
|
-
|
|
10290
|
+
const appId = this.getAppId();
|
|
10291
|
+
return this.http.get(`/api/storage/${encodeURIComponent(appId)}/usage`);
|
|
9335
10292
|
}
|
|
9336
10293
|
/**
|
|
9337
10294
|
* Check if a file exists
|
|
9338
10295
|
*/
|
|
9339
10296
|
async exists(cid) {
|
|
9340
|
-
|
|
10297
|
+
const appId = this.getAppId();
|
|
10298
|
+
return this.http.get(`/api/storage/${encodeURIComponent(appId)}/exists/${encodeURIComponent(cid)}`);
|
|
9341
10299
|
}
|
|
9342
10300
|
};
|
|
9343
10301
|
|
|
@@ -9360,42 +10318,60 @@ var FunctionsClient = class {
|
|
|
9360
10318
|
* Invoke a function
|
|
9361
10319
|
*/
|
|
9362
10320
|
async invoke(functionId, payload) {
|
|
9363
|
-
|
|
10321
|
+
const appId = this.getAppId();
|
|
10322
|
+
return this.http.post(
|
|
10323
|
+
`/api/functions/${encodeURIComponent(appId)}/${encodeURIComponent(functionId)}/invoke`,
|
|
10324
|
+
payload ?? {}
|
|
10325
|
+
);
|
|
9364
10326
|
}
|
|
9365
10327
|
/**
|
|
9366
|
-
* List all functions
|
|
10328
|
+
* List all functions for the current app
|
|
9367
10329
|
*/
|
|
9368
10330
|
async list() {
|
|
9369
|
-
|
|
10331
|
+
const appId = this.getAppId();
|
|
10332
|
+
return this.http.get(`/api/functions/${encodeURIComponent(appId)}`);
|
|
9370
10333
|
}
|
|
9371
10334
|
/**
|
|
9372
10335
|
* Get function details
|
|
9373
10336
|
*/
|
|
9374
10337
|
async get(functionId) {
|
|
9375
|
-
|
|
10338
|
+
const appId = this.getAppId();
|
|
10339
|
+
return this.http.get(
|
|
10340
|
+
`/api/functions/${encodeURIComponent(appId)}/${encodeURIComponent(functionId)}`
|
|
10341
|
+
);
|
|
9376
10342
|
}
|
|
9377
10343
|
/**
|
|
9378
10344
|
* Update a function
|
|
9379
10345
|
*/
|
|
9380
10346
|
async update(functionId, updates) {
|
|
9381
|
-
|
|
10347
|
+
const appId = this.getAppId();
|
|
10348
|
+
return this.http.put(
|
|
10349
|
+
`/api/functions/${encodeURIComponent(appId)}/${encodeURIComponent(functionId)}`,
|
|
10350
|
+
updates
|
|
10351
|
+
);
|
|
9382
10352
|
}
|
|
9383
10353
|
/**
|
|
9384
10354
|
* Delete a function
|
|
9385
10355
|
*/
|
|
9386
10356
|
async delete(functionId) {
|
|
9387
|
-
|
|
10357
|
+
const appId = this.getAppId();
|
|
10358
|
+
return this.http.delete(
|
|
10359
|
+
`/api/functions/${encodeURIComponent(appId)}/${encodeURIComponent(functionId)}`
|
|
10360
|
+
);
|
|
9388
10361
|
}
|
|
9389
10362
|
/**
|
|
9390
10363
|
* Get function execution logs
|
|
9391
10364
|
*/
|
|
9392
10365
|
async getLogs(functionId, options) {
|
|
10366
|
+
const appId = this.getAppId();
|
|
9393
10367
|
const params = new URLSearchParams();
|
|
9394
10368
|
if (options?.limit !== void 0) params.set("limit", String(options.limit));
|
|
9395
10369
|
if (options?.startTime) params.set("startTime", options.startTime);
|
|
9396
10370
|
if (options?.level) params.set("level", options.level);
|
|
9397
10371
|
const qs = params.toString();
|
|
9398
|
-
return this.http.get(
|
|
10372
|
+
return this.http.get(
|
|
10373
|
+
`/api/functions/${encodeURIComponent(appId)}/${encodeURIComponent(functionId)}/logs${qs ? `?${qs}` : ""}`
|
|
10374
|
+
);
|
|
9399
10375
|
}
|
|
9400
10376
|
/**
|
|
9401
10377
|
* Get function statistics for an app
|
|
@@ -9467,25 +10443,43 @@ var MessagingClient = class {
|
|
|
9467
10443
|
);
|
|
9468
10444
|
}
|
|
9469
10445
|
/**
|
|
9470
|
-
* 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.
|
|
9471
10452
|
*/
|
|
9472
|
-
async setPresence(member) {
|
|
10453
|
+
async setPresence(channel, member) {
|
|
9473
10454
|
const appId = this.getAppId();
|
|
9474
|
-
return this.http.post(
|
|
10455
|
+
return this.http.post(
|
|
10456
|
+
`/api/messaging/${encodeURIComponent(appId)}/channels/${encodeURIComponent(channel)}/presence`,
|
|
10457
|
+
member
|
|
10458
|
+
);
|
|
9475
10459
|
}
|
|
9476
10460
|
/**
|
|
9477
|
-
* Remove presence
|
|
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.
|
|
9478
10468
|
*/
|
|
9479
|
-
async removePresence(
|
|
10469
|
+
async removePresence(channel, clientId) {
|
|
9480
10470
|
const appId = this.getAppId();
|
|
9481
|
-
return this.http.delete(
|
|
10471
|
+
return this.http.delete(
|
|
10472
|
+
`/api/messaging/${encodeURIComponent(appId)}/channels/${encodeURIComponent(channel)}/presence/${encodeURIComponent(clientId)}`
|
|
10473
|
+
);
|
|
9482
10474
|
}
|
|
9483
10475
|
/**
|
|
9484
10476
|
* Get presence info for a channel
|
|
9485
10477
|
*/
|
|
9486
10478
|
async getPresence(channel) {
|
|
9487
10479
|
const appId = this.getAppId();
|
|
9488
|
-
return this.http.get(
|
|
10480
|
+
return this.http.get(
|
|
10481
|
+
`/api/messaging/${encodeURIComponent(appId)}/channels/${encodeURIComponent(channel)}/presence`
|
|
10482
|
+
);
|
|
9489
10483
|
}
|
|
9490
10484
|
/**
|
|
9491
10485
|
* Get messaging statistics
|
|
@@ -9568,8 +10562,90 @@ var CustomerSessionClient = class {
|
|
|
9568
10562
|
}
|
|
9569
10563
|
};
|
|
9570
10564
|
|
|
10565
|
+
// src/baas/rules/client.ts
|
|
10566
|
+
var RulesClient = class {
|
|
10567
|
+
constructor(http) {
|
|
10568
|
+
this.http = http;
|
|
10569
|
+
}
|
|
10570
|
+
http;
|
|
10571
|
+
/** Publish a canonical ValidatorRules document to HCS. */
|
|
10572
|
+
async publish(rule) {
|
|
10573
|
+
return this.http.post("/api/rules/publish", rule);
|
|
10574
|
+
}
|
|
10575
|
+
/** Fetch a published rule by its HCS consensus timestamp. */
|
|
10576
|
+
async get(consensusTimestamp) {
|
|
10577
|
+
return this.http.get(`/api/rules/${encodeURIComponent(consensusTimestamp)}`);
|
|
10578
|
+
}
|
|
10579
|
+
/** List rules owned by the authenticated entity, optionally filtered by type. */
|
|
10580
|
+
async listByOwner(filter) {
|
|
10581
|
+
const path = filter?.type ? `/api/rules?type=${encodeURIComponent(filter.type)}` : "/api/rules";
|
|
10582
|
+
return this.http.get(path);
|
|
10583
|
+
}
|
|
10584
|
+
/**
|
|
10585
|
+
* Simulate cluster-side evaluation of an action against a rule. Either
|
|
10586
|
+
* `ruleRef` (published) or `rule` (inline) must be supplied by the caller.
|
|
10587
|
+
*/
|
|
10588
|
+
async simulate(params) {
|
|
10589
|
+
return this.http.post("/api/rules/simulate", params);
|
|
10590
|
+
}
|
|
10591
|
+
/** Walk the version history of a published rule. */
|
|
10592
|
+
async getVersionHistory(consensusTimestamp) {
|
|
10593
|
+
return this.http.get(
|
|
10594
|
+
`/api/rules/${encodeURIComponent(consensusTimestamp)}/versions`
|
|
10595
|
+
);
|
|
10596
|
+
}
|
|
10597
|
+
/** Deprecate a published rule (owner-only). */
|
|
10598
|
+
async deprecate(consensusTimestamp) {
|
|
10599
|
+
return this.http.post(
|
|
10600
|
+
`/api/rules/${encodeURIComponent(consensusTimestamp)}/deprecate`,
|
|
10601
|
+
{}
|
|
10602
|
+
);
|
|
10603
|
+
}
|
|
10604
|
+
};
|
|
10605
|
+
|
|
10606
|
+
// src/baas/entities/client.ts
|
|
10607
|
+
var EntitiesClient = class {
|
|
10608
|
+
constructor(http) {
|
|
10609
|
+
this.http = http;
|
|
10610
|
+
}
|
|
10611
|
+
http;
|
|
10612
|
+
/** Create a canonical token entity bound to a published rule. */
|
|
10613
|
+
async createToken(req) {
|
|
10614
|
+
return this.http.post("/api/entities/createToken", req);
|
|
10615
|
+
}
|
|
10616
|
+
/** Create a canonical account entity bound to a published rule. */
|
|
10617
|
+
async createAccount(req) {
|
|
10618
|
+
return this.http.post("/api/entities/createAccount", req);
|
|
10619
|
+
}
|
|
10620
|
+
/** Create a canonical topic entity bound to a published rule. */
|
|
10621
|
+
async createTopic(req) {
|
|
10622
|
+
return this.http.post("/api/entities/createTopic", req);
|
|
10623
|
+
}
|
|
10624
|
+
/** Create a canonical agent entity bound to a published rule. */
|
|
10625
|
+
async createAgent(req) {
|
|
10626
|
+
return this.http.post("/api/entities/createAgent", req);
|
|
10627
|
+
}
|
|
10628
|
+
/**
|
|
10629
|
+
* Mega-helper: build a token rule with a launchpad ModuleEntry attached,
|
|
10630
|
+
* publish it, create the token, and return the combined result in one HTTP
|
|
10631
|
+
* round-trip.
|
|
10632
|
+
*/
|
|
10633
|
+
async launchpad(req) {
|
|
10634
|
+
return this.http.post("/api/entities/launchpad", req);
|
|
10635
|
+
}
|
|
10636
|
+
/** Fetch an entity by its canonical `entityId`. */
|
|
10637
|
+
async get(entityId) {
|
|
10638
|
+
return this.http.get(`/api/entities/${encodeURIComponent(entityId)}`);
|
|
10639
|
+
}
|
|
10640
|
+
/** List entities owned by the authenticated wallet, optionally filtered by type. */
|
|
10641
|
+
async listByOwner(filter) {
|
|
10642
|
+
const path = filter?.type ? `/api/entities?type=${encodeURIComponent(filter.type)}` : "/api/entities";
|
|
10643
|
+
return this.http.get(path);
|
|
10644
|
+
}
|
|
10645
|
+
};
|
|
10646
|
+
|
|
9571
10647
|
// src/baas/client.ts
|
|
9572
|
-
var BaasClient = class {
|
|
10648
|
+
var BaasClient = class _BaasClient {
|
|
9573
10649
|
hostUrl;
|
|
9574
10650
|
pathPrefix;
|
|
9575
10651
|
appId;
|
|
@@ -9594,6 +10670,10 @@ var BaasClient = class {
|
|
|
9594
10670
|
agents;
|
|
9595
10671
|
/** Customer→smart-app session bridge (TokenGate Face B). */
|
|
9596
10672
|
customerSession;
|
|
10673
|
+
/** Canonical validator-rules authoring surface (publish/get/list/simulate). */
|
|
10674
|
+
rules;
|
|
10675
|
+
/** Canonical entity authoring surface (token/account/topic/agent + launchpad). */
|
|
10676
|
+
entities;
|
|
9597
10677
|
constructor(config) {
|
|
9598
10678
|
this.allowInsecure = config.allowInsecure ?? false;
|
|
9599
10679
|
this.hostUrl = validateUrl2(config.hostUrl, this.allowInsecure);
|
|
@@ -9606,14 +10686,92 @@ var BaasClient = class {
|
|
|
9606
10686
|
baseUrl: baseUrlWithPrefix,
|
|
9607
10687
|
timeout: this.timeout
|
|
9608
10688
|
});
|
|
9609
|
-
const getAppId = () => this.requireAppId();
|
|
9610
|
-
this.db = new DatabaseClient(this.http, getAppId);
|
|
9611
|
-
this.storage = new StorageClient(this.http, getAppId);
|
|
9612
|
-
this.functions = new FunctionsClient(this.http, getAppId);
|
|
9613
|
-
this.messaging = new MessagingClient(this.http, getAppId);
|
|
9614
|
-
this.deployment = new DeploymentClient(this.http);
|
|
9615
|
-
this.agents = new AgentsClient(this.http);
|
|
9616
|
-
this.customerSession = new CustomerSessionClient(baseUrlWithPrefix, this.timeout);
|
|
10689
|
+
const getAppId = () => this.requireAppId();
|
|
10690
|
+
this.db = new DatabaseClient(this.http, getAppId);
|
|
10691
|
+
this.storage = new StorageClient(this.http, getAppId);
|
|
10692
|
+
this.functions = new FunctionsClient(this.http, getAppId);
|
|
10693
|
+
this.messaging = new MessagingClient(this.http, getAppId);
|
|
10694
|
+
this.deployment = new DeploymentClient(this.http);
|
|
10695
|
+
this.agents = new AgentsClient(this.http);
|
|
10696
|
+
this.customerSession = new CustomerSessionClient(baseUrlWithPrefix, this.timeout);
|
|
10697
|
+
this.rules = new RulesClient(this.http);
|
|
10698
|
+
this.entities = new EntitiesClient(this.http);
|
|
10699
|
+
}
|
|
10700
|
+
/**
|
|
10701
|
+
* Connect to the Smart Engines BaaS via cluster auto-discovery.
|
|
10702
|
+
*
|
|
10703
|
+
* Zero-config entrypoint flow:
|
|
10704
|
+
*
|
|
10705
|
+
* 1. Resolves the bootstrap seed list:
|
|
10706
|
+
* - `network: 'testnet' | 'mainnet'` → canonical Cloudflare-fronted
|
|
10707
|
+
* gateway via {@link KNOWN_NETWORKS}.
|
|
10708
|
+
* - `bootstrap: string[]` → explicit seed list (private deployments).
|
|
10709
|
+
* 2. Fetches `GET /api/v3/discovery/clusters` from the first reachable
|
|
10710
|
+
* seed; the response carries every active cluster's gateway URL.
|
|
10711
|
+
* 3. Random-picks one active cluster.
|
|
10712
|
+
* 4. Returns a `BaasClient` pointed at that cluster's gatewayUrl, with
|
|
10713
|
+
* `pathPrefix: '/host'` so all BaaS sub-clients (db / storage /
|
|
10714
|
+
* functions / messaging / agents / rules / entities) route through
|
|
10715
|
+
* the gateway's `/host/*` rewrite.
|
|
10716
|
+
*
|
|
10717
|
+
* @example Zero-config (recommended)
|
|
10718
|
+
* ```ts
|
|
10719
|
+
* const baas = await BaasClient.connectToCluster({
|
|
10720
|
+
* network: 'testnet',
|
|
10721
|
+
* appId: 'app_abc',
|
|
10722
|
+
* });
|
|
10723
|
+
*
|
|
10724
|
+
* await baas.db.insert('users', { name: 'Alice' });
|
|
10725
|
+
* ```
|
|
10726
|
+
*
|
|
10727
|
+
* @example Custom seeds (private deployments)
|
|
10728
|
+
* ```ts
|
|
10729
|
+
* const baas = await BaasClient.connectToCluster({
|
|
10730
|
+
* bootstrap: ['https://gateway.my-private-net.example'],
|
|
10731
|
+
* appId: 'app_abc',
|
|
10732
|
+
* });
|
|
10733
|
+
* ```
|
|
10734
|
+
*
|
|
10735
|
+
* @throws {BaasError} `503` when no cluster is reachable via any seed.
|
|
10736
|
+
* @throws {BaasError} `400` when bootstrap resolution yields an empty list
|
|
10737
|
+
* (only possible when the caller passes an empty array explicitly).
|
|
10738
|
+
*/
|
|
10739
|
+
static async connectToCluster(config) {
|
|
10740
|
+
const allowInsecure = config.allowInsecure ?? false;
|
|
10741
|
+
const bootstrap = config.bootstrap ? [...config.bootstrap] : [...resolveNetwork(config.network).bootstrap];
|
|
10742
|
+
if (bootstrap.length === 0) {
|
|
10743
|
+
throw new BaasError(
|
|
10744
|
+
"connectToCluster requires either a non-empty `bootstrap` list or a known `network` name.",
|
|
10745
|
+
400
|
|
10746
|
+
);
|
|
10747
|
+
}
|
|
10748
|
+
const discovery = new ClusterDiscoveryClient({
|
|
10749
|
+
bootstrap,
|
|
10750
|
+
allowInsecure,
|
|
10751
|
+
trustAnchor: config.trustAnchor ? {
|
|
10752
|
+
network: config.trustAnchor.network,
|
|
10753
|
+
registryTopicId: config.trustAnchor.registryTopicId,
|
|
10754
|
+
mirrorNodeUrl: config.trustAnchor.mirrorNodeUrl,
|
|
10755
|
+
allowInsecure
|
|
10756
|
+
} : void 0
|
|
10757
|
+
});
|
|
10758
|
+
const cluster = await discovery.getRandomCluster();
|
|
10759
|
+
if (!cluster) {
|
|
10760
|
+
throw new BaasError(
|
|
10761
|
+
"No active clusters available via bootstrap seeds. Check network reachability or bootstrap URLs.",
|
|
10762
|
+
503
|
|
10763
|
+
);
|
|
10764
|
+
}
|
|
10765
|
+
return new _BaasClient({
|
|
10766
|
+
hostUrl: cluster.endpoints.gatewayUrl,
|
|
10767
|
+
appId: config.appId,
|
|
10768
|
+
appName: config.appName,
|
|
10769
|
+
timeout: config.timeout,
|
|
10770
|
+
allowInsecure,
|
|
10771
|
+
// BaaS traffic is gateway-routed at `/host/*` by default. Callers
|
|
10772
|
+
// pointing at a bare host can override with `pathPrefix: ''`.
|
|
10773
|
+
pathPrefix: config.pathPrefix ?? "/host"
|
|
10774
|
+
});
|
|
9617
10775
|
}
|
|
9618
10776
|
/** Set the app ID (for newly registered apps) */
|
|
9619
10777
|
setAppId(appId) {
|
|
@@ -9627,6 +10785,16 @@ var BaasClient = class {
|
|
|
9627
10785
|
getAppId() {
|
|
9628
10786
|
return this.appId;
|
|
9629
10787
|
}
|
|
10788
|
+
/**
|
|
10789
|
+
* Get the configured host URL. After
|
|
10790
|
+
* {@link BaasClient.connectToCluster} this is the gateway URL of the
|
|
10791
|
+
* cluster the SDK landed on after random-pick — useful for logging,
|
|
10792
|
+
* "behind the curtain" UIs, or debugging which cluster is serving a
|
|
10793
|
+
* given request.
|
|
10794
|
+
*/
|
|
10795
|
+
getHostUrl() {
|
|
10796
|
+
return this.hostUrl;
|
|
10797
|
+
}
|
|
9630
10798
|
/**
|
|
9631
10799
|
* Get HTTP resilience health information
|
|
9632
10800
|
* @returns Object with circuit breaker state and last error (if any)
|
|
@@ -9935,6 +11103,1370 @@ async function verifyPqcAttestation(cert, payload, registrySnapshot) {
|
|
|
9935
11103
|
thresholdMet: true
|
|
9936
11104
|
};
|
|
9937
11105
|
}
|
|
11106
|
+
|
|
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;
|
|
11297
|
+
}
|
|
11298
|
+
/** Add a single module entry on top of any previously set modules. */
|
|
11299
|
+
addModule(module) {
|
|
11300
|
+
this.state.modules = [...this.state.modules ?? [], module];
|
|
11301
|
+
return this;
|
|
11302
|
+
}
|
|
11303
|
+
withInvariants(invariants) {
|
|
11304
|
+
this.state.invariants = invariants;
|
|
11305
|
+
return this;
|
|
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
|
+
}
|
|
11409
|
+
/** Validate + return the typed, schema-conformant rule. Throws on invalid. */
|
|
11410
|
+
build() {
|
|
11411
|
+
const result = this.schema().safeParse(this.state);
|
|
11412
|
+
if (!result.success) {
|
|
11413
|
+
const errors = result.error.issues.map((issue) => {
|
|
11414
|
+
const path = issue.path.join(".");
|
|
11415
|
+
return path ? `${path}: ${issue.message}` : issue.message;
|
|
11416
|
+
});
|
|
11417
|
+
throw new RuleBuildError(`Invalid ${this.state.type ?? "rule"}: ${errors.join("; ")}`, errors);
|
|
11418
|
+
}
|
|
11419
|
+
return result.data;
|
|
11420
|
+
}
|
|
11421
|
+
/** Return the in-progress partial — handy for templates that finish the rule later. */
|
|
11422
|
+
partial() {
|
|
11423
|
+
return this.state;
|
|
11424
|
+
}
|
|
11425
|
+
};
|
|
11426
|
+
var SmartNodeSecuritySchema = zod.z.enum(["partial", "full"]);
|
|
11427
|
+
var OperationControllerSchema = zod.z.enum(["owner", "dao"]);
|
|
11428
|
+
var OperationLimitsSchema = zod.z.object({
|
|
11429
|
+
maxPerTransaction: zod.z.string().optional(),
|
|
11430
|
+
dailyLimit: zod.z.string().optional(),
|
|
11431
|
+
weeklyLimit: zod.z.string().optional(),
|
|
11432
|
+
monthlyLimit: zod.z.string().optional(),
|
|
11433
|
+
totalLimit: zod.z.string().optional(),
|
|
11434
|
+
cooldownSeconds: zod.z.number().int().min(0).optional(),
|
|
11435
|
+
minPerTransaction: zod.z.string().optional()
|
|
11436
|
+
}).strict();
|
|
11437
|
+
var BaseOperationConfigSchema = zod.z.object({
|
|
11438
|
+
enabled: zod.z.boolean(),
|
|
11439
|
+
controller: OperationControllerSchema.optional(),
|
|
11440
|
+
requiresApproval: zod.z.boolean().optional(),
|
|
11441
|
+
limits: OperationLimitsSchema.optional()
|
|
11442
|
+
}).strict();
|
|
11443
|
+
var MintOperationConfigSchema = BaseOperationConfigSchema.extend({}).strict();
|
|
11444
|
+
var UpdateOperationConfigSchema = BaseOperationConfigSchema.extend({
|
|
11445
|
+
allowedFields: zod.z.array(zod.z.string()).optional()
|
|
11446
|
+
}).strict();
|
|
11447
|
+
var PayloadSchemaRefSchema = zod.z.discriminatedUnion("kind", [
|
|
11448
|
+
zod.z.object({ kind: zod.z.literal("builtin"), id: zod.z.string().min(1) }).strict(),
|
|
11449
|
+
zod.z.object({ kind: zod.z.literal("jsonschema"), schema: zod.z.record(zod.z.unknown()) }).strict()
|
|
11450
|
+
]);
|
|
11451
|
+
var SubmitOperationConfigSchema = BaseOperationConfigSchema.extend({
|
|
11452
|
+
maxMessageSize: zod.z.number().int().min(0).optional(),
|
|
11453
|
+
rateLimit: zod.z.object({
|
|
11454
|
+
maxMessages: zod.z.number().int().min(1),
|
|
11455
|
+
periodSeconds: zod.z.number().int().min(1)
|
|
11456
|
+
}).strict().optional(),
|
|
11457
|
+
payloadSchema: PayloadSchemaRefSchema.optional()
|
|
11458
|
+
}).strict();
|
|
11459
|
+
var BurnOperationConfigSchema = BaseOperationConfigSchema.extend({
|
|
11460
|
+
allowHolderBurn: zod.z.boolean().optional()
|
|
11461
|
+
}).strict();
|
|
11462
|
+
var TransferOperationConfigSchema = BaseOperationConfigSchema.extend({
|
|
11463
|
+
blacklistEnabled: zod.z.boolean().optional(),
|
|
11464
|
+
requiresKyc: zod.z.boolean().optional(),
|
|
11465
|
+
whitelist: zod.z.array(zod.z.string()).optional(),
|
|
11466
|
+
blacklist: zod.z.array(zod.z.string()).optional()
|
|
11467
|
+
}).strict();
|
|
11468
|
+
var FreezeOperationConfigSchema = BaseOperationConfigSchema.extend({
|
|
11469
|
+
requiresMultisig: zod.z.boolean().optional()
|
|
11470
|
+
}).strict();
|
|
11471
|
+
var PauseOperationConfigSchema = BaseOperationConfigSchema.extend({}).strict();
|
|
11472
|
+
var TokenOperationsConfigSchema = zod.z.object({
|
|
11473
|
+
mint: MintOperationConfigSchema.optional(),
|
|
11474
|
+
burn: BurnOperationConfigSchema.optional(),
|
|
11475
|
+
transfer: TransferOperationConfigSchema.optional(),
|
|
11476
|
+
freeze: FreezeOperationConfigSchema.optional(),
|
|
11477
|
+
pause: PauseOperationConfigSchema.optional(),
|
|
11478
|
+
wipe: BaseOperationConfigSchema.optional(),
|
|
11479
|
+
update: UpdateOperationConfigSchema.optional(),
|
|
11480
|
+
associate: BaseOperationConfigSchema.optional(),
|
|
11481
|
+
dissociate: BaseOperationConfigSchema.optional(),
|
|
11482
|
+
grantKyc: BaseOperationConfigSchema.optional(),
|
|
11483
|
+
revokeKyc: BaseOperationConfigSchema.optional()
|
|
11484
|
+
}).strict();
|
|
11485
|
+
var AccountOperationsConfigSchema = zod.z.object({
|
|
11486
|
+
transfer: TransferOperationConfigSchema.optional(),
|
|
11487
|
+
update: UpdateOperationConfigSchema.optional(),
|
|
11488
|
+
delete: BaseOperationConfigSchema.optional(),
|
|
11489
|
+
approveAllowance: BaseOperationConfigSchema.optional(),
|
|
11490
|
+
deleteAllowance: BaseOperationConfigSchema.optional(),
|
|
11491
|
+
stake: BaseOperationConfigSchema.optional(),
|
|
11492
|
+
unstake: BaseOperationConfigSchema.optional()
|
|
11493
|
+
}).strict();
|
|
11494
|
+
var TopicOperationsConfigSchema = zod.z.object({
|
|
11495
|
+
submit: SubmitOperationConfigSchema.optional(),
|
|
11496
|
+
update: UpdateOperationConfigSchema.optional(),
|
|
11497
|
+
delete: BaseOperationConfigSchema.optional()
|
|
11498
|
+
}).strict();
|
|
11499
|
+
var KeyConditionSchema = zod.z.object({
|
|
11500
|
+
enabled: zod.z.boolean().optional(),
|
|
11501
|
+
security: SmartNodeSecuritySchema.optional(),
|
|
11502
|
+
controller: OperationControllerSchema.optional(),
|
|
11503
|
+
requiresApproval: zod.z.boolean().optional(),
|
|
11504
|
+
threshold: zod.z.number().int().min(1).optional()
|
|
11505
|
+
}).strict();
|
|
11506
|
+
var TokenKeyConditionsSchema = zod.z.object({
|
|
11507
|
+
admin: KeyConditionSchema.optional(),
|
|
11508
|
+
supply: KeyConditionSchema.optional(),
|
|
11509
|
+
freeze: KeyConditionSchema.optional(),
|
|
11510
|
+
pause: KeyConditionSchema.optional(),
|
|
11511
|
+
wipe: KeyConditionSchema.optional(),
|
|
11512
|
+
kyc: KeyConditionSchema.optional(),
|
|
11513
|
+
feeSchedule: KeyConditionSchema.optional()
|
|
11514
|
+
}).strict();
|
|
11515
|
+
var AccountKeyConditionsSchema = zod.z.object({
|
|
11516
|
+
admin: KeyConditionSchema.optional(),
|
|
11517
|
+
signing: KeyConditionSchema.optional()
|
|
11518
|
+
}).strict();
|
|
11519
|
+
var TopicKeyConditionsSchema = zod.z.object({
|
|
11520
|
+
admin: KeyConditionSchema.optional(),
|
|
11521
|
+
submit: KeyConditionSchema.optional()
|
|
11522
|
+
}).strict();
|
|
11523
|
+
var FixedFeeConditionSchema = zod.z.object({
|
|
11524
|
+
enabled: zod.z.boolean(),
|
|
11525
|
+
amount: zod.z.string(),
|
|
11526
|
+
feeTokenId: zod.z.string().optional(),
|
|
11527
|
+
feeCollectorAccountId: zod.z.string(),
|
|
11528
|
+
allCollectorsAreExempt: zod.z.boolean().optional()
|
|
11529
|
+
}).strict();
|
|
11530
|
+
var FractionalFeeConditionSchema = zod.z.object({
|
|
11531
|
+
enabled: zod.z.boolean(),
|
|
11532
|
+
numerator: zod.z.number().int(),
|
|
11533
|
+
denominator: zod.z.number().int().min(1),
|
|
11534
|
+
minimumAmount: zod.z.string().optional(),
|
|
11535
|
+
maximumAmount: zod.z.string().optional(),
|
|
11536
|
+
feeCollectorAccountId: zod.z.string(),
|
|
11537
|
+
netOfTransfers: zod.z.boolean().optional()
|
|
11538
|
+
}).strict();
|
|
11539
|
+
var RoyaltyFeeConditionSchema = zod.z.object({
|
|
11540
|
+
enabled: zod.z.boolean(),
|
|
11541
|
+
numerator: zod.z.number().int(),
|
|
11542
|
+
denominator: zod.z.number().int().min(1),
|
|
11543
|
+
fallbackFee: FixedFeeConditionSchema.optional(),
|
|
11544
|
+
feeCollectorAccountId: zod.z.string()
|
|
11545
|
+
}).strict();
|
|
11546
|
+
var FeeConditionsSchema = zod.z.object({
|
|
11547
|
+
fixed: zod.z.array(FixedFeeConditionSchema).optional(),
|
|
11548
|
+
fractional: zod.z.array(FractionalFeeConditionSchema).optional(),
|
|
11549
|
+
royalty: zod.z.array(RoyaltyFeeConditionSchema).optional()
|
|
11550
|
+
}).strict();
|
|
11551
|
+
var TimeRangeSchema = zod.z.object({
|
|
11552
|
+
start: zod.z.union([zod.z.number(), zod.z.string()]),
|
|
11553
|
+
end: zod.z.union([zod.z.number(), zod.z.string()])
|
|
11554
|
+
}).strict();
|
|
11555
|
+
var FungibleTokenGateSchema = zod.z.object({
|
|
11556
|
+
tokenId: zod.z.string(),
|
|
11557
|
+
minBalance: zod.z.string(),
|
|
11558
|
+
timeRange: TimeRangeSchema.optional()
|
|
11559
|
+
}).strict();
|
|
11560
|
+
var NonFungibleTokenGateSchema = zod.z.object({
|
|
11561
|
+
tokenId: zod.z.string(),
|
|
11562
|
+
serialNumbers: zod.z.array(zod.z.string()).optional(),
|
|
11563
|
+
timeRange: TimeRangeSchema.optional()
|
|
11564
|
+
}).strict();
|
|
11565
|
+
var TokenGateConditionsSchema = zod.z.object({
|
|
11566
|
+
fungibles: zod.z.object({
|
|
11567
|
+
tokens: zod.z.array(FungibleTokenGateSchema)
|
|
11568
|
+
}),
|
|
11569
|
+
nonFungibles: zod.z.object({
|
|
11570
|
+
tokens: zod.z.array(NonFungibleTokenGateSchema)
|
|
11571
|
+
}),
|
|
11572
|
+
timeRange: TimeRangeSchema.nullable()
|
|
11573
|
+
}).strict();
|
|
11574
|
+
var GovernanceConfigSchema = zod.z.object({
|
|
11575
|
+
daoTokenId: zod.z.string().optional(),
|
|
11576
|
+
proposalThreshold: zod.z.string().optional(),
|
|
11577
|
+
votingThreshold: zod.z.string().optional(),
|
|
11578
|
+
votingPeriodSeconds: zod.z.number().int().min(0).optional(),
|
|
11579
|
+
timelockSeconds: zod.z.number().int().min(0).optional(),
|
|
11580
|
+
quorumPercentage: zod.z.number().min(0).max(100).optional(),
|
|
11581
|
+
/** Pluggable wisdom-weight function (SDK-GOV-1). Registered server-side under `registryKey`. */
|
|
11582
|
+
wisdomWeightFn: zod.z.object({
|
|
11583
|
+
registryKey: zod.z.string().min(1)
|
|
11584
|
+
}).strict().optional(),
|
|
11585
|
+
/** Multi-hop liquid delegation (SDK-GOV-1 / whitepaper §A.7). */
|
|
11586
|
+
delegation: zod.z.object({
|
|
11587
|
+
maxHops: zod.z.number().int().min(1).max(10),
|
|
11588
|
+
decayPerHop: zod.z.number().min(0).max(1),
|
|
11589
|
+
concentrationAlert: zod.z.number().min(0).max(1).optional()
|
|
11590
|
+
}).strict().optional()
|
|
11591
|
+
}).strict();
|
|
11592
|
+
var ValidatorMetadataSchema = zod.z.object({
|
|
11593
|
+
version: zod.z.string(),
|
|
11594
|
+
previousVersion: zod.z.string().optional(),
|
|
11595
|
+
deprecatedAt: zod.z.string().optional(),
|
|
11596
|
+
expiresAt: zod.z.string().optional(),
|
|
11597
|
+
description: zod.z.string().max(500).optional(),
|
|
11598
|
+
author: zod.z.string().optional(),
|
|
11599
|
+
tags: zod.z.array(zod.z.string()).optional(),
|
|
11600
|
+
documentationUrl: zod.z.string().url().optional()
|
|
11601
|
+
}).strict();
|
|
11602
|
+
var RuleInvariantsSchema = zod.z.object({
|
|
11603
|
+
maxSupply: zod.z.string().optional(),
|
|
11604
|
+
minBalance: zod.z.string().optional(),
|
|
11605
|
+
minQuorumPercentage: zod.z.number().min(0).max(100).optional(),
|
|
11606
|
+
minTimelockSeconds: zod.z.number().int().min(0).optional(),
|
|
11607
|
+
immutableFields: zod.z.array(zod.z.string())
|
|
11608
|
+
}).strict();
|
|
11609
|
+
var SoulboundAllowedActionSchema = zod.z.enum(["burn", "wipe", "mint"]);
|
|
11610
|
+
var SoulboundNftConfigSchema = zod.z.object({
|
|
11611
|
+
enforced: zod.z.boolean(),
|
|
11612
|
+
allowedActions: zod.z.array(SoulboundAllowedActionSchema).optional()
|
|
11613
|
+
}).strict();
|
|
11614
|
+
var ModuleEntrySchema = zod.z.object({
|
|
11615
|
+
type: zod.z.string().min(1).max(64).regex(/^[a-z][a-z0-9-]*$/, "Module type must be lowercase alphanumeric with hyphens"),
|
|
11616
|
+
version: zod.z.string().min(1).max(20).regex(/^\d+\.\d+\.\d+$/, "Version must be semver (e.g. 1.0.0)"),
|
|
11617
|
+
config: zod.z.record(zod.z.unknown())
|
|
11618
|
+
});
|
|
11619
|
+
var TokenValidatorRulesSchema = zod.z.object({
|
|
11620
|
+
version: zod.z.literal("3.0"),
|
|
11621
|
+
type: zod.z.literal("token"),
|
|
11622
|
+
created: zod.z.string(),
|
|
11623
|
+
smartNodeSecurity: SmartNodeSecuritySchema.optional(),
|
|
11624
|
+
defaultSecurity: SmartNodeSecuritySchema.optional(),
|
|
11625
|
+
defaultController: OperationControllerSchema.optional(),
|
|
11626
|
+
operations: TokenOperationsConfigSchema,
|
|
11627
|
+
keys: TokenKeyConditionsSchema.optional(),
|
|
11628
|
+
fees: FeeConditionsSchema.optional(),
|
|
11629
|
+
tokenGates: TokenGateConditionsSchema.optional(),
|
|
11630
|
+
timeRange: TimeRangeSchema.nullable().optional(),
|
|
11631
|
+
governance: GovernanceConfigSchema.optional(),
|
|
11632
|
+
metadata: ValidatorMetadataSchema.optional(),
|
|
11633
|
+
modules: zod.z.array(ModuleEntrySchema).max(10).optional(),
|
|
11634
|
+
soulbound: SoulboundNftConfigSchema.optional(),
|
|
11635
|
+
invariants: RuleInvariantsSchema.optional()
|
|
11636
|
+
}).strict().refine((data) => data.smartNodeSecurity || data.defaultSecurity, {
|
|
11637
|
+
message: "Either smartNodeSecurity or defaultSecurity must be provided"
|
|
11638
|
+
});
|
|
11639
|
+
var AccountValidatorRulesSchema = zod.z.object({
|
|
11640
|
+
version: zod.z.literal("3.0"),
|
|
11641
|
+
type: zod.z.literal("account"),
|
|
11642
|
+
created: zod.z.string(),
|
|
11643
|
+
smartNodeSecurity: SmartNodeSecuritySchema.optional(),
|
|
11644
|
+
defaultSecurity: SmartNodeSecuritySchema.optional(),
|
|
11645
|
+
defaultController: OperationControllerSchema.optional(),
|
|
11646
|
+
operations: AccountOperationsConfigSchema,
|
|
11647
|
+
keys: AccountKeyConditionsSchema.optional(),
|
|
11648
|
+
tokenGates: TokenGateConditionsSchema.optional(),
|
|
11649
|
+
timeRange: TimeRangeSchema.nullable().optional(),
|
|
11650
|
+
governance: GovernanceConfigSchema.optional(),
|
|
11651
|
+
metadata: ValidatorMetadataSchema.optional(),
|
|
11652
|
+
modules: zod.z.array(ModuleEntrySchema).max(10).optional(),
|
|
11653
|
+
invariants: RuleInvariantsSchema.optional()
|
|
11654
|
+
}).strict().refine((data) => data.smartNodeSecurity || data.defaultSecurity, {
|
|
11655
|
+
message: "Either smartNodeSecurity or defaultSecurity must be provided"
|
|
11656
|
+
});
|
|
11657
|
+
var TopicValidatorRulesSchema = zod.z.object({
|
|
11658
|
+
version: zod.z.literal("3.0"),
|
|
11659
|
+
type: zod.z.literal("topic"),
|
|
11660
|
+
created: zod.z.string(),
|
|
11661
|
+
smartNodeSecurity: SmartNodeSecuritySchema.optional(),
|
|
11662
|
+
defaultSecurity: SmartNodeSecuritySchema.optional(),
|
|
11663
|
+
defaultController: OperationControllerSchema.optional(),
|
|
11664
|
+
operations: TopicOperationsConfigSchema,
|
|
11665
|
+
keys: TopicKeyConditionsSchema.optional(),
|
|
11666
|
+
tokenGates: TokenGateConditionsSchema.optional(),
|
|
11667
|
+
timeRange: TimeRangeSchema.nullable().optional(),
|
|
11668
|
+
governance: GovernanceConfigSchema.optional(),
|
|
11669
|
+
metadata: ValidatorMetadataSchema.optional(),
|
|
11670
|
+
modules: zod.z.array(ModuleEntrySchema).max(10).optional(),
|
|
11671
|
+
invariants: RuleInvariantsSchema.optional()
|
|
11672
|
+
}).strict().refine((data) => data.smartNodeSecurity || data.defaultSecurity, {
|
|
11673
|
+
message: "Either smartNodeSecurity or defaultSecurity must be provided"
|
|
11674
|
+
});
|
|
11675
|
+
var AgentTypeSchema = zod.z.enum(["trading", "monitoring", "analytics", "custom"]);
|
|
11676
|
+
var AgentPermissionScopeSchema = zod.z.enum(["read", "execute", "modify", "admin"]);
|
|
11677
|
+
var AgentControllerTypeSchema = zod.z.enum(["owner", "dao", "multisig", "automated"]);
|
|
11678
|
+
var AgentAccessControlModeSchema = zod.z.enum([
|
|
11679
|
+
"whitelist",
|
|
11680
|
+
"blacklist",
|
|
11681
|
+
"public",
|
|
11682
|
+
"token_gated"
|
|
11683
|
+
]);
|
|
11684
|
+
var AgentPermissionEntrySchema = zod.z.object({
|
|
11685
|
+
accountId: zod.z.string(),
|
|
11686
|
+
scope: AgentPermissionScopeSchema.optional(),
|
|
11687
|
+
expiresAt: zod.z.union([zod.z.string(), zod.z.date()]).optional(),
|
|
11688
|
+
label: zod.z.string().optional(),
|
|
11689
|
+
metadata: zod.z.record(zod.z.unknown()).optional()
|
|
11690
|
+
}).strict();
|
|
11691
|
+
var AgentPermissionsSchema = zod.z.object({
|
|
11692
|
+
mode: AgentAccessControlModeSchema.optional(),
|
|
11693
|
+
entries: zod.z.array(AgentPermissionEntrySchema),
|
|
11694
|
+
controller: AgentControllerTypeSchema.optional(),
|
|
11695
|
+
allowSelfAdd: zod.z.boolean().optional(),
|
|
11696
|
+
maxEntries: zod.z.number().int().min(0).optional(),
|
|
11697
|
+
requiredScope: AgentPermissionScopeSchema.optional(),
|
|
11698
|
+
allowWildcards: zod.z.boolean().optional()
|
|
11699
|
+
}).strict();
|
|
11700
|
+
var AgentTradeLimitsSchema = zod.z.object({
|
|
11701
|
+
maxPerTrade: zod.z.string(),
|
|
11702
|
+
dailyLimit: zod.z.string(),
|
|
11703
|
+
periodMs: zod.z.number().int().min(0).optional(),
|
|
11704
|
+
decimals: zod.z.number().int().min(0).optional()
|
|
11705
|
+
}).strict();
|
|
11706
|
+
var AgentTokenPairSchema = zod.z.object({
|
|
11707
|
+
baseToken: zod.z.string(),
|
|
11708
|
+
quoteToken: zod.z.string(),
|
|
11709
|
+
chain: zod.z.string()
|
|
11710
|
+
}).strict();
|
|
11711
|
+
var AgentApprovedPairsSchema = zod.z.object({
|
|
11712
|
+
pairs: zod.z.array(AgentTokenPairSchema),
|
|
11713
|
+
strictMode: zod.z.boolean().optional()
|
|
11714
|
+
}).strict();
|
|
11715
|
+
var AgentCooldownSchema = zod.z.object({
|
|
11716
|
+
cooldownMs: zod.z.number().int().min(0),
|
|
11717
|
+
perAction: zod.z.record(zod.z.string(), zod.z.number().int().min(0)).optional()
|
|
11718
|
+
}).strict();
|
|
11719
|
+
var AgentApprovalThresholdSchema = zod.z.object({
|
|
11720
|
+
threshold: zod.z.string(),
|
|
11721
|
+
currency: zod.z.string().optional(),
|
|
11722
|
+
decimals: zod.z.number().int().min(0).optional(),
|
|
11723
|
+
controller: OperationControllerSchema.optional()
|
|
11724
|
+
}).strict();
|
|
11725
|
+
var AgentOperationalWindowSchema = zod.z.object({
|
|
11726
|
+
from: zod.z.union([zod.z.number(), zod.z.string()]),
|
|
11727
|
+
to: zod.z.union([zod.z.number(), zod.z.string()]),
|
|
11728
|
+
timezone: zod.z.string().optional(),
|
|
11729
|
+
inclusive: zod.z.boolean().optional()
|
|
11730
|
+
}).strict();
|
|
11731
|
+
var AgentAllocationLimitsSchema = zod.z.object({
|
|
11732
|
+
min: zod.z.union([zod.z.number(), zod.z.string()]).optional(),
|
|
11733
|
+
max: zod.z.union([zod.z.number(), zod.z.string()]).optional(),
|
|
11734
|
+
tokenId: zod.z.string().optional(),
|
|
11735
|
+
decimals: zod.z.number().int().min(0).optional(),
|
|
11736
|
+
inclusive: zod.z.boolean().optional()
|
|
11737
|
+
}).strict();
|
|
11738
|
+
var AgentValidatorRulesSchema = zod.z.object({
|
|
11739
|
+
version: zod.z.literal("3.0"),
|
|
11740
|
+
type: zod.z.literal("agent"),
|
|
11741
|
+
created: zod.z.string(),
|
|
11742
|
+
smartNodeSecurity: SmartNodeSecuritySchema.optional(),
|
|
11743
|
+
defaultSecurity: SmartNodeSecuritySchema.optional(),
|
|
11744
|
+
defaultController: OperationControllerSchema.optional(),
|
|
11745
|
+
name: zod.z.string().optional(),
|
|
11746
|
+
agentType: AgentTypeSchema.optional(),
|
|
11747
|
+
permissions: AgentPermissionsSchema.optional(),
|
|
11748
|
+
tradeLimits: AgentTradeLimitsSchema.optional(),
|
|
11749
|
+
approvedPairs: AgentApprovedPairsSchema.optional(),
|
|
11750
|
+
cooldown: AgentCooldownSchema.optional(),
|
|
11751
|
+
approvalThreshold: AgentApprovalThresholdSchema.optional(),
|
|
11752
|
+
operationalWindow: AgentOperationalWindowSchema.optional(),
|
|
11753
|
+
allocationLimits: AgentAllocationLimitsSchema.optional(),
|
|
11754
|
+
tokenGates: TokenGateConditionsSchema.optional(),
|
|
11755
|
+
timeRange: TimeRangeSchema.nullable().optional(),
|
|
11756
|
+
governance: GovernanceConfigSchema.optional(),
|
|
11757
|
+
metadata: ValidatorMetadataSchema.optional(),
|
|
11758
|
+
modules: zod.z.array(ModuleEntrySchema).max(10).optional(),
|
|
11759
|
+
invariants: RuleInvariantsSchema.optional()
|
|
11760
|
+
}).strict().refine((data) => data.smartNodeSecurity || data.defaultSecurity, {
|
|
11761
|
+
message: "Either smartNodeSecurity or defaultSecurity must be provided"
|
|
11762
|
+
});
|
|
11763
|
+
var ValidatorRulesSchema = zod.z.union([
|
|
11764
|
+
TokenValidatorRulesSchema,
|
|
11765
|
+
AccountValidatorRulesSchema,
|
|
11766
|
+
TopicValidatorRulesSchema,
|
|
11767
|
+
AgentValidatorRulesSchema
|
|
11768
|
+
]);
|
|
11769
|
+
|
|
11770
|
+
// src/rules/builders/token-rules-builder.ts
|
|
11771
|
+
var TokenRulesBuilder = class extends BaseRuleBuilder {
|
|
11772
|
+
constructor() {
|
|
11773
|
+
super("token");
|
|
11774
|
+
}
|
|
11775
|
+
schema() {
|
|
11776
|
+
return TokenValidatorRulesSchema;
|
|
11777
|
+
}
|
|
11778
|
+
/** Set the full operations config (required by the canonical schema). */
|
|
11779
|
+
withOperations(operations) {
|
|
11780
|
+
this.state.operations = operations;
|
|
11781
|
+
return this;
|
|
11782
|
+
}
|
|
11783
|
+
/** Patch-style operations merge: pass only the ops you want to set/change. */
|
|
11784
|
+
patchOperations(partial) {
|
|
11785
|
+
this.state.operations = { ...this.state.operations ?? {}, ...partial };
|
|
11786
|
+
return this;
|
|
11787
|
+
}
|
|
11788
|
+
withKeys(keys) {
|
|
11789
|
+
this.state.keys = keys;
|
|
11790
|
+
return this;
|
|
11791
|
+
}
|
|
11792
|
+
withFees(fees) {
|
|
11793
|
+
this.state.fees = fees;
|
|
11794
|
+
return this;
|
|
11795
|
+
}
|
|
11796
|
+
withSoulbound(soulbound) {
|
|
11797
|
+
this.state.soulbound = soulbound;
|
|
11798
|
+
return this;
|
|
11799
|
+
}
|
|
11800
|
+
};
|
|
11801
|
+
function forToken() {
|
|
11802
|
+
return new TokenRulesBuilder();
|
|
11803
|
+
}
|
|
11804
|
+
|
|
11805
|
+
// src/rules/builders/account-rules-builder.ts
|
|
11806
|
+
var AccountRulesBuilder = class extends BaseRuleBuilder {
|
|
11807
|
+
constructor() {
|
|
11808
|
+
super("account");
|
|
11809
|
+
}
|
|
11810
|
+
schema() {
|
|
11811
|
+
return AccountValidatorRulesSchema;
|
|
11812
|
+
}
|
|
11813
|
+
withOperations(operations) {
|
|
11814
|
+
this.state.operations = operations;
|
|
11815
|
+
return this;
|
|
11816
|
+
}
|
|
11817
|
+
patchOperations(partial) {
|
|
11818
|
+
this.state.operations = { ...this.state.operations ?? {}, ...partial };
|
|
11819
|
+
return this;
|
|
11820
|
+
}
|
|
11821
|
+
withKeys(keys) {
|
|
11822
|
+
this.state.keys = keys;
|
|
11823
|
+
return this;
|
|
11824
|
+
}
|
|
11825
|
+
};
|
|
11826
|
+
function forAccount() {
|
|
11827
|
+
return new AccountRulesBuilder();
|
|
11828
|
+
}
|
|
11829
|
+
|
|
11830
|
+
// src/rules/builders/topic-rules-builder.ts
|
|
11831
|
+
var TopicRulesBuilder = class extends BaseRuleBuilder {
|
|
11832
|
+
constructor() {
|
|
11833
|
+
super("topic");
|
|
11834
|
+
}
|
|
11835
|
+
schema() {
|
|
11836
|
+
return TopicValidatorRulesSchema;
|
|
11837
|
+
}
|
|
11838
|
+
withOperations(operations) {
|
|
11839
|
+
this.state.operations = operations;
|
|
11840
|
+
return this;
|
|
11841
|
+
}
|
|
11842
|
+
patchOperations(partial) {
|
|
11843
|
+
this.state.operations = { ...this.state.operations ?? {}, ...partial };
|
|
11844
|
+
return this;
|
|
11845
|
+
}
|
|
11846
|
+
withKeys(keys) {
|
|
11847
|
+
this.state.keys = keys;
|
|
11848
|
+
return this;
|
|
11849
|
+
}
|
|
11850
|
+
/**
|
|
11851
|
+
* Convenience: set the submit operation in one call.
|
|
11852
|
+
* Common usage on topics that gate message shape via JSON-Schema payload.
|
|
11853
|
+
*/
|
|
11854
|
+
withSubmit(submit) {
|
|
11855
|
+
this.state.operations = {
|
|
11856
|
+
...this.state.operations ?? {},
|
|
11857
|
+
submit
|
|
11858
|
+
};
|
|
11859
|
+
return this;
|
|
11860
|
+
}
|
|
11861
|
+
/**
|
|
11862
|
+
* Convenience: attach a JSON-Schema payload validation to the submit op.
|
|
11863
|
+
* Equivalent to `withSubmit({ enabled: true, payloadSchema: ref })`.
|
|
11864
|
+
*/
|
|
11865
|
+
withPayloadSchema(payloadSchema) {
|
|
11866
|
+
return this.withSubmit({
|
|
11867
|
+
...this.state.operations?.submit ?? { enabled: true },
|
|
11868
|
+
payloadSchema
|
|
11869
|
+
});
|
|
11870
|
+
}
|
|
11871
|
+
};
|
|
11872
|
+
function forTopic() {
|
|
11873
|
+
return new TopicRulesBuilder();
|
|
11874
|
+
}
|
|
11875
|
+
|
|
11876
|
+
// src/rules/builders/agent-rules-builder.ts
|
|
11877
|
+
var AgentRulesBuilder = class extends BaseRuleBuilder {
|
|
11878
|
+
constructor() {
|
|
11879
|
+
super("agent");
|
|
11880
|
+
}
|
|
11881
|
+
schema() {
|
|
11882
|
+
return AgentValidatorRulesSchema;
|
|
11883
|
+
}
|
|
11884
|
+
withName(name) {
|
|
11885
|
+
this.state.name = name;
|
|
11886
|
+
return this;
|
|
11887
|
+
}
|
|
11888
|
+
withAgentType(agentType) {
|
|
11889
|
+
this.state.agentType = agentType;
|
|
11890
|
+
return this;
|
|
11891
|
+
}
|
|
11892
|
+
withPermissions(permissions) {
|
|
11893
|
+
this.state.permissions = permissions;
|
|
11894
|
+
return this;
|
|
11895
|
+
}
|
|
11896
|
+
withTradeLimits(tradeLimits) {
|
|
11897
|
+
this.state.tradeLimits = tradeLimits;
|
|
11898
|
+
return this;
|
|
11899
|
+
}
|
|
11900
|
+
withApprovedPairs(approvedPairs) {
|
|
11901
|
+
this.state.approvedPairs = approvedPairs;
|
|
11902
|
+
return this;
|
|
11903
|
+
}
|
|
11904
|
+
withCooldown(cooldown) {
|
|
11905
|
+
this.state.cooldown = cooldown;
|
|
11906
|
+
return this;
|
|
11907
|
+
}
|
|
11908
|
+
withApprovalThreshold(approvalThreshold) {
|
|
11909
|
+
this.state.approvalThreshold = approvalThreshold;
|
|
11910
|
+
return this;
|
|
11911
|
+
}
|
|
11912
|
+
withOperationalWindow(window) {
|
|
11913
|
+
this.state.operationalWindow = window;
|
|
11914
|
+
return this;
|
|
11915
|
+
}
|
|
11916
|
+
withAllocationLimits(allocationLimits) {
|
|
11917
|
+
this.state.allocationLimits = allocationLimits;
|
|
11918
|
+
return this;
|
|
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
|
+
}
|
|
11956
|
+
};
|
|
11957
|
+
function forAgent() {
|
|
11958
|
+
return new AgentRulesBuilder();
|
|
11959
|
+
}
|
|
11960
|
+
|
|
11961
|
+
// src/rules/validate.ts
|
|
11962
|
+
function formatIssue(issue) {
|
|
11963
|
+
const path = issue.path.join(".");
|
|
11964
|
+
return path ? `${path}: ${issue.message}` : issue.message;
|
|
11965
|
+
}
|
|
11966
|
+
function pickArm(rule) {
|
|
11967
|
+
if (rule && typeof rule === "object" && "type" in rule) {
|
|
11968
|
+
const t = rule.type;
|
|
11969
|
+
if (t === "token") return TokenValidatorRulesSchema;
|
|
11970
|
+
if (t === "account") return AccountValidatorRulesSchema;
|
|
11971
|
+
if (t === "topic") return TopicValidatorRulesSchema;
|
|
11972
|
+
if (t === "agent") return AgentValidatorRulesSchema;
|
|
11973
|
+
}
|
|
11974
|
+
return ValidatorRulesSchema;
|
|
11975
|
+
}
|
|
11976
|
+
function validate(rule) {
|
|
11977
|
+
const result = pickArm(rule).safeParse(rule);
|
|
11978
|
+
if (result.success) {
|
|
11979
|
+
return { valid: true, errors: [] };
|
|
11980
|
+
}
|
|
11981
|
+
return {
|
|
11982
|
+
valid: false,
|
|
11983
|
+
errors: result.error.issues.map(formatIssue)
|
|
11984
|
+
};
|
|
11985
|
+
}
|
|
11986
|
+
|
|
11987
|
+
// src/rules/modules/index.ts
|
|
11988
|
+
function withLaunchpadDefaults(c) {
|
|
11989
|
+
return {
|
|
11990
|
+
launchTokenDecimals: 0,
|
|
11991
|
+
paymentTokenDecimals: 0,
|
|
11992
|
+
refundOnFailure: true,
|
|
11993
|
+
overflowPolicy: "proportional",
|
|
11994
|
+
platformFeePercent: 0,
|
|
11995
|
+
...c
|
|
11996
|
+
};
|
|
11997
|
+
}
|
|
11998
|
+
function withStakingPoolDefaults(c) {
|
|
11999
|
+
return {
|
|
12000
|
+
stakingTokenDecimals: 0,
|
|
12001
|
+
distributionMethod: "proportional",
|
|
12002
|
+
lockPeriodMs: 0,
|
|
12003
|
+
earlyUnstakePenalty: 0,
|
|
12004
|
+
autoCompound: false,
|
|
12005
|
+
withdrawalCooldownMs: 0,
|
|
12006
|
+
emergencyWithdrawEnabled: true,
|
|
12007
|
+
...c
|
|
12008
|
+
};
|
|
12009
|
+
}
|
|
12010
|
+
function withDaoDefaults(c) {
|
|
12011
|
+
return { smartNodeSecurity: "partial", ...c };
|
|
12012
|
+
}
|
|
12013
|
+
function withDexDefaults(c) {
|
|
12014
|
+
return {
|
|
12015
|
+
defaultSwapFeePercent: 0.3,
|
|
12016
|
+
multiHopEnabled: true,
|
|
12017
|
+
maxHops: 3,
|
|
12018
|
+
defaultSlippagePercent: 0.5,
|
|
12019
|
+
...c
|
|
12020
|
+
};
|
|
12021
|
+
}
|
|
12022
|
+
var module_ = {
|
|
12023
|
+
launchpad: (config) => ({
|
|
12024
|
+
type: "launchpad",
|
|
12025
|
+
version: "1.0.0",
|
|
12026
|
+
config: withLaunchpadDefaults(config)
|
|
12027
|
+
}),
|
|
12028
|
+
stakingPool: (config) => ({
|
|
12029
|
+
type: "staking-pool",
|
|
12030
|
+
version: "1.0.0",
|
|
12031
|
+
config: withStakingPoolDefaults(config)
|
|
12032
|
+
}),
|
|
12033
|
+
dao: (config) => ({
|
|
12034
|
+
type: "dao",
|
|
12035
|
+
version: "1.0.0",
|
|
12036
|
+
config: withDaoDefaults(config)
|
|
12037
|
+
}),
|
|
12038
|
+
dex: (config) => ({
|
|
12039
|
+
type: "dex",
|
|
12040
|
+
version: "1.0.0",
|
|
12041
|
+
config: withDexDefaults(config)
|
|
12042
|
+
})
|
|
12043
|
+
// PR F — `agent` retired per Arc 6 Phase 6.5. Use `Rules.forAgent()` instead.
|
|
12044
|
+
};
|
|
12045
|
+
|
|
12046
|
+
// src/rules/templates/index.ts
|
|
12047
|
+
function toEpoch(d) {
|
|
12048
|
+
return typeof d === "number" ? d : d.getTime();
|
|
12049
|
+
}
|
|
12050
|
+
function meta(templateName, description) {
|
|
12051
|
+
return {
|
|
12052
|
+
version: "1.0.0",
|
|
12053
|
+
description: description ?? `${templateName} (Rules.template.${templateName})`,
|
|
12054
|
+
tags: [`template:${templateName}`]
|
|
12055
|
+
};
|
|
12056
|
+
}
|
|
12057
|
+
function fairLaunch(p) {
|
|
12058
|
+
const launchpad = module_.launchpad({
|
|
12059
|
+
name: p.name,
|
|
12060
|
+
launchTokenId: p.launchTokenId,
|
|
12061
|
+
launchTokenDecimals: p.launchTokenDecimals,
|
|
12062
|
+
paymentTokenId: p.paymentTokenId,
|
|
12063
|
+
paymentTokenDecimals: p.paymentTokenDecimals,
|
|
12064
|
+
totalTokensForSale: p.totalTokensForSale,
|
|
12065
|
+
pricePerToken: p.pricePerToken,
|
|
12066
|
+
hardCap: p.hardCap,
|
|
12067
|
+
softCap: p.softCap,
|
|
12068
|
+
publicWindow: atom.timeRange({
|
|
12069
|
+
from: toEpoch(p.publicStart),
|
|
12070
|
+
to: toEpoch(p.publicEnd)
|
|
12071
|
+
}),
|
|
12072
|
+
treasuryAccount: p.treasuryAccount,
|
|
12073
|
+
vestingSchedule: p.vestingSchedule,
|
|
12074
|
+
refundOnFailure: true,
|
|
12075
|
+
overflowPolicy: "proportional",
|
|
12076
|
+
description: `Fair-launch IDO for ${p.symbol}`
|
|
12077
|
+
});
|
|
12078
|
+
return forToken().withOperations({
|
|
12079
|
+
mint: { enabled: true, controller: "owner" },
|
|
12080
|
+
transfer: { enabled: true, controller: "owner" }
|
|
12081
|
+
}).addModule(launchpad).withMetadata(meta("fairLaunch", p.description)).build();
|
|
12082
|
+
}
|
|
12083
|
+
function tieredIDO(p) {
|
|
12084
|
+
const lowestTierBalance = p.tiers.reduce((acc, t) => {
|
|
12085
|
+
if (acc === "") return t.requiredBalance;
|
|
12086
|
+
const len = Math.max(acc.length, t.requiredBalance.length);
|
|
12087
|
+
const a = acc.padStart(len, "0");
|
|
12088
|
+
const b = t.requiredBalance.padStart(len, "0");
|
|
12089
|
+
return a < b ? acc : t.requiredBalance;
|
|
12090
|
+
}, "");
|
|
12091
|
+
const eligibility = molecule.tokenGate({
|
|
12092
|
+
fungibles: {
|
|
12093
|
+
tokens: [
|
|
12094
|
+
{
|
|
12095
|
+
tokenId: p.governanceTokenId,
|
|
12096
|
+
minBalance: lowestTierBalance || "0",
|
|
12097
|
+
checkBalance: true
|
|
12098
|
+
}
|
|
12099
|
+
],
|
|
12100
|
+
operator: "AND"
|
|
12101
|
+
},
|
|
12102
|
+
overallOperator: "AND"
|
|
12103
|
+
});
|
|
12104
|
+
const launchpad = module_.launchpad({
|
|
12105
|
+
name: p.name,
|
|
12106
|
+
launchTokenId: p.launchTokenId,
|
|
12107
|
+
paymentTokenId: p.paymentTokenId,
|
|
12108
|
+
totalTokensForSale: p.totalTokensForSale,
|
|
12109
|
+
pricePerToken: p.pricePerToken,
|
|
12110
|
+
hardCap: p.hardCap,
|
|
12111
|
+
softCap: p.softCap,
|
|
12112
|
+
registrationWindow: atom.timeRange({
|
|
12113
|
+
from: toEpoch(p.registrationStart),
|
|
12114
|
+
to: toEpoch(p.registrationEnd)
|
|
12115
|
+
}),
|
|
12116
|
+
guaranteedWindow: atom.timeRange({
|
|
12117
|
+
from: toEpoch(p.guaranteedStart),
|
|
12118
|
+
to: toEpoch(p.guaranteedEnd)
|
|
12119
|
+
}),
|
|
12120
|
+
publicWindow: atom.timeRange({
|
|
12121
|
+
from: toEpoch(p.publicStart),
|
|
12122
|
+
to: toEpoch(p.publicEnd)
|
|
12123
|
+
}),
|
|
12124
|
+
eligibility,
|
|
12125
|
+
tiers: p.tiers,
|
|
12126
|
+
treasuryAccount: p.treasuryAccount,
|
|
12127
|
+
refundOnFailure: true,
|
|
12128
|
+
overflowPolicy: "proportional",
|
|
12129
|
+
description: `Tiered IDO for ${p.symbol}`
|
|
12130
|
+
});
|
|
12131
|
+
return forToken().withOperations({
|
|
12132
|
+
mint: { enabled: true, controller: "owner" },
|
|
12133
|
+
transfer: { enabled: true, controller: "owner" }
|
|
12134
|
+
}).addModule(launchpad).withMetadata(meta("tieredIDO", p.description)).build();
|
|
12135
|
+
}
|
|
12136
|
+
function simpleStaking(p) {
|
|
12137
|
+
const startEpoch = toEpoch(p.startAt);
|
|
12138
|
+
const endEpoch = p.endAt !== void 0 ? toEpoch(p.endAt) : void 0;
|
|
12139
|
+
const stakingPool = module_.stakingPool({
|
|
12140
|
+
name: p.name,
|
|
12141
|
+
poolType: "single",
|
|
12142
|
+
stakingTokenId: p.stakingTokenId,
|
|
12143
|
+
rewardTokens: [
|
|
12144
|
+
{
|
|
12145
|
+
tokenId: p.rewardTokenId,
|
|
12146
|
+
rewardRate: p.rewardRate,
|
|
12147
|
+
totalRewards: p.totalRewards
|
|
12148
|
+
}
|
|
12149
|
+
],
|
|
12150
|
+
distributionMethod: "proportional",
|
|
12151
|
+
startAt: new Date(startEpoch).toISOString(),
|
|
12152
|
+
endAt: endEpoch !== void 0 ? new Date(endEpoch).toISOString() : void 0,
|
|
12153
|
+
lockPeriodMs: p.lockPeriodMs ?? 0,
|
|
12154
|
+
autoCompound: false,
|
|
12155
|
+
emergencyWithdrawEnabled: true,
|
|
12156
|
+
description: `Single-asset staking pool: ${p.name}`
|
|
12157
|
+
});
|
|
12158
|
+
return forToken().withOperations({
|
|
12159
|
+
transfer: { enabled: true, controller: "owner" }
|
|
12160
|
+
}).addModule(stakingPool).withMetadata(meta("simpleStaking", p.description)).build();
|
|
12161
|
+
}
|
|
12162
|
+
function tokenDAO(p) {
|
|
12163
|
+
const quorum = p.quorumPercent ?? 10;
|
|
12164
|
+
const timeLockMs = p.timeLockMs ?? 0;
|
|
12165
|
+
const governance = molecule.governance({
|
|
12166
|
+
governanceTokenId: p.governanceTokenId,
|
|
12167
|
+
quorumPercent: quorum,
|
|
12168
|
+
approvalThresholdPercent: p.approvalThresholdPercent ?? 50,
|
|
12169
|
+
proposalThreshold: p.proposalThreshold,
|
|
12170
|
+
votingPeriodMs: p.votingPeriodMs,
|
|
12171
|
+
timeLockMs
|
|
12172
|
+
});
|
|
12173
|
+
const dao = module_.dao({
|
|
12174
|
+
name: p.name,
|
|
12175
|
+
daoType: "token_governed",
|
|
12176
|
+
smartNodeSecurity: "full",
|
|
12177
|
+
governance,
|
|
12178
|
+
treasury: {
|
|
12179
|
+
accountId: p.treasuryAccountId,
|
|
12180
|
+
controlledTokens: p.controlledTokens
|
|
12181
|
+
},
|
|
12182
|
+
description: `Token-governed DAO: ${p.name}`
|
|
12183
|
+
});
|
|
12184
|
+
return forToken().withController("dao").withOperations({
|
|
12185
|
+
mint: { enabled: true, controller: "dao", requiresApproval: true },
|
|
12186
|
+
burn: { enabled: true, controller: "dao", requiresApproval: true },
|
|
12187
|
+
transfer: { enabled: true, controller: "owner" }
|
|
12188
|
+
}).withGovernance({
|
|
12189
|
+
daoTokenId: p.governanceTokenId,
|
|
12190
|
+
proposalThreshold: p.proposalThreshold,
|
|
12191
|
+
votingPeriodSeconds: Math.floor(p.votingPeriodMs / 1e3),
|
|
12192
|
+
timelockSeconds: Math.floor(timeLockMs / 1e3),
|
|
12193
|
+
quorumPercentage: quorum
|
|
12194
|
+
}).addModule(dao).withInvariants({
|
|
12195
|
+
minQuorumPercentage: quorum,
|
|
12196
|
+
minTimelockSeconds: Math.floor(timeLockMs / 1e3),
|
|
12197
|
+
immutableFields: ["governance", "treasury"]
|
|
12198
|
+
}).withMetadata(meta("tokenDAO", p.description)).build();
|
|
12199
|
+
}
|
|
12200
|
+
function multisigDAO(p) {
|
|
12201
|
+
if (p.threshold < 1 || p.threshold > p.signers.length) {
|
|
12202
|
+
throw new Error(
|
|
12203
|
+
`multisigDAO: threshold ${p.threshold} must be between 1 and signers.length (${p.signers.length})`
|
|
12204
|
+
);
|
|
12205
|
+
}
|
|
12206
|
+
const proposalExpirationMs = p.proposalExpirationMs ?? 7 * 24 * 60 * 60 * 1e3;
|
|
12207
|
+
const governance = molecule.governance({
|
|
12208
|
+
governanceTokenId: "multisig",
|
|
12209
|
+
proposalThreshold: "0",
|
|
12210
|
+
votingPeriodMs: proposalExpirationMs,
|
|
12211
|
+
quorumPercent: 0,
|
|
12212
|
+
approvalThresholdPercent: Math.floor(p.threshold / p.signers.length * 100)
|
|
12213
|
+
});
|
|
12214
|
+
const dao = module_.dao({
|
|
12215
|
+
name: p.name,
|
|
12216
|
+
daoType: "multisig",
|
|
12217
|
+
smartNodeSecurity: "full",
|
|
12218
|
+
governance,
|
|
12219
|
+
treasury: {
|
|
12220
|
+
accountId: p.treasuryAccountId,
|
|
12221
|
+
controlledTokens: p.controlledTokens
|
|
12222
|
+
},
|
|
12223
|
+
multisig: {
|
|
12224
|
+
signers: p.signers,
|
|
12225
|
+
threshold: p.threshold,
|
|
12226
|
+
proposalExpirationMs
|
|
12227
|
+
},
|
|
12228
|
+
description: `Multisig DAO: ${p.name}`
|
|
12229
|
+
});
|
|
12230
|
+
return forToken().withController("owner").withOperations({
|
|
12231
|
+
transfer: { enabled: true, controller: "owner", requiresApproval: true }
|
|
12232
|
+
}).addModule(dao).withMetadata(meta("multisigDAO", p.description)).build();
|
|
12233
|
+
}
|
|
12234
|
+
function simpleAMM(p) {
|
|
12235
|
+
const swapFeePercent = p.swapFeePercent ?? 0.3;
|
|
12236
|
+
const poolId = `${p.tokenA.tokenId}-${p.tokenB.tokenId}`;
|
|
12237
|
+
const dex = module_.dex({
|
|
12238
|
+
name: p.name,
|
|
12239
|
+
dexType: "amm",
|
|
12240
|
+
pools: [
|
|
12241
|
+
{
|
|
12242
|
+
poolId,
|
|
12243
|
+
tokenA: p.tokenA,
|
|
12244
|
+
tokenB: p.tokenB,
|
|
12245
|
+
curveType: "constant_product",
|
|
12246
|
+
swapFeePercent
|
|
12247
|
+
}
|
|
12248
|
+
],
|
|
12249
|
+
defaultSwapFeePercent: swapFeePercent,
|
|
12250
|
+
multiHopEnabled: false,
|
|
12251
|
+
description: `Single-pool AMM: ${poolId}`
|
|
12252
|
+
});
|
|
12253
|
+
return forToken().withOperations({
|
|
12254
|
+
transfer: { enabled: true, controller: "owner" }
|
|
12255
|
+
}).addModule(dex).withMetadata(meta("simpleAMM", p.description)).build();
|
|
12256
|
+
}
|
|
12257
|
+
function vestingSchedule(p) {
|
|
12258
|
+
const startEpoch = toEpoch(p.startAt);
|
|
12259
|
+
const vestingMolecule = molecule.vesting({
|
|
12260
|
+
tokenId: p.tokenId,
|
|
12261
|
+
totalAmount: p.totalAmount,
|
|
12262
|
+
beneficiary: p.beneficiary,
|
|
12263
|
+
scheduleType: p.scheduleType,
|
|
12264
|
+
startAt: new Date(startEpoch).toISOString(),
|
|
12265
|
+
cliffDurationMs: p.cliffDurationMs ?? 0,
|
|
12266
|
+
vestingDurationMs: p.vestingDurationMs,
|
|
12267
|
+
treasuryAccount: p.treasuryAccount,
|
|
12268
|
+
returnToTreasury: p.treasuryAccount !== void 0
|
|
12269
|
+
});
|
|
12270
|
+
const vestingModule = {
|
|
12271
|
+
type: "vesting",
|
|
12272
|
+
version: "1.0.0",
|
|
12273
|
+
config: vestingMolecule
|
|
12274
|
+
};
|
|
12275
|
+
return forAccount().withOperations({
|
|
12276
|
+
transfer: { enabled: true, controller: "owner" }
|
|
12277
|
+
}).addModule(vestingModule).withMetadata(meta("vestingSchedule", p.description)).build();
|
|
12278
|
+
}
|
|
12279
|
+
function tradingAgent(p) {
|
|
12280
|
+
return forAgent().withName(p.name).withAgentType("trading").withTradeLimits({
|
|
12281
|
+
maxPerTrade: p.maxPerTrade,
|
|
12282
|
+
dailyLimit: p.dailyLimit
|
|
12283
|
+
}).withApprovedPairs({
|
|
12284
|
+
pairs: p.approvedPairs,
|
|
12285
|
+
strictMode: true
|
|
12286
|
+
}).withCooldown({ cooldownMs: p.cooldownMs ?? 0 }).withApprovalThreshold({
|
|
12287
|
+
threshold: p.approvalThreshold ?? "999999999"
|
|
12288
|
+
}).withMetadata(meta("tradingAgent", p.description)).build();
|
|
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
|
+
}
|
|
12429
|
+
var template = {
|
|
12430
|
+
fairLaunch,
|
|
12431
|
+
tieredIDO,
|
|
12432
|
+
simpleStaking,
|
|
12433
|
+
tokenDAO,
|
|
12434
|
+
multisigDAO,
|
|
12435
|
+
simpleAMM,
|
|
12436
|
+
vestingSchedule,
|
|
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
|
|
12447
|
+
};
|
|
12448
|
+
|
|
12449
|
+
// src/rules/index.ts
|
|
12450
|
+
var Rules = {
|
|
12451
|
+
/** Build a canonical `TokenValidatorRules`. */
|
|
12452
|
+
forToken,
|
|
12453
|
+
/** Build a canonical `AccountValidatorRules`. */
|
|
12454
|
+
forAccount,
|
|
12455
|
+
/** Build a canonical `TopicValidatorRules`. */
|
|
12456
|
+
forTopic,
|
|
12457
|
+
/** Build a canonical `AgentValidatorRules`. */
|
|
12458
|
+
forAgent,
|
|
12459
|
+
/** Local preflight — runs the canonical Zod schema, returns `{valid, errors}`. */
|
|
12460
|
+
validate,
|
|
12461
|
+
/** Atom factories — typed config for primitive rule pieces (`timeRange`, `limits`, …). */
|
|
12462
|
+
atom,
|
|
12463
|
+
/** Molecule factories — typed config for compound rules (`tokenGate`, `governance`, …). */
|
|
12464
|
+
molecule,
|
|
12465
|
+
/** Module factories — typed organism configs wrapped as canonical `ModuleEntry`. */
|
|
12466
|
+
module: module_,
|
|
12467
|
+
/** One-call template factories — ready-to-publish canonical ValidatorRules. */
|
|
12468
|
+
template
|
|
12469
|
+
};
|
|
9938
12470
|
/*! Bundled license information:
|
|
9939
12471
|
|
|
9940
12472
|
@scure/base/lib/index.js:
|
|
@@ -9952,9 +12484,32 @@ async function verifyPqcAttestation(cert, payload, registrySnapshot) {
|
|
|
9952
12484
|
(*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) *)
|
|
9953
12485
|
*/
|
|
9954
12486
|
|
|
12487
|
+
exports.AccountKeyConditionsSchema = AccountKeyConditionsSchema;
|
|
12488
|
+
exports.AccountOperationsConfigSchema = AccountOperationsConfigSchema;
|
|
12489
|
+
exports.AccountRulesBuilder = AccountRulesBuilder;
|
|
12490
|
+
exports.AccountValidatorRulesSchema = AccountValidatorRulesSchema;
|
|
12491
|
+
exports.AgentAccessControlModeSchema = AgentAccessControlModeSchema;
|
|
12492
|
+
exports.AgentAllocationLimitsSchema = AgentAllocationLimitsSchema;
|
|
12493
|
+
exports.AgentApprovalThresholdSchema = AgentApprovalThresholdSchema;
|
|
12494
|
+
exports.AgentApprovedPairsSchema = AgentApprovedPairsSchema;
|
|
12495
|
+
exports.AgentControllerTypeSchema = AgentControllerTypeSchema;
|
|
12496
|
+
exports.AgentCooldownSchema = AgentCooldownSchema;
|
|
12497
|
+
exports.AgentOperationalWindowSchema = AgentOperationalWindowSchema;
|
|
12498
|
+
exports.AgentPermissionEntrySchema = AgentPermissionEntrySchema;
|
|
12499
|
+
exports.AgentPermissionScopeSchema = AgentPermissionScopeSchema;
|
|
12500
|
+
exports.AgentPermissionsSchema = AgentPermissionsSchema;
|
|
12501
|
+
exports.AgentRulesBuilder = AgentRulesBuilder;
|
|
12502
|
+
exports.AgentTokenPairSchema = AgentTokenPairSchema;
|
|
12503
|
+
exports.AgentTradeLimitsSchema = AgentTradeLimitsSchema;
|
|
12504
|
+
exports.AgentTypeSchema = AgentTypeSchema;
|
|
12505
|
+
exports.AgentValidatorRulesSchema = AgentValidatorRulesSchema;
|
|
9955
12506
|
exports.AgentsClient = AgentsClient;
|
|
9956
12507
|
exports.BaasClient = BaasClient;
|
|
9957
12508
|
exports.BaasError = BaasError;
|
|
12509
|
+
exports.BaseOperationConfigSchema = BaseOperationConfigSchema;
|
|
12510
|
+
exports.BaseRuleBuilder = BaseRuleBuilder;
|
|
12511
|
+
exports.BridgeClient = BridgeClient;
|
|
12512
|
+
exports.BurnOperationConfigSchema = BurnOperationConfigSchema;
|
|
9958
12513
|
exports.CapabilityNotEnabledError = CapabilityNotEnabledError;
|
|
9959
12514
|
exports.CapabilityValidationError = CapabilityValidationError;
|
|
9960
12515
|
exports.CircuitBreaker = CircuitBreaker;
|
|
@@ -9963,62 +12518,144 @@ exports.ClusterDiscoveryClient = ClusterDiscoveryClient;
|
|
|
9963
12518
|
exports.CustomerSessionClient = CustomerSessionClient;
|
|
9964
12519
|
exports.DEFAULT_CIRCUIT_BREAKER_CONFIG = DEFAULT_CIRCUIT_BREAKER_CONFIG;
|
|
9965
12520
|
exports.DEFAULT_RETRY_CONFIG = DEFAULT_RETRY_CONFIG;
|
|
12521
|
+
exports.DaoClient = DaoClient;
|
|
12522
|
+
exports.DaoDashboardClient = DaoDashboardClient;
|
|
9966
12523
|
exports.DatabaseClient = DatabaseClient;
|
|
9967
12524
|
exports.DeploymentClient = DeploymentClient;
|
|
12525
|
+
exports.DiscoveryClient = DiscoveryClient;
|
|
9968
12526
|
exports.DnsClient = DnsClient;
|
|
9969
12527
|
exports.DomainsClient = DomainsClient;
|
|
12528
|
+
exports.EntitiesClient = EntitiesClient;
|
|
12529
|
+
exports.EnvelopeClient = EnvelopeClient;
|
|
9970
12530
|
exports.ErrorCode = ErrorCode;
|
|
12531
|
+
exports.FeeConditionsSchema = FeeConditionsSchema;
|
|
12532
|
+
exports.FixedFeeConditionSchema = FixedFeeConditionSchema;
|
|
12533
|
+
exports.FractionalFeeConditionSchema = FractionalFeeConditionSchema;
|
|
12534
|
+
exports.FreezeOperationConfigSchema = FreezeOperationConfigSchema;
|
|
9971
12535
|
exports.FunctionsClient = FunctionsClient;
|
|
12536
|
+
exports.FungibleTokenGateSchema = FungibleTokenGateSchema;
|
|
9972
12537
|
exports.GovernanceClient = GovernanceClient;
|
|
12538
|
+
exports.GovernanceConfigSchema = GovernanceConfigSchema;
|
|
12539
|
+
exports.HealthClient = HealthClient;
|
|
9973
12540
|
exports.HederaTransactionsClient = HederaTransactionsClient;
|
|
12541
|
+
exports.HederaTssClient = HederaTssClient;
|
|
9974
12542
|
exports.HistoricalBalanceClient = HistoricalBalanceClient;
|
|
9975
12543
|
exports.HistoricalBalanceClientError = HistoricalBalanceClientError;
|
|
9976
12544
|
exports.IPFSClient = IPFSClient;
|
|
12545
|
+
exports.KNOWN_NETWORKS = KNOWN_NETWORKS;
|
|
12546
|
+
exports.KeyConditionSchema = KeyConditionSchema;
|
|
9977
12547
|
exports.MIRROR_NODE_URLS = MIRROR_NODE_URLS;
|
|
9978
12548
|
exports.MessagingClient = MessagingClient;
|
|
12549
|
+
exports.MintOperationConfigSchema = MintOperationConfigSchema;
|
|
9979
12550
|
exports.MirrorNodeClient = MirrorNodeClient;
|
|
9980
12551
|
exports.MirrorNodeError = MirrorNodeError;
|
|
12552
|
+
exports.ModuleEntrySchema = ModuleEntrySchema;
|
|
12553
|
+
exports.NonFungibleTokenGateSchema = NonFungibleTokenGateSchema;
|
|
12554
|
+
exports.OperationControllerSchema = OperationControllerSchema;
|
|
12555
|
+
exports.OperationLimitsSchema = OperationLimitsSchema;
|
|
12556
|
+
exports.OperatorClient = OperatorClient;
|
|
9981
12557
|
exports.PERSONHOOD_VERIFIER_NOT_CONFIGURED = PERSONHOOD_VERIFIER_NOT_CONFIGURED;
|
|
12558
|
+
exports.PauseOperationConfigSchema = PauseOperationConfigSchema;
|
|
12559
|
+
exports.PayloadSchemaRefSchema = PayloadSchemaRefSchema;
|
|
9982
12560
|
exports.PersonhoodClient = PersonhoodClient;
|
|
12561
|
+
exports.PlatformImagesClient = PlatformImagesClient;
|
|
9983
12562
|
exports.PolkadotTransactionsClient = PolkadotTransactionsClient;
|
|
9984
12563
|
exports.PqcCertV1Schema = PqcCertV1Schema;
|
|
9985
12564
|
exports.RateLimiter = RateLimiter;
|
|
12565
|
+
exports.ResourcesClient = ResourcesClient;
|
|
9986
12566
|
exports.RoutingClient = RoutingClient;
|
|
12567
|
+
exports.RoyaltyFeeConditionSchema = RoyaltyFeeConditionSchema;
|
|
12568
|
+
exports.RuleBuildError = RuleBuildError;
|
|
12569
|
+
exports.RuleInvariantsSchema = RuleInvariantsSchema;
|
|
12570
|
+
exports.Rules = Rules;
|
|
12571
|
+
exports.RulesClient = RulesClient;
|
|
9987
12572
|
exports.SdkHttpError = SdkHttpError;
|
|
9988
12573
|
exports.SettlementClient = SettlementClient;
|
|
9989
12574
|
exports.SmartEngineClient = SmartEngineClient;
|
|
9990
12575
|
exports.SmartEngineError = SmartEngineError;
|
|
9991
12576
|
exports.SmartGatewayClient = SmartGatewayClient;
|
|
12577
|
+
exports.SmartNodeSecuritySchema = SmartNodeSecuritySchema;
|
|
9992
12578
|
exports.SnapshotsClient = SnapshotsClient;
|
|
9993
12579
|
exports.SolanaTransactionsClient = SolanaTransactionsClient;
|
|
12580
|
+
exports.SoulboundAllowedActionSchema = SoulboundAllowedActionSchema;
|
|
12581
|
+
exports.SoulboundNftConfigSchema = SoulboundNftConfigSchema;
|
|
9994
12582
|
exports.StorageClient = StorageClient;
|
|
12583
|
+
exports.SubmitOperationConfigSchema = SubmitOperationConfigSchema;
|
|
9995
12584
|
exports.SubscriptionClient = SubscriptionClient;
|
|
9996
12585
|
exports.TSSClient = TSSClient;
|
|
12586
|
+
exports.TimeRangeSchema = TimeRangeSchema;
|
|
12587
|
+
exports.TokenGateConditionsSchema = TokenGateConditionsSchema;
|
|
12588
|
+
exports.TokenKeyConditionsSchema = TokenKeyConditionsSchema;
|
|
12589
|
+
exports.TokenOperationsConfigSchema = TokenOperationsConfigSchema;
|
|
12590
|
+
exports.TokenRulesBuilder = TokenRulesBuilder;
|
|
12591
|
+
exports.TokenValidatorRulesSchema = TokenValidatorRulesSchema;
|
|
12592
|
+
exports.TokensClient = TokensClient;
|
|
12593
|
+
exports.TopicKeyConditionsSchema = TopicKeyConditionsSchema;
|
|
12594
|
+
exports.TopicOperationsConfigSchema = TopicOperationsConfigSchema;
|
|
12595
|
+
exports.TopicRulesBuilder = TopicRulesBuilder;
|
|
12596
|
+
exports.TopicValidatorRulesSchema = TopicValidatorRulesSchema;
|
|
9997
12597
|
exports.TransactionsClient = TransactionsClient;
|
|
12598
|
+
exports.TransferOperationConfigSchema = TransferOperationConfigSchema;
|
|
9998
12599
|
exports.UnsupportedCapabilityError = UnsupportedCapabilityError;
|
|
12600
|
+
exports.UpdateOperationConfigSchema = UpdateOperationConfigSchema;
|
|
9999
12601
|
exports.ValidatorAuthClient = ValidatorAuthClient;
|
|
10000
12602
|
exports.ValidatorAuthError = ValidatorAuthError;
|
|
10001
12603
|
exports.ValidatorDiscoveryClient = ValidatorDiscoveryClient;
|
|
12604
|
+
exports.ValidatorMetadataSchema = ValidatorMetadataSchema;
|
|
12605
|
+
exports.ValidatorRulesSchema = ValidatorRulesSchema;
|
|
10002
12606
|
exports.XrplTransactionsClient = XrplTransactionsClient;
|
|
12607
|
+
exports.appTopic = appTopic;
|
|
12608
|
+
exports.atom = atom;
|
|
10003
12609
|
exports.auth = auth_exports;
|
|
10004
12610
|
exports.baas = baas_exports;
|
|
12611
|
+
exports.bridge = bridge_exports;
|
|
10005
12612
|
exports.chains = chains_exports;
|
|
10006
12613
|
exports.createHttpClient = createHttpClient;
|
|
10007
12614
|
exports.createResilientFetchWithBreaker = createResilientFetchWithBreaker;
|
|
10008
12615
|
exports.createXrplWeb3Signer = createXrplWeb3Signer;
|
|
12616
|
+
exports.dao = dao_exports;
|
|
12617
|
+
exports.daoGovernedToken = daoGovernedToken;
|
|
10009
12618
|
exports.discovery = discovery_exports;
|
|
10010
12619
|
exports.encodePathParam = encodePathParam;
|
|
12620
|
+
exports.envelope = envelope_exports;
|
|
12621
|
+
exports.fairLaunch = fairLaunch;
|
|
10011
12622
|
exports.fetchRegistrySnapshot = fetchRegistrySnapshot;
|
|
12623
|
+
exports.forAccount = forAccount;
|
|
12624
|
+
exports.forAgent = forAgent;
|
|
12625
|
+
exports.forToken = forToken;
|
|
12626
|
+
exports.forTopic = forTopic;
|
|
10012
12627
|
exports.governance = governance_exports;
|
|
12628
|
+
exports.isKnownNetwork = isKnownNetwork;
|
|
10013
12629
|
exports.isPersonhoodVerifierNotConfigured = isPersonhoodVerifierNotConfigured;
|
|
10014
12630
|
exports.isRuleRejected = isRuleRejected;
|
|
12631
|
+
exports.managedAccount = managedAccount;
|
|
12632
|
+
exports.membershipNft = membershipNft;
|
|
12633
|
+
exports.module_ = module_;
|
|
12634
|
+
exports.molecule = molecule;
|
|
12635
|
+
exports.multisigDAO = multisigDAO;
|
|
12636
|
+
exports.operator = operator_exports;
|
|
10015
12637
|
exports.parsePqcCert = parsePqcCert;
|
|
10016
12638
|
exports.personhood = personhood_exports;
|
|
10017
12639
|
exports.pqcVerify = pqc_verify_exports;
|
|
10018
12640
|
exports.resilientFetch = resilientFetch;
|
|
12641
|
+
exports.resolveNetwork = resolveNetwork;
|
|
12642
|
+
exports.resources = resources_exports;
|
|
10019
12643
|
exports.settlement = settlement_exports;
|
|
12644
|
+
exports.simpleAMM = simpleAMM;
|
|
12645
|
+
exports.simpleStaking = simpleStaking;
|
|
12646
|
+
exports.soulboundNft = soulboundNft;
|
|
10020
12647
|
exports.subscription = subscription_exports;
|
|
12648
|
+
exports.subscriptionNft = subscriptionNft;
|
|
12649
|
+
exports.systemTopic = systemTopic;
|
|
12650
|
+
exports.template = template;
|
|
12651
|
+
exports.tieredIDO = tieredIDO;
|
|
12652
|
+
exports.tokenDAO = tokenDAO;
|
|
12653
|
+
exports.tokens = tokens_exports;
|
|
12654
|
+
exports.tradingAgent = tradingAgent;
|
|
12655
|
+
exports.utilityToken = utilityToken;
|
|
12656
|
+
exports.validate = validate;
|
|
10021
12657
|
exports.validateAgentRules = validateAgentRules;
|
|
10022
12658
|
exports.verifyPqcAttestation = verifyPqcAttestation;
|
|
12659
|
+
exports.vestingSchedule = vestingSchedule;
|
|
10023
12660
|
//# sourceMappingURL=index.js.map
|
|
10024
12661
|
//# sourceMappingURL=index.js.map
|