@toon-protocol/townhouse 0.1.3 → 0.3.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/cli.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import Docker from 'dockerode';
3
- import { C as ComposeLoaderOptions, T as TownhouseConfig, W as WalletManager, N as NodeType } from './manager-SsneW_Mj.js';
3
+ import { C as ComposeLoaderOptions, T as TownhouseConfig, W as WalletManager, N as NodeType } from './manager-BtpOFwd6.js';
4
4
 
5
5
  /**
6
6
  * Cross-platform browser opener for the wizard CLI command.
@@ -119,12 +119,6 @@ interface CliNodeCommandOverrides {
119
119
  confirm?: (question: string) => Promise<boolean>;
120
120
  apiUrl?: string;
121
121
  }
122
- /**
123
- * Main CLI entry — exported for testability (same pattern as Mill CLI).
124
- * Accepts optional dockerode instance for dependency injection in tests.
125
- * The optional `hsOverrides` bag is used by unit tests to stub out Docker,
126
- * file I/O, and admin-client calls in the `hs up` / `hs down` path.
127
- */
128
122
  declare function main(argv: string[], dockerInstance?: Docker, browserOpener?: BrowserOpener, hsOverrides?: CliHsOverrides, nodeCommandOverrides?: CliNodeCommandOverrides): Promise<void>;
129
123
 
130
124
  export { CliHelpRequested, type CliHsOverrides, type CliNodeCommandOverrides, main };
package/dist/cli.js CHANGED
@@ -23,11 +23,12 @@ import {
23
23
  materializeComposeTemplate,
24
24
  readImageManifest,
25
25
  readNodesYaml,
26
+ saveConfig,
26
27
  saveWallet,
27
28
  serviceFromContainerName,
28
29
  tailContainerLogs,
29
30
  writeHsConnectorConfig
30
- } from "./chunk-QHFUIWEN.js";
31
+ } from "./chunk-B4KWPVEK.js";
31
32
  import "./chunk-5O4SBV5O.js";
32
33
  import {
33
34
  CONTAINER_PREFIX
@@ -2004,6 +2005,9 @@ Usage:
2004
2005
  townhouse node add [<type>] [--json] [-c <path>] Provision a child node (default: town)
2005
2006
  townhouse node remove <id> [--yes] [--json] [-c <path>] Deprovision a child node
2006
2007
  townhouse node list [--json] [-c <path>] List provisioned nodes
2008
+ townhouse chains list [--json] [-c <path>] List configured settlement chains (EVM/Solana/Mina)
2009
+ townhouse chains add --chain-type <evm|solana|mina> --chain-id <id> [fields] [-c <path>] Add/update a settlement chain
2010
+ townhouse chains remove <chainId> [-c <path>] Remove a settlement chain
2007
2011
  townhouse channels [--json] Show open payment channels
2008
2012
  townhouse logs <node-id> [-f|--follow] [--lines N] [--json] Tail logs for a node (Ctrl-C to stop)
2009
2013
  townhouse peer <id> [--json] Show per-peer detail card
@@ -3443,6 +3447,143 @@ function _runDockerComposeDown(composePath, withVolumes) {
3443
3447
  });
3444
3448
  });
3445
3449
  }
3450
+ var CHAINS_HELP = `townhouse chains \u2014 configure settlement chains (connector chainProviders)
3451
+
3452
+ The connector settles ILP payment claims on these chains. Changes take effect
3453
+ on the next 'townhouse hs down && townhouse hs up'.
3454
+
3455
+ Usage:
3456
+ townhouse chains list [--json] [-c <path>]
3457
+ townhouse chains add --chain-type <evm|solana|mina> --chain-id <id> [fields] [-c <path>]
3458
+ townhouse chains remove <chainId> [-c <path>]
3459
+
3460
+ Fields by chain type:
3461
+ evm: --rpc-url <url> --registry <0x..> --token-address <0x..> --key-id <0x..>
3462
+ solana: --rpc-url <url> --program-id <addr> --key-id <id> [--ws-url <url>] [--token-mint <addr>]
3463
+ mina: --graphql-url <url> --zkapp <addr> [--key-id <id>]`;
3464
+ function buildChainProviderFromFlags(f) {
3465
+ const { chainType, chainId } = f;
3466
+ if (chainType !== "evm" && chainType !== "solana" && chainType !== "mina") {
3467
+ throw new Error("--chain-type must be one of: evm, solana, mina");
3468
+ }
3469
+ if (!chainId) throw new Error("--chain-id is required");
3470
+ const require2 = (flag, val) => {
3471
+ if (!val) throw new Error(`${flag} is required for ${chainType} chains`);
3472
+ return val;
3473
+ };
3474
+ if (chainType === "evm") {
3475
+ return {
3476
+ chainType: "evm",
3477
+ chainId,
3478
+ rpcUrl: require2("--rpc-url", f.rpcUrl),
3479
+ registryAddress: require2("--registry", f.registry),
3480
+ tokenAddress: require2("--token-address", f.tokenAddress),
3481
+ keyId: require2("--key-id", f.keyId)
3482
+ };
3483
+ }
3484
+ if (chainType === "solana") {
3485
+ return {
3486
+ chainType: "solana",
3487
+ chainId,
3488
+ rpcUrl: require2("--rpc-url", f.rpcUrl),
3489
+ ...f.wsUrl ? { wsUrl: f.wsUrl } : {},
3490
+ programId: require2("--program-id", f.programId),
3491
+ ...f.tokenMint ? { tokenMint: f.tokenMint } : {},
3492
+ keyId: require2("--key-id", f.keyId)
3493
+ };
3494
+ }
3495
+ return {
3496
+ chainType: "mina",
3497
+ chainId,
3498
+ graphqlUrl: require2("--graphql-url", f.graphqlUrl),
3499
+ zkAppAddress: require2("--zkapp", f.zkapp),
3500
+ ...f.keyId ? { keyId: f.keyId } : {}
3501
+ };
3502
+ }
3503
+ async function handleChains(action, chainIdArg, flags, configPath, jsonMode) {
3504
+ if (!action) {
3505
+ console.log(CHAINS_HELP);
3506
+ throw new CliHelpRequested();
3507
+ }
3508
+ const config = loadConfig(configPath);
3509
+ const providers = config.chainProviders ?? [];
3510
+ switch (action) {
3511
+ case "list": {
3512
+ if (jsonMode) {
3513
+ console.log(JSON.stringify(providers, null, 2));
3514
+ return;
3515
+ }
3516
+ if (providers.length === 0) {
3517
+ console.log(
3518
+ "No settlement chains configured \u2014 the connector uses a built-in dev-Anvil EVM placeholder."
3519
+ );
3520
+ console.log(
3521
+ "Add one with: townhouse chains add --chain-type evm --chain-id evm:base:8453 ..."
3522
+ );
3523
+ return;
3524
+ }
3525
+ console.log("Configured settlement chains:");
3526
+ for (const p of providers) {
3527
+ console.log(` ${p.chainType.padEnd(6)} ${p.chainId}`);
3528
+ }
3529
+ return;
3530
+ }
3531
+ case "add": {
3532
+ let entry;
3533
+ try {
3534
+ entry = buildChainProviderFromFlags(flags);
3535
+ } catch (err) {
3536
+ console.error(err instanceof Error ? err.message : String(err));
3537
+ process.exitCode = 1;
3538
+ return;
3539
+ }
3540
+ const next = providers.filter((p) => p.chainId !== entry.chainId);
3541
+ next.push(entry);
3542
+ try {
3543
+ saveConfig(configPath, { ...config, chainProviders: next });
3544
+ } catch (err) {
3545
+ console.error(
3546
+ `Invalid chain config: ${err instanceof Error ? err.message : String(err)}`
3547
+ );
3548
+ process.exitCode = 1;
3549
+ return;
3550
+ }
3551
+ console.log(
3552
+ `Added ${entry.chainType} settlement chain '${entry.chainId}'.`
3553
+ );
3554
+ console.log("Apply with: townhouse hs down && townhouse hs up");
3555
+ return;
3556
+ }
3557
+ case "remove": {
3558
+ if (!chainIdArg) {
3559
+ console.error("Usage: townhouse chains remove <chainId>");
3560
+ process.exitCode = 1;
3561
+ return;
3562
+ }
3563
+ const next = providers.filter((p) => p.chainId !== chainIdArg);
3564
+ if (next.length === providers.length) {
3565
+ console.error(
3566
+ `No settlement chain with chainId '${chainIdArg}' found.`
3567
+ );
3568
+ process.exitCode = 1;
3569
+ return;
3570
+ }
3571
+ saveConfig(configPath, {
3572
+ ...config,
3573
+ chainProviders: next.length > 0 ? next : void 0
3574
+ });
3575
+ console.log(`Removed settlement chain '${chainIdArg}'.`);
3576
+ console.log("Apply with: townhouse hs down && townhouse hs up");
3577
+ return;
3578
+ }
3579
+ default: {
3580
+ const safe = action.replace(/[\x00-\x1f\x7f]/g, "");
3581
+ console.error(`Unknown chains subcommand: ${safe}`);
3582
+ console.log(CHAINS_HELP);
3583
+ process.exitCode = 1;
3584
+ }
3585
+ }
3586
+ }
3446
3587
  async function main(argv, dockerInstance, browserOpener, hsOverrides, nodeCommandOverrides) {
3447
3588
  const { values, positionals } = parseArgs({
3448
3589
  args: argv,
@@ -3477,7 +3618,19 @@ async function main(argv, dockerInstance, browserOpener, hsOverrides, nodeComman
3477
3618
  // wallet show / wallet seed (epic-49, Phase 3)
3478
3619
  hex: { type: "boolean" },
3479
3620
  paths: { type: "boolean" },
3480
- confirm: { type: "boolean" }
3621
+ confirm: { type: "boolean" },
3622
+ // chains add (multi-chain settlement config)
3623
+ "chain-type": { type: "string" },
3624
+ "chain-id": { type: "string" },
3625
+ "rpc-url": { type: "string" },
3626
+ "ws-url": { type: "string" },
3627
+ registry: { type: "string" },
3628
+ "token-address": { type: "string" },
3629
+ "token-mint": { type: "string" },
3630
+ "program-id": { type: "string" },
3631
+ "graphql-url": { type: "string" },
3632
+ zkapp: { type: "string" },
3633
+ "key-id": { type: "string" }
3481
3634
  },
3482
3635
  strict: false,
3483
3636
  allowPositionals: true
@@ -3712,6 +3865,32 @@ async function main(argv, dockerInstance, browserOpener, hsOverrides, nodeComman
3712
3865
  }
3713
3866
  break;
3714
3867
  }
3868
+ case "chains": {
3869
+ const configPath = values.config ?? DEFAULT_CONFIG_PATH;
3870
+ const action = positionals[1];
3871
+ const chainIdArg = positionals[2];
3872
+ const flags = {
3873
+ chainType: values["chain-type"],
3874
+ chainId: values["chain-id"],
3875
+ rpcUrl: values["rpc-url"],
3876
+ wsUrl: values["ws-url"],
3877
+ registry: values["registry"],
3878
+ tokenAddress: values["token-address"],
3879
+ tokenMint: values["token-mint"],
3880
+ programId: values["program-id"],
3881
+ graphqlUrl: values["graphql-url"],
3882
+ zkapp: values["zkapp"],
3883
+ keyId: values["key-id"]
3884
+ };
3885
+ await handleChains(
3886
+ action,
3887
+ chainIdArg,
3888
+ flags,
3889
+ configPath,
3890
+ values.json === true
3891
+ );
3892
+ break;
3893
+ }
3715
3894
  default: {
3716
3895
  const sanitized = command.replace(/[\x00-\x1f\x7f]/g, "");
3717
3896
  console.error(`Unknown command: ${sanitized}`);