@toon-protocol/townhouse 0.5.1 → 0.5.4

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.
@@ -13999,6 +13999,17 @@ var ILP_TO_SEMANTIC = Object.freeze({
13999
13999
  T00: "internal_error",
14000
14000
  T04: "insufficient_funds",
14001
14001
  F00: "invalid_request",
14002
+ // F01 ("Invalid Packet" in ILP terms — emitted by the swap handler for
14003
+ // "Invalid gift wrap" / "Invalid amount") has NO dedicated entry in the
14004
+ // connector's REJECT_CODE_MAP (accepted semantics are: insufficient_funds,
14005
+ // expired, unreachable, invalid_request, invalid_amount,
14006
+ // insufficient_destination_amount, unexpected_payment, application_error,
14007
+ // internal_error, timeout). The closest faithful reason is `invalid_request`,
14008
+ // which the connector re-encodes to wire code F00. We map F01 EXPLICITLY
14009
+ // (rather than relying on the fallback below) so the F01 -> F00 normalization
14010
+ // is intentional and test-pinned, not a silent collapse that misleads callers
14011
+ // into thinking they hit a different failure class. See issue #86.
14012
+ F01: "invalid_request",
14002
14013
  F02: "unreachable",
14003
14014
  F03: "invalid_amount",
14004
14015
  F04: "insufficient_destination_amount",
@@ -14288,6 +14299,7 @@ function resolveConfigNetworkProfile(config, keyId) {
14288
14299
  // src/connector/hs-config-writer.ts
14289
14300
  var HS_DIR = "/var/lib/anon/hs";
14290
14301
  var HS_PORT = 3e3;
14302
+ var DVM_HANDLER_URL = "http://townhouse-hs-dvm:3300";
14291
14303
  function writeHsConnectorConfig(configDir, config, options = {}) {
14292
14304
  const yamlPath = join4(configDir, "connector.yaml");
14293
14305
  if (!options.force && existsSync2(yamlPath)) {
@@ -14326,6 +14338,19 @@ function writeHsConnectorConfig(configDir, config, options = {}) {
14326
14338
  const baseYaml = generator.toYaml(hsRuntimeConfig);
14327
14339
  const parsed = parse2(baseYaml);
14328
14340
  parsed["anon"] = { enabled: true };
14341
+ const apexNodeId = typeof parsed["nodeId"] === "string" ? parsed["nodeId"] : "g.townhouse";
14342
+ parsed["localDelivery"] = { enabled: true, handlerUrl: DVM_HANDLER_URL };
14343
+ const existingRoutes = Array.isArray(parsed["routes"]) ? parsed["routes"] : [];
14344
+ if (!existingRoutes.some(
14345
+ (r) => r["prefix"] === apexNodeId && r["nextHop"] === "local"
14346
+ )) {
14347
+ existingRoutes.push({
14348
+ prefix: apexNodeId,
14349
+ nextHop: "local",
14350
+ priority: 100
14351
+ });
14352
+ }
14353
+ parsed["routes"] = existingRoutes;
14329
14354
  const finalYaml = yamlStringify2(parsed);
14330
14355
  writeFileSync3(yamlPath, finalYaml, { mode: 384, encoding: "utf-8" });
14331
14356
  chmodSync(yamlPath, 384);
@@ -14627,7 +14652,14 @@ var BootReconciler = class {
14627
14652
  id: entry.peerId,
14628
14653
  url: deriveBtpUrl(entry),
14629
14654
  authToken: "",
14630
- routes: [{ prefix: entry.ilpAddress, priority: 0 }]
14655
+ routes: [{ prefix: entry.ilpAddress, priority: 0 }],
14656
+ // Re-registration must mirror the provisioning-path peer config
14657
+ // (nodes-lifecycle.ts), or a connector restart silently restores
14658
+ // peers as settlement 'peer's (paid packets → T00) dialled over the
14659
+ // global SOCKS5 transport (Docker-internal hostnames → HostUnreachable).
14660
+ // Every nodes.yaml entry is an apex-owned child.
14661
+ relation: "child",
14662
+ transport: "direct"
14631
14663
  });
14632
14664
  summary.reregistered++;
14633
14665
  await this.tryAppendLog({
@@ -20311,6 +20343,17 @@ var ACCOUNT_INDEX = {
20311
20343
  dvm: ACCOUNT_INDEX_DVM
20312
20344
  };
20313
20345
  var APEX_ILP_ADDRESS = "g.townhouse";
20346
+ function zeroChannelIdForChain(chain2) {
20347
+ if (chain2.startsWith("solana:")) return "1".repeat(32);
20348
+ return "0x" + "0".repeat(64);
20349
+ }
20350
+ function buildMillChainProviders(config) {
20351
+ const source = config.chainProviders && config.chainProviders.length > 0 ? config.chainProviders : DEFAULT_HS_CHAIN_PROVIDERS;
20352
+ return source.map((provider) => {
20353
+ const { keyId: _keyId, ...rest } = provider;
20354
+ return rest;
20355
+ });
20356
+ }
20314
20357
  function buildMillSwapPairConfig(config) {
20315
20358
  const fromChain = config.chainProviders?.[0]?.chainId ?? "evm:base:31337";
20316
20359
  const toChain = "solana:devnet";
@@ -20326,12 +20369,13 @@ function buildMillSwapPairConfig(config) {
20326
20369
  ],
20327
20370
  chains: ["evm", "solana"],
20328
20371
  // Bootstrap: validateConfig() requires a non-empty channels array for
20329
- // each distinct pair.to.chain. The zero channelId is a valid-format
20330
- // sentinel that will never match a real on-chain channel.
20372
+ // each distinct pair.to.chain. The sentinel channelId is valid-FORMAT for
20373
+ // the target chain (see zeroChannelIdForChain) and never matches a real
20374
+ // on-chain channel.
20331
20375
  channels: {
20332
20376
  [toChain]: [
20333
20377
  {
20334
- channelId: "0x" + "0".repeat(64),
20378
+ channelId: zeroChannelIdForChain(toChain),
20335
20379
  cumulativeAmount: "0",
20336
20380
  nonce: "0"
20337
20381
  }
@@ -20340,7 +20384,9 @@ function buildMillSwapPairConfig(config) {
20340
20384
  // Zero initial SOL inventory; parsed to 0n by the Mill CLI.
20341
20385
  inventory: {
20342
20386
  [toChain]: "0"
20343
- }
20387
+ },
20388
+ // Per-packet claim service config — REQUIRED for the mill to accept swaps.
20389
+ chainProviders: buildMillChainProviders(config)
20344
20390
  };
20345
20391
  }
20346
20392
  async function waitForHealthy(url, timeoutMs) {
@@ -20601,7 +20647,7 @@ function registerNodeLifecycleRoutes(app, deps) {
20601
20647
  await fs5.chmod(dirname8(millConfigPath), 448);
20602
20648
  await fs5.writeFile(millConfigPath, defaultMillConfig, {
20603
20649
  encoding: "utf-8",
20604
- mode: 384
20650
+ mode: 420
20605
20651
  });
20606
20652
  millConfigWritten = true;
20607
20653
  } catch (err) {
@@ -20753,6 +20799,16 @@ function registerNodeLifecycleRoutes(app, deps) {
20753
20799
  url: btpUrl,
20754
20800
  authToken: "",
20755
20801
  routes: [{ prefix: ilpAddress, priority: 0 }],
20802
+ // Tag every provisioned node as a CHILD of the apex. The connector's
20803
+ // `requiresSettlementClaim()` returns false for children, so the apex
20804
+ // forwards client-paid PREPAREs to the node for FREE (parent→child
20805
+ // packets carry no per-packet claim — the apex settles in aggregate).
20806
+ // Without this the peer defaults to 'peer' and every paid packet
20807
+ // forwarded to a town/mill/dvm node is rejected `T00 No payment
20808
+ // channel available for peer`. Pairs with the child-side
20809
+ // `TOON_PARENT_PEER_ID` in townhouse-hs.yml (which MUST equal the
20810
+ // apex connector's nodeId so the child applies the parent relation).
20811
+ relation: "child",
20756
20812
  // Force direct (non-SOCKS5) BTP dial for this Docker-sibling
20757
20813
  // peer. The apex connector runs with `transport.type: socks5`
20758
20814
  // so the .anyone HS can publish; without this override, every
@@ -22789,4 +22845,4 @@ export {
22789
22845
  @scure/bip32/index.js:
22790
22846
  (*! scure-bip32 - MIT License (c) 2022 Patricio Palladino, Paul Miller (paulmillr.com) *)
22791
22847
  */
22792
- //# sourceMappingURL=chunk-EQ6SS4ZJ.js.map
22848
+ //# sourceMappingURL=chunk-FFGRTYIK.js.map