@toon-protocol/townhouse 0.1.2 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-W33MEOPM.js → chunk-B4KWPVEK.js} +219 -40
- package/dist/chunk-B4KWPVEK.js.map +1 -0
- package/dist/cli.d.ts +1 -7
- package/dist/cli.js +227 -44
- package/dist/cli.js.map +1 -1
- package/dist/compose/townhouse-hs.yml +8 -8
- package/dist/image-manifest.json +10 -10
- package/dist/index.d.ts +9 -3
- package/dist/index.js +1 -1
- package/dist/{manager-SsneW_Mj.d.ts → manager-BtpOFwd6.d.ts} +44 -8
- package/dist/{tui-OIFXGBTL.js → tui-QE3ZRZO3.js} +21 -8
- package/dist/tui-QE3ZRZO3.js.map +1 -0
- package/package.json +3 -3
- package/dist/chunk-W33MEOPM.js.map +0 -1
- package/dist/tui-OIFXGBTL.js.map +0 -1
|
@@ -6261,7 +6261,7 @@ function getDefaultConfig() {
|
|
|
6261
6261
|
}
|
|
6262
6262
|
|
|
6263
6263
|
// src/config/validator.ts
|
|
6264
|
-
var VALID_CHAIN_TYPES = /* @__PURE__ */ new Set(["evm"]);
|
|
6264
|
+
var VALID_CHAIN_TYPES = /* @__PURE__ */ new Set(["evm", "solana", "mina"]);
|
|
6265
6265
|
var HEX_ADDRESS = /^0x[a-fA-F0-9]+$/;
|
|
6266
6266
|
var ConfigValidationError = class extends Error {
|
|
6267
6267
|
constructor(message) {
|
|
@@ -6443,39 +6443,74 @@ function validateConfig(raw) {
|
|
|
6443
6443
|
chainProviders = raw["chainProviders"].map((entry, idx) => {
|
|
6444
6444
|
const path = `config.chainProviders[${idx}]`;
|
|
6445
6445
|
assertObject(entry, path);
|
|
6446
|
-
|
|
6447
|
-
|
|
6446
|
+
const chainType = entry["chainType"];
|
|
6447
|
+
assertString(chainType, `${path}.chainType`);
|
|
6448
|
+
if (!VALID_CHAIN_TYPES.has(chainType)) {
|
|
6448
6449
|
throw new ConfigValidationError(
|
|
6449
6450
|
`${path}.chainType must be one of: ${[...VALID_CHAIN_TYPES].join(", ")}`
|
|
6450
6451
|
);
|
|
6451
6452
|
}
|
|
6452
6453
|
assertString(entry["chainId"], `${path}.chainId`);
|
|
6453
|
-
|
|
6454
|
-
|
|
6455
|
-
|
|
6456
|
-
|
|
6457
|
-
|
|
6458
|
-
|
|
6454
|
+
if (chainType === "evm") {
|
|
6455
|
+
assertString(entry["rpcUrl"], `${path}.rpcUrl`);
|
|
6456
|
+
assertString(entry["registryAddress"], `${path}.registryAddress`);
|
|
6457
|
+
if (!HEX_ADDRESS.test(entry["registryAddress"])) {
|
|
6458
|
+
throw new ConfigValidationError(
|
|
6459
|
+
`${path}.registryAddress must match /^0x[a-fA-F0-9]+$/`
|
|
6460
|
+
);
|
|
6461
|
+
}
|
|
6462
|
+
assertString(entry["tokenAddress"], `${path}.tokenAddress`);
|
|
6463
|
+
if (!HEX_ADDRESS.test(entry["tokenAddress"])) {
|
|
6464
|
+
throw new ConfigValidationError(
|
|
6465
|
+
`${path}.tokenAddress must match /^0x[a-fA-F0-9]+$/`
|
|
6466
|
+
);
|
|
6467
|
+
}
|
|
6468
|
+
assertString(entry["keyId"], `${path}.keyId`);
|
|
6469
|
+
if (!HEX_ADDRESS.test(entry["keyId"])) {
|
|
6470
|
+
throw new ConfigValidationError(
|
|
6471
|
+
`${path}.keyId must match /^0x[a-fA-F0-9]+$/`
|
|
6472
|
+
);
|
|
6473
|
+
}
|
|
6474
|
+
return {
|
|
6475
|
+
chainType: "evm",
|
|
6476
|
+
chainId: entry["chainId"],
|
|
6477
|
+
rpcUrl: entry["rpcUrl"],
|
|
6478
|
+
registryAddress: entry["registryAddress"],
|
|
6479
|
+
tokenAddress: entry["tokenAddress"],
|
|
6480
|
+
keyId: entry["keyId"]
|
|
6481
|
+
};
|
|
6459
6482
|
}
|
|
6460
|
-
|
|
6461
|
-
|
|
6462
|
-
|
|
6463
|
-
|
|
6464
|
-
)
|
|
6483
|
+
if (chainType === "solana") {
|
|
6484
|
+
assertString(entry["rpcUrl"], `${path}.rpcUrl`);
|
|
6485
|
+
assertString(entry["programId"], `${path}.programId`);
|
|
6486
|
+
assertString(entry["keyId"], `${path}.keyId`);
|
|
6487
|
+
if (entry["wsUrl"] !== void 0) {
|
|
6488
|
+
assertString(entry["wsUrl"], `${path}.wsUrl`);
|
|
6489
|
+
}
|
|
6490
|
+
if (entry["tokenMint"] !== void 0) {
|
|
6491
|
+
assertString(entry["tokenMint"], `${path}.tokenMint`);
|
|
6492
|
+
}
|
|
6493
|
+
return {
|
|
6494
|
+
chainType: "solana",
|
|
6495
|
+
chainId: entry["chainId"],
|
|
6496
|
+
rpcUrl: entry["rpcUrl"],
|
|
6497
|
+
...entry["wsUrl"] !== void 0 ? { wsUrl: entry["wsUrl"] } : {},
|
|
6498
|
+
programId: entry["programId"],
|
|
6499
|
+
...entry["tokenMint"] !== void 0 ? { tokenMint: entry["tokenMint"] } : {},
|
|
6500
|
+
keyId: entry["keyId"]
|
|
6501
|
+
};
|
|
6465
6502
|
}
|
|
6466
|
-
assertString(entry["
|
|
6467
|
-
|
|
6468
|
-
|
|
6469
|
-
|
|
6470
|
-
);
|
|
6503
|
+
assertString(entry["graphqlUrl"], `${path}.graphqlUrl`);
|
|
6504
|
+
assertString(entry["zkAppAddress"], `${path}.zkAppAddress`);
|
|
6505
|
+
if (entry["keyId"] !== void 0) {
|
|
6506
|
+
assertString(entry["keyId"], `${path}.keyId`);
|
|
6471
6507
|
}
|
|
6472
6508
|
return {
|
|
6473
|
-
chainType:
|
|
6509
|
+
chainType: "mina",
|
|
6474
6510
|
chainId: entry["chainId"],
|
|
6475
|
-
|
|
6476
|
-
|
|
6477
|
-
|
|
6478
|
-
keyId: entry["keyId"]
|
|
6511
|
+
graphqlUrl: entry["graphqlUrl"],
|
|
6512
|
+
zkAppAddress: entry["zkAppAddress"],
|
|
6513
|
+
...entry["keyId"] !== void 0 ? { keyId: entry["keyId"] } : {}
|
|
6479
6514
|
};
|
|
6480
6515
|
});
|
|
6481
6516
|
}
|
|
@@ -6740,14 +6775,36 @@ var ConnectorConfigGenerator = class {
|
|
|
6740
6775
|
routes: []
|
|
6741
6776
|
};
|
|
6742
6777
|
if (this.config.chainProviders !== void 0 && this.config.chainProviders.length > 0) {
|
|
6743
|
-
yamlObj["chainProviders"] = this.config.chainProviders.map((p) =>
|
|
6744
|
-
|
|
6745
|
-
|
|
6746
|
-
|
|
6747
|
-
|
|
6748
|
-
|
|
6749
|
-
|
|
6750
|
-
|
|
6778
|
+
yamlObj["chainProviders"] = this.config.chainProviders.map((p) => {
|
|
6779
|
+
if (p.chainType === "evm") {
|
|
6780
|
+
return {
|
|
6781
|
+
chainType: "evm",
|
|
6782
|
+
chainId: p.chainId,
|
|
6783
|
+
rpcUrl: p.rpcUrl,
|
|
6784
|
+
registryAddress: p.registryAddress,
|
|
6785
|
+
tokenAddress: p.tokenAddress,
|
|
6786
|
+
keyId: p.keyId
|
|
6787
|
+
};
|
|
6788
|
+
}
|
|
6789
|
+
if (p.chainType === "solana") {
|
|
6790
|
+
return {
|
|
6791
|
+
chainType: "solana",
|
|
6792
|
+
chainId: p.chainId,
|
|
6793
|
+
rpcUrl: p.rpcUrl,
|
|
6794
|
+
...p.wsUrl !== void 0 ? { wsUrl: p.wsUrl } : {},
|
|
6795
|
+
programId: p.programId,
|
|
6796
|
+
...p.tokenMint !== void 0 ? { tokenMint: p.tokenMint } : {},
|
|
6797
|
+
keyId: p.keyId
|
|
6798
|
+
};
|
|
6799
|
+
}
|
|
6800
|
+
return {
|
|
6801
|
+
chainType: "mina",
|
|
6802
|
+
chainId: p.chainId,
|
|
6803
|
+
graphqlUrl: p.graphqlUrl,
|
|
6804
|
+
zkAppAddress: p.zkAppAddress,
|
|
6805
|
+
...p.keyId !== void 0 ? { keyId: p.keyId } : {}
|
|
6806
|
+
};
|
|
6807
|
+
});
|
|
6751
6808
|
}
|
|
6752
6809
|
return yamlStringify(yamlObj);
|
|
6753
6810
|
}
|
|
@@ -18337,18 +18394,24 @@ function buildCorsOptions() {
|
|
|
18337
18394
|
// src/api/build-app.ts
|
|
18338
18395
|
var STARTED_AT = (/* @__PURE__ */ new Date()).toISOString();
|
|
18339
18396
|
var _localRequire = nodeCreateRequire(import.meta.url);
|
|
18340
|
-
function
|
|
18341
|
-
for (const rel of [
|
|
18397
|
+
function _resolvePackageVersion(req = _localRequire, env = process.env) {
|
|
18398
|
+
for (const rel of [
|
|
18399
|
+
"../package.json",
|
|
18400
|
+
"../../package.json",
|
|
18401
|
+
"./package.json"
|
|
18402
|
+
]) {
|
|
18342
18403
|
try {
|
|
18343
|
-
|
|
18404
|
+
const pkg = req(rel);
|
|
18405
|
+
if (pkg && typeof pkg.version === "string") {
|
|
18406
|
+
return pkg.version;
|
|
18407
|
+
}
|
|
18344
18408
|
} catch {
|
|
18345
18409
|
}
|
|
18346
18410
|
}
|
|
18347
|
-
|
|
18348
|
-
|
|
18349
|
-
);
|
|
18411
|
+
const envVersion = env["TOWNHOUSE_VERSION"];
|
|
18412
|
+
return typeof envVersion === "string" && envVersion.length > 0 ? envVersion : "0.0.0-unknown";
|
|
18350
18413
|
}
|
|
18351
|
-
var _pkgVersion =
|
|
18414
|
+
var _pkgVersion = _resolvePackageVersion();
|
|
18352
18415
|
var LOOPBACK_HOSTS = ["127.0.0.1", "::1", "localhost"];
|
|
18353
18416
|
async function buildFastifyApp(opts = {}) {
|
|
18354
18417
|
const bindHost = opts.bindHost ?? "127.0.0.1";
|
|
@@ -21113,6 +21176,9 @@ function buildConfigFromRequest(request, configPath) {
|
|
|
21113
21176
|
config.nodes.dvm.feePerJob = request.nodes.dvm.feePerJob;
|
|
21114
21177
|
}
|
|
21115
21178
|
config.transport.mode = request.transport.mode;
|
|
21179
|
+
if (request.chainProviders && request.chainProviders.length > 0) {
|
|
21180
|
+
config.chainProviders = request.chainProviders;
|
|
21181
|
+
}
|
|
21116
21182
|
return config;
|
|
21117
21183
|
}
|
|
21118
21184
|
|
|
@@ -21320,6 +21386,118 @@ function registerTransportRoutes(app, deps, opts = {}) {
|
|
|
21320
21386
|
);
|
|
21321
21387
|
}
|
|
21322
21388
|
|
|
21389
|
+
// src/api/routes/chains.ts
|
|
21390
|
+
var REDACTED = "***";
|
|
21391
|
+
function redactKeyId(providers) {
|
|
21392
|
+
return providers.map((p) => {
|
|
21393
|
+
const hasKey = p.keyId !== void 0;
|
|
21394
|
+
return hasKey ? { ...p, keyId: REDACTED } : { ...p };
|
|
21395
|
+
});
|
|
21396
|
+
}
|
|
21397
|
+
var patchBodySchema3 = {
|
|
21398
|
+
body: {
|
|
21399
|
+
type: "object",
|
|
21400
|
+
additionalProperties: false,
|
|
21401
|
+
required: ["chainProviders"],
|
|
21402
|
+
properties: {
|
|
21403
|
+
chainProviders: {
|
|
21404
|
+
type: "array",
|
|
21405
|
+
maxItems: 32,
|
|
21406
|
+
items: {
|
|
21407
|
+
type: "object",
|
|
21408
|
+
// Deep per-chain validation runs in validateConfig() below; keep the
|
|
21409
|
+
// JSON schema permissive about the discriminated fields, but pin the
|
|
21410
|
+
// discriminator + chainId so obviously-bad payloads fail fast.
|
|
21411
|
+
required: ["chainType", "chainId"],
|
|
21412
|
+
additionalProperties: true,
|
|
21413
|
+
properties: {
|
|
21414
|
+
chainType: { type: "string", enum: ["evm", "solana", "mina"] },
|
|
21415
|
+
chainId: { type: "string", minLength: 1, maxLength: 256 }
|
|
21416
|
+
}
|
|
21417
|
+
}
|
|
21418
|
+
}
|
|
21419
|
+
}
|
|
21420
|
+
}
|
|
21421
|
+
};
|
|
21422
|
+
function registerChainsRoutes(app, deps) {
|
|
21423
|
+
app.get("/api/chains", async (_request, reply) => {
|
|
21424
|
+
return reply.status(200).send({
|
|
21425
|
+
chainProviders: redactKeyId(deps.config.chainProviders ?? []),
|
|
21426
|
+
ts: Date.now()
|
|
21427
|
+
});
|
|
21428
|
+
});
|
|
21429
|
+
app.patch(
|
|
21430
|
+
"/api/chains",
|
|
21431
|
+
{ schema: patchBodySchema3 },
|
|
21432
|
+
async (request, reply) => {
|
|
21433
|
+
const incoming = request.body.chainProviders;
|
|
21434
|
+
if (!acquireConfigMutex()) {
|
|
21435
|
+
return reply.status(409).send({ error: "config_mutation_in_flight" });
|
|
21436
|
+
}
|
|
21437
|
+
const prior = deps.config.chainProviders;
|
|
21438
|
+
const priorByChainId = new Map(
|
|
21439
|
+
(prior ?? []).map((p) => [p.chainId, p])
|
|
21440
|
+
);
|
|
21441
|
+
try {
|
|
21442
|
+
const merged = incoming.map((entry) => {
|
|
21443
|
+
const incomingKeyId = entry.keyId;
|
|
21444
|
+
if (incomingKeyId === void 0 || incomingKeyId === REDACTED) {
|
|
21445
|
+
const priorKeyId = priorByChainId.get(entry.chainId)?.keyId;
|
|
21446
|
+
if (priorKeyId !== void 0) {
|
|
21447
|
+
return { ...entry, keyId: priorKeyId };
|
|
21448
|
+
}
|
|
21449
|
+
if (incomingKeyId === REDACTED) {
|
|
21450
|
+
const { keyId: _drop, ...rest } = entry;
|
|
21451
|
+
return rest;
|
|
21452
|
+
}
|
|
21453
|
+
}
|
|
21454
|
+
return entry;
|
|
21455
|
+
});
|
|
21456
|
+
deps.config.chainProviders = merged.length > 0 ? merged : void 0;
|
|
21457
|
+
try {
|
|
21458
|
+
validateConfig(deps.config);
|
|
21459
|
+
} catch (validationError) {
|
|
21460
|
+
deps.config.chainProviders = prior;
|
|
21461
|
+
return reply.status(400).send({
|
|
21462
|
+
error: "config_validation_error",
|
|
21463
|
+
message: validationError instanceof Error ? validationError.message : "Invalid chain configuration"
|
|
21464
|
+
});
|
|
21465
|
+
}
|
|
21466
|
+
try {
|
|
21467
|
+
await saveConfig(deps.configPath, deps.config);
|
|
21468
|
+
} catch (saveError) {
|
|
21469
|
+
deps.config.chainProviders = prior;
|
|
21470
|
+
return reply.status(500).send({
|
|
21471
|
+
error: "config_save_failed",
|
|
21472
|
+
message: saveError instanceof Error ? saveError.message : "Failed to persist config"
|
|
21473
|
+
});
|
|
21474
|
+
}
|
|
21475
|
+
const activeNodes = Object.entries(deps.config.nodes).filter(([, cfg]) => cfg.enabled).map(([t]) => t);
|
|
21476
|
+
try {
|
|
21477
|
+
await deps.orchestrator.regenerateConnectorConfig(activeNodes);
|
|
21478
|
+
} catch (restartError) {
|
|
21479
|
+
deps.config.chainProviders = prior;
|
|
21480
|
+
try {
|
|
21481
|
+
await saveConfig(deps.configPath, deps.config);
|
|
21482
|
+
} catch {
|
|
21483
|
+
}
|
|
21484
|
+
return reply.status(500).send({
|
|
21485
|
+
error: "connector_restart_failed",
|
|
21486
|
+
message: restartError instanceof Error ? restartError.message : "Connector restart failed"
|
|
21487
|
+
});
|
|
21488
|
+
}
|
|
21489
|
+
return reply.status(200).send({
|
|
21490
|
+
chainProviders: redactKeyId(deps.config.chainProviders ?? []),
|
|
21491
|
+
restartTriggered: true,
|
|
21492
|
+
restartedAt: Date.now()
|
|
21493
|
+
});
|
|
21494
|
+
} finally {
|
|
21495
|
+
releaseConfigMutex();
|
|
21496
|
+
}
|
|
21497
|
+
}
|
|
21498
|
+
);
|
|
21499
|
+
}
|
|
21500
|
+
|
|
21323
21501
|
// src/api/routes/earnings.ts
|
|
21324
21502
|
import { dirname as dirname10, join as join8 } from "path";
|
|
21325
21503
|
|
|
@@ -21807,6 +21985,7 @@ async function createApiServer(deps) {
|
|
|
21807
21985
|
{ mode: "normal" }
|
|
21808
21986
|
);
|
|
21809
21987
|
registerTransportRoutes(app, deps);
|
|
21988
|
+
registerChainsRoutes(app, deps);
|
|
21810
21989
|
registerNodeRoutes(app, deps);
|
|
21811
21990
|
registerWalletRoutes(app, deps);
|
|
21812
21991
|
registerWalletBalancesRoutes(app, deps);
|
|
@@ -22108,4 +22287,4 @@ export {
|
|
|
22108
22287
|
@scure/bip32/index.js:
|
|
22109
22288
|
(*! scure-bip32 - MIT License (c) 2022 Patricio Palladino, Paul Miller (paulmillr.com) *)
|
|
22110
22289
|
*/
|
|
22111
|
-
//# sourceMappingURL=chunk-
|
|
22290
|
+
//# sourceMappingURL=chunk-B4KWPVEK.js.map
|