shinjuku-shielded 0.3.68 → 0.3.69

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/manifest.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "schema": "carbon-shielded-wallet/bundle-manifest/v1",
3
3
  "file": "shinjuku-wallet.mjs",
4
- "sha256": "3d64f9b47b1139c42d3a2ff22642951710beeb669bf633b934b31419e94cc843",
5
- "bytes": 12187129,
6
- "sourceCommit": "8fd3e9152a6ef43a73769ded07e2cfa23c03615b",
4
+ "sha256": "c6cbe0a61037f0a435f7ce448d6ff6fc6a4a97a9b7336fea33c9e7a1e56c11e7",
5
+ "bytes": 12194855,
6
+ "sourceCommit": "6325678a822487e65a0bccf3f398ba32fab563e8",
7
7
  "sourceDirty": false,
8
8
  "installRecordMatchesLockfile": true,
9
9
  "releaseRule": "valid only when two fresh npm ci --ignore-scripts builds on different OSes give the same sha256; installRecordMatchesLockfile true means every entry npm installed equals its package-lock.json entry and every entry not marked optional, devOptional included, is installed: an optional entry (a package for another platform) may be absent",
@@ -1282,5 +1282,5 @@
1282
1282
  "version": "1.8.0"
1283
1283
  }
1284
1284
  ],
1285
- "publishedAt": "2026-10-22T13:57:14.597Z"
1285
+ "publishedAt": "2026-10-22T14:42:59.608Z"
1286
1286
  }
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "shinjuku-shielded",
3
- "version": "0.3.68",
3
+ "version": "0.3.69",
4
4
  "mcpName": "io.github.ShinjukuStaition/shinjuku-mcp",
5
5
  "description": "Shinjuku Shielded, the private x402 facilitator on Solana: the self-custody wallet CLI and its MCP server. Shield, pay, and unshield USDC from any MCP agent, under caps you set.",
6
- "shinjukuRelease": "3d64f9b4",
7
- "shinjukuSha256": "3d64f9b47b1139c42d3a2ff22642951710beeb669bf633b934b31419e94cc843",
6
+ "shinjukuRelease": "c6cbe0a6",
7
+ "shinjukuSha256": "c6cbe0a61037f0a435f7ce448d6ff6fc6a4a97a9b7336fea33c9e7a1e56c11e7",
8
8
  "license": "SEE LICENSE IN LICENSE.txt",
9
9
  "author": "Shinjuku Shielded",
10
10
  "homepage": "https://github.com/ShinjukuStaition/shinjuku-mcp#readme",
@@ -13144,8 +13144,8 @@ var require_utils4 = __commonJS({
13144
13144
  module.exports.wrapperForImpl = function(impl) {
13145
13145
  return impl[module.exports.wrapperSymbol];
13146
13146
  };
13147
- module.exports.implForWrapper = function(wrapper) {
13148
- return wrapper[module.exports.implSymbol];
13147
+ module.exports.implForWrapper = function(wrapper2) {
13148
+ return wrapper2[module.exports.implSymbol];
13149
13149
  };
13150
13150
  }
13151
13151
  });
@@ -18026,9 +18026,9 @@ var require_event_target = __commonJS({
18026
18026
  return;
18027
18027
  }
18028
18028
  }
18029
- let wrapper;
18029
+ let wrapper2;
18030
18030
  if (type === "message") {
18031
- wrapper = function onMessage(data, isBinary) {
18031
+ wrapper2 = function onMessage(data, isBinary) {
18032
18032
  const event = new MessageEvent("message", {
18033
18033
  data: isBinary ? data : data.toString()
18034
18034
  });
@@ -18036,7 +18036,7 @@ var require_event_target = __commonJS({
18036
18036
  callListener(handler, this, event);
18037
18037
  };
18038
18038
  } else if (type === "close") {
18039
- wrapper = function onClose(code2, message) {
18039
+ wrapper2 = function onClose(code2, message) {
18040
18040
  const event = new CloseEvent("close", {
18041
18041
  code: code2,
18042
18042
  reason: message.toString(),
@@ -18046,7 +18046,7 @@ var require_event_target = __commonJS({
18046
18046
  callListener(handler, this, event);
18047
18047
  };
18048
18048
  } else if (type === "error") {
18049
- wrapper = function onError(error) {
18049
+ wrapper2 = function onError(error) {
18050
18050
  const event = new ErrorEvent("error", {
18051
18051
  error,
18052
18052
  message: error.message
@@ -18055,7 +18055,7 @@ var require_event_target = __commonJS({
18055
18055
  callListener(handler, this, event);
18056
18056
  };
18057
18057
  } else if (type === "open") {
18058
- wrapper = function onOpen() {
18058
+ wrapper2 = function onOpen() {
18059
18059
  const event = new Event("open");
18060
18060
  event[kTarget] = this;
18061
18061
  callListener(handler, this, event);
@@ -18063,12 +18063,12 @@ var require_event_target = __commonJS({
18063
18063
  } else {
18064
18064
  return;
18065
18065
  }
18066
- wrapper[kForOnEventAttribute] = !!options[kForOnEventAttribute];
18067
- wrapper[kListener] = handler;
18066
+ wrapper2[kForOnEventAttribute] = !!options[kForOnEventAttribute];
18067
+ wrapper2[kListener] = handler;
18068
18068
  if (options.once) {
18069
- this.once(type, wrapper);
18069
+ this.once(type, wrapper2);
18070
18070
  } else {
18071
- this.on(type, wrapper);
18071
+ this.on(type, wrapper2);
18072
18072
  }
18073
18073
  },
18074
18074
  /**
@@ -42800,7 +42800,10 @@ async function routeFacilitatorsOverOnion(argv2, {
42800
42800
  onNone?.();
42801
42801
  }
42802
42802
  });
42803
+ const first = firstRaces.has(group.label) ? void 0 : { startedAt: Date.now() };
42804
+ if (first) firstRaces.set(group.label, first);
42803
42805
  group.pending = raced.winner.then((onion) => {
42806
+ if (first) Object.assign(first, { endedAt: Date.now(), answered: !unanswered2 });
42804
42807
  group.winner = onion;
42805
42808
  group.pending = void 0;
42806
42809
  if (!unanswered2 && !raced.stopped) err(`tor: the onion ${hostOf(onion)} of ${group.label} answered first; it serves this run's requests to it
@@ -42901,7 +42904,7 @@ async function routeFacilitatorsOverOnion(argv2, {
42901
42904
  }
42902
42905
  };
42903
42906
  }
42904
- var SITE_ONIONS, SITE_SPARE_ONIONS, PINNED_FACILITATOR_ONIONS, PINNED_SPARE_ONIONS, HISTORY_ONIONS, PINNED_HISTORY_ONIONS, HISTORY_PROBE_PATH, FACILITATOR_FLAGS, V3_ONION, DISCOVERY_TIMEOUT_MS, WARM_TIMEOUT_MS, RACE_TIMEOUT_MS, ROUTE_WAIT_MS, SPARE_AFTER_MS, SPARE_CAUSE, routedGroups, liveOnions, hostOf, noAnswer, routedOnions, routedOrigins, onionsOfOrigin, routesOverOnion, GLOBAL_DISPATCHER, onionDispatchers;
42907
+ var SITE_ONIONS, SITE_SPARE_ONIONS, PINNED_FACILITATOR_ONIONS, PINNED_SPARE_ONIONS, HISTORY_ONIONS, PINNED_HISTORY_ONIONS, HISTORY_PROBE_PATH, FACILITATOR_FLAGS, V3_ONION, DISCOVERY_TIMEOUT_MS, WARM_TIMEOUT_MS, RACE_TIMEOUT_MS, ROUTE_WAIT_MS, SPARE_AFTER_MS, SPARE_CAUSE, routedGroups, liveOnions, hostOf, noAnswer, routedOnions, routedOrigins, onionsOfOrigin, routesOverOnion, firstRaces, firstOnionRace, GLOBAL_DISPATCHER, onionDispatchers;
42905
42908
  var init_facilitatorOnion = __esm({
42906
42909
  "wallet/src/net/facilitatorOnion.mjs"() {
42907
42910
  "use strict";
@@ -42951,6 +42954,11 @@ var init_facilitatorOnion = __esm({
42951
42954
  routedOrigins = /* @__PURE__ */ new Map();
42952
42955
  onionsOfOrigin = (origin) => routedOrigins.get(origin) ?? PINNED_FACILITATOR_ONIONS[origin] ?? [];
42953
42956
  routesOverOnion = (origin) => routedOrigins.has(origin);
42957
+ firstRaces = /* @__PURE__ */ new Map();
42958
+ firstOnionRace = (origin) => {
42959
+ const race = firstRaces.get(origin);
42960
+ return race === void 0 ? void 0 : { ...race };
42961
+ };
42954
42962
  GLOBAL_DISPATCHER = /* @__PURE__ */ Symbol.for("undici.globalDispatcher.1");
42955
42963
  onionDispatchers = /* @__PURE__ */ new Map();
42956
42964
  }
@@ -58471,7 +58479,8 @@ async function loadOrExtendFinalizedP03History({
58471
58479
  fallbacks += 1;
58472
58480
  }
58473
58481
  let laggingRetries = 0;
58474
- for (let laggingTry = 0; cached; laggingTry += 1) {
58482
+ let cursorRetry;
58483
+ for (let attempt = 0; cached; attempt += 1) {
58475
58484
  try {
58476
58485
  const extended = await extendFromCache({
58477
58486
  connection,
@@ -58484,11 +58493,12 @@ async function loadOrExtendFinalizedP03History({
58484
58493
  historySource,
58485
58494
  forceRead,
58486
58495
  // A retry reads the pool again: the first read may be the one that lagged (stamp review).
58487
- liveRead: laggingTry === 0 ? liveRead : void 0
58496
+ liveRead: attempt === 0 ? liveRead : void 0
58488
58497
  });
58489
58498
  await beforePersist?.(extended);
58490
58499
  await persistCache(cache, extended, programIdBase58, poolBase58);
58491
58500
  remember(extended);
58501
+ if (cursorRetry === "running") markPhase("extension-retry-ok");
58492
58502
  return {
58493
58503
  report: extended.report,
58494
58504
  mode: extended.mode,
@@ -58498,11 +58508,22 @@ async function loadOrExtendFinalizedP03History({
58498
58508
  ...extended.window ? { window: extended.window } : {}
58499
58509
  };
58500
58510
  } catch (error) {
58511
+ if (cursorRetry === void 0 && /^p03_history_cursor_exhausted/.test(String(error?.message))) {
58512
+ cursorRetry = "running";
58513
+ onEvent("extension_retry", error);
58514
+ markPhase("extension-retry-start");
58515
+ await new Promise((resolve38) => setTimeout(resolve38, EXTENSION_CURSOR_RETRY_MS));
58516
+ continue;
58517
+ }
58518
+ if (cursorRetry === "running") {
58519
+ cursorRetry = "done";
58520
+ markPhase("extension-retry-failed");
58521
+ }
58501
58522
  onEvent("extension_failed", error);
58502
58523
  if (isProgramDataIdentityError(error)) throw error;
58503
- if (isLaggingNodeRpcError(error) && laggingTry < EXTENSION_LAGGING_RETRY_MS.length) {
58524
+ if (isLaggingNodeRpcError(error) && laggingRetries < EXTENSION_LAGGING_RETRY_MS.length) {
58504
58525
  laggingRetries += 1;
58505
- await new Promise((resolve38) => setTimeout(resolve38, EXTENSION_LAGGING_RETRY_MS[laggingTry]));
58526
+ await new Promise((resolve38) => setTimeout(resolve38, EXTENSION_LAGGING_RETRY_MS[laggingRetries - 1]));
58506
58527
  continue;
58507
58528
  }
58508
58529
  fallbacks += 1;
@@ -58888,7 +58909,7 @@ async function persistCache(cache, { report, entries: walked, attestation, marks
58888
58909
  ...attestation ? { attestation } : {}
58889
58910
  });
58890
58911
  }
58891
- var import_web398, EXTENSION_LAGGING_RETRY_MS, PAGE_SIZE2, LAST_REPORTS, sameMark, HISTORY_ROUND_BUCKET, HISTORY_WARM_FRESH_MS, runBufferLists;
58912
+ var import_web398, EXTENSION_LAGGING_RETRY_MS, EXTENSION_CURSOR_RETRY_MS, PAGE_SIZE2, LAST_REPORTS, sameMark, HISTORY_ROUND_BUCKET, HISTORY_WARM_FRESH_MS, runBufferLists;
58892
58913
  var init_incremental = __esm({
58893
58914
  "wallet/src/history/incremental.mjs"() {
58894
58915
  "use strict";
@@ -58897,6 +58918,7 @@ var init_incremental = __esm({
58897
58918
  init_walk();
58898
58919
  init_phaseTiming();
58899
58920
  EXTENSION_LAGGING_RETRY_MS = [1e3, 2e3];
58921
+ EXTENSION_CURSOR_RETRY_MS = 2e3;
58900
58922
  PAGE_SIZE2 = 1e3;
58901
58923
  LAST_REPORTS = /* @__PURE__ */ new WeakMap();
58902
58924
  sameMark = (cached, live) => cached === void 0 || cached === live;
@@ -64273,6 +64295,7 @@ var init_errorCodes = __esm({
64273
64295
  "exit_policy_values_invalid",
64274
64296
  "exit_proof_tools_invalid",
64275
64297
  "extension_failed",
64298
+ "extension_retry",
64276
64299
  "max_delay_invalid",
64277
64300
  "max_delay_minutes",
64278
64301
  "no_anchor",
@@ -95977,7 +96000,7 @@ function withSellerResource(xPayment, record) {
95977
96000
  return patched;
95978
96001
  }
95979
96002
  function floatFetch(base, seen) {
95980
- const wrapper = async (target, init = {}) => {
96003
+ const wrapper2 = async (target, init = {}) => {
95981
96004
  const response = await base(target, floatInit(init));
95982
96005
  const paid = Object.keys(init.headers ?? {}).some((name) => name.toLowerCase() === "payment-signature");
95983
96006
  if (paid || response.status === 402 || response.status < 400) return response;
@@ -95999,7 +96022,7 @@ function floatFetch(base, seen) {
95999
96022
  };
96000
96023
  return new Response(null, { status: 400 });
96001
96024
  };
96002
- return Object.defineProperty(wrapper, "baseFetch", { value: base });
96025
+ return Object.defineProperty(wrapper2, "baseFetch", { value: base });
96003
96026
  }
96004
96027
  function floatRefusalError(refusal3, record) {
96005
96028
  const extra = {
@@ -105384,7 +105407,8 @@ async function downloadSet({ fetchImpl, base, entries, budget, onFile, onBytes =
105384
105407
  } }) {
105385
105408
  const stop3 = new AbortController();
105386
105409
  const files = entries.map((entry) => ({ entry, url: new URL(entry.path, base).href, label: `the proof-tool file ${entry.path}`, buffer: void 0, left: 0 }));
105387
- const queue = files.map((file) => ({ file, start: 0, end: RANGE_BYTES - 1, head: true, attempts: 0 })).sort((x, y) => Number(y.file.entry.path.endsWith(".params")) - Number(x.file.entry.path.endsWith(".params")));
105410
+ const rank = (file) => file.entry.path === "proof-tools.json" ? 2 : file.entry.path.endsWith(".params") ? 1 : 0;
105411
+ const queue = files.map((file) => ({ file, start: 0, end: RANGE_BYTES - 1, head: true, attempts: 0 })).sort((x, y) => rank(y.file) - rank(x.file));
105388
105412
  const inFlight = /* @__PURE__ */ new Set();
105389
105413
  let firstError;
105390
105414
  let filesLeft = files.length;
@@ -105581,12 +105605,17 @@ async function installProofTools({
105581
105605
  onProgress = () => {
105582
105606
  },
105583
105607
  progressLine = (text3) => process.stderr.write(text3),
105584
- progressEveryMs = PROGRESS_EVERY_MS
105608
+ progressEveryMs = PROGRESS_EVERY_MS,
105609
+ onFileWritten = () => {
105610
+ },
105611
+ mark = () => {
105612
+ }
105585
105613
  }) {
105586
105614
  const { dir, sumsSha256 } = expected;
105587
105615
  if (!HEX643.test(String(sumsSha256)) || dir !== sumsSha256.slice(0, 8)) throw fail26("setup_release_invalid", "the expected proof-tool set is not a 64-hex list hash");
105588
105616
  const folder = join21(toolsRoot, dir);
105589
105617
  if (existsSync(folder) && verifyToolsFolder(folder, sumsSha256)) {
105618
+ mark("present");
105590
105619
  return Object.freeze({ dir, sumsSha256, folder, downloaded: 0, ...toolPaths(folder) });
105591
105620
  }
105592
105621
  const base = new URL(`/proof-tools/${dir}/`, facilitator);
@@ -105594,6 +105623,7 @@ async function installProofTools({
105594
105623
  if (sha2569(sums) !== sumsSha256) {
105595
105624
  throw fail26("setup_sums_mismatch", "the downloaded SHA256SUMS does not have the pinned SHA-256, so no proof tool was downloaded");
105596
105625
  }
105626
+ mark("sums");
105597
105627
  const entries = parseSums(sums.toString("utf8"));
105598
105628
  const partial = `${folder}.partial`;
105599
105629
  for (const entry of entries) {
@@ -105627,14 +105657,22 @@ async function installProofTools({
105627
105657
  let bytesDone = 0;
105628
105658
  let downloaded = 0;
105629
105659
  const budget = { left: LIMITS.total };
105660
+ let hashMs = 0;
105630
105661
  const write = (entry, bytes2) => {
105631
105662
  const target = localPath(partial, entry.path);
105632
- if (sha2569(bytes2) !== entry.sha256) {
105663
+ const hashStart = Date.now();
105664
+ const hash12 = sha2569(bytes2);
105665
+ hashMs += Date.now() - hashStart;
105666
+ if (hash12 !== entry.sha256) {
105633
105667
  throw fail26("setup_file_hash_mismatch", `the proof-tool file ${entry.path} does not have the SHA-256 that SHA256SUMS lists, so it was not kept; rerun setup`);
105634
105668
  }
105635
105669
  mkdirSync(dirname20(target), { recursive: true, mode: 448 });
105636
105670
  writeFileSync(target, bytes2, { flag: "wx", mode: 384 });
105637
105671
  if (executable(entry.path)) chmodSync(target, 493);
105672
+ try {
105673
+ onFileWritten({ path: entry.path, file: target });
105674
+ } catch {
105675
+ }
105638
105676
  };
105639
105677
  for (const { entry, bytes: bytes2 } of kept) {
105640
105678
  write(entry, bytes2);
@@ -105668,20 +105706,35 @@ async function installProofTools({
105668
105706
  }, progressEveryMs);
105669
105707
  ticker.unref?.();
105670
105708
  }
105709
+ let quarter = 0;
105710
+ const markQuarters = () => {
105711
+ const share = totalBytes !== void 0 && totalBytes > 0 ? (keptBytes + arrived) / totalBytes : (kept.length + downloaded) / entries.length;
105712
+ while (quarter < 4 && share >= (quarter + 1) / 4) {
105713
+ quarter += 1;
105714
+ mark(`download-${quarter * 25}`);
105715
+ }
105716
+ };
105717
+ mark("download-start", `f${missing.length}_of_${entries.length}`);
105671
105718
  try {
105672
105719
  await downloadSet({ fetchImpl, base, entries: missing, budget, onBytes: (count2) => {
105673
105720
  arrived += count2;
105721
+ markQuarters();
105674
105722
  }, onFile: (entry, bytes2) => {
105675
105723
  write(entry, bytes2);
105676
105724
  bytesDone += bytes2.length;
105677
105725
  downloaded += 1;
105726
+ mark("file", `f${kept.length + downloaded}_of_${entries.length}`);
105678
105727
  onProgress({ filesDone: kept.length + downloaded, filesTotal: entries.length, bytesDone });
105679
105728
  } });
105680
105729
  } finally {
105681
105730
  clearInterval(ticker);
105682
105731
  }
105732
+ if (quarter < 4) mark("download-100");
105733
+ mark("file-hashes", `ms${hashMs}`);
105683
105734
  writeFileSync(join21(partial, "SHA256SUMS"), sums, { flag: "wx", mode: 384 });
105735
+ mark("hash-check-start");
105684
105736
  if (!verifyToolsFolder(partial, sumsSha256)) throw fail26("setup_file_hash_mismatch", "the downloaded proof-tools folder did not check out on disk; rerun setup");
105737
+ mark("hash-check-end");
105685
105738
  if (existsSync(folder)) rmSync(folder, { recursive: true, force: true });
105686
105739
  renameSync(partial, folder);
105687
105740
  return Object.freeze({ dir, sumsSha256, folder, downloaded, ...toolPaths(folder) });
@@ -106231,6 +106284,18 @@ function facilitatorAnchor(origin, fetchImpl = fetch) {
106231
106284
  fail29(`anchor_refused_${response.status}`);
106232
106285
  };
106233
106286
  }
106287
+ function markedAnchorRequest(requestAnchor) {
106288
+ return async () => {
106289
+ markPhase("anchor-request-start");
106290
+ try {
106291
+ await requestAnchor();
106292
+ markPhase("anchor-request-done");
106293
+ } catch (error) {
106294
+ markPhase("anchor-request-done", "refused");
106295
+ throw error;
106296
+ }
106297
+ };
106298
+ }
106234
106299
  async function exitWhenAnchored(run5, { now = Date.now, sleep: sleep6 = (ms) => new Promise((resolve38) => setTimeout(resolve38, ms)), ring } = {}) {
106235
106300
  const deadline = now() + EXIT_ANCHOR_WAIT_MS;
106236
106301
  for (; ; ) {
@@ -106245,7 +106310,9 @@ async function exitWhenAnchored(run5, { now = Date.now, sleep: sleep6 = (ms) =>
106245
106310
  if (start + waitMs > deadline) throw error;
106246
106311
  const before = subAnchors ? await readRingBefore(ring, start) : void 0;
106247
106312
  progress(`your self-payment's note is spendable after the next pool anchor at ${new Date(anchorAt).toISOString().slice(11, 19)}Z; waiting ${Math.ceil(waitMs / 1e3)} s (nothing was signed for the exit): ${anchorWaitText(start)}; the exit then runs by itself`);
106313
+ markPhase("anchor-wait-start");
106248
106314
  await sleepForAnchor(waitMs, { ring, before, now, sleep: sleep6 });
106315
+ markPhase("anchor-wait-done");
106249
106316
  }
106250
106317
  }
106251
106318
  }
@@ -106452,6 +106519,7 @@ var init_cli2 = __esm({
106452
106519
  init_privateSend();
106453
106520
  init_promised();
106454
106521
  init_usdcWords();
106522
+ init_phaseTiming();
106455
106523
  USAGE2 = "node --import tsx wallet/src/unshield/cli.mjs --wallet <encrypted-file> --passphrase-file <file> [--rpc-file <file>] --payer-proof-tools <manifest> --exit-proof-tools <manifest> --profile <public-profile.json> --program <address> --facilitator <https-origin> --unshield-id <id> --amount <atomic> --to <token-account> --recipient-owner <pubkey> [--history-rpc <own|url>] [--parts <1-8>] [--max-delay-minutes <0-60>]";
106456
106524
  REQUIRED2 = [
106457
106525
  "wallet",
@@ -117330,7 +117398,7 @@ async function runUnshield({
117330
117398
  recipientOwner: owner.toBase58(),
117331
117399
  allowForeignRecipient: true,
117332
117400
  relaySubmit: facilitatorExitRelay(facilitatorOrigin2),
117333
- requestAnchor: facilitatorAnchor(facilitatorOrigin2),
117401
+ requestAnchor: markedAnchorRequest(facilitatorAnchor(facilitatorOrigin2)),
117334
117402
  deps: { walkHistory: walk(exitProofTools.deploymentIdentity) }
117335
117403
  }), { ring: { connection: session.connection, pool: store.state.pool } }));
117336
117404
  mark("unshield-exited");
@@ -117390,7 +117458,7 @@ async function runDirectExit({
117390
117458
  recipientOwner: owner.toBase58(),
117391
117459
  allowForeignRecipient: true,
117392
117460
  relaySubmit: facilitatorExitRelay(facilitatorOrigin2),
117393
- requestAnchor: facilitatorAnchor(facilitatorOrigin2),
117461
+ requestAnchor: markedAnchorRequest(facilitatorAnchor(facilitatorOrigin2)),
117394
117462
  deps: { walkHistory: walk(exitProofTools.deploymentIdentity), proveExit }
117395
117463
  }), { ring: { connection: session.connection, pool: store.state.pool } }));
117396
117464
  } catch (error) {
@@ -146364,7 +146432,7 @@ init_cli();
146364
146432
  init_floatPay();
146365
146433
  import { randomBytes as randomBytes33 } from "node:crypto";
146366
146434
  import { dirname as dirname29, join as join36, resolve as resolve37 } from "node:path";
146367
- import { spawn as spawn6 } from "node:child_process";
146435
+ import { spawn as spawn7 } from "node:child_process";
146368
146436
  import { fileURLToPath as fileURLToPath22 } from "node:url";
146369
146437
 
146370
146438
  // wallet/src/fetch/index.mjs
@@ -146387,6 +146455,8 @@ init_recoveryFile();
146387
146455
  init_config2();
146388
146456
  init_proofTools();
146389
146457
  init_proxy();
146458
+ init_facilitatorOnion();
146459
+ init_timing();
146390
146460
  init_migration();
146391
146461
  init_successions();
146392
146462
  init_chain2();
@@ -146512,10 +146582,23 @@ function readPassphrase(path, access) {
146512
146582
  }
146513
146583
  async function runSetup(options, deps = {}) {
146514
146584
  const home = resolve26(options.home);
146515
- const onStage = options.onStage ?? (() => {
146516
- });
146517
146585
  const now = deps.now ?? (() => /* @__PURE__ */ new Date());
146518
146586
  const warnings = [];
146587
+ const setupStartedAt = Date.now();
146588
+ const heldMarks = [];
146589
+ let writeMark;
146590
+ const mark = (phase, outcome, at = Date.now()) => {
146591
+ try {
146592
+ if (writeMark) writeMark(phase, outcome, at);
146593
+ else heldMarks.push([phase, outcome, at]);
146594
+ } catch {
146595
+ }
146596
+ };
146597
+ const onStage = (stage, detail) => {
146598
+ if (stage !== "proof-tools" || detail === void 0) mark(`stage-${stage}`);
146599
+ (options.onStage ?? (() => {
146600
+ }))(stage, detail);
146601
+ };
146519
146602
  onStage("platform");
146520
146603
  const platform = proverPlatform({ platform: deps.platform, hasWsl: deps.hasWsl });
146521
146604
  if (!platform.ok) throw fail40(platform.code, platform.detail);
@@ -146539,6 +146622,10 @@ async function runSetup(options, deps = {}) {
146539
146622
  } catch (error) {
146540
146623
  releaseError = error;
146541
146624
  }
146625
+ mark("release-read", release ? void 0 : "failed");
146626
+ const race = firstOnionRace(facilitator);
146627
+ if (race !== void 0) mark("onion-race-start", void 0, race.startedAt);
146628
+ if (race?.endedAt !== void 0) mark("onion-race-end", race.answered ? "answered" : "none", race.endedAt);
146542
146629
  let identity;
146543
146630
  if (release) {
146544
146631
  expected = await trustServedSet({ home, facilitator, release, expected, fetchImpl: deps.fetchImpl ?? fetch });
@@ -146708,19 +146795,56 @@ async function runSetup(options, deps = {}) {
146708
146795
  }
146709
146796
  const keep = old?.proofToolsRelease && old.pool === identity.pool ? { proofTools: old.proofTools, exitProofTools: old.exitProofTools, profile: old.profile, proofToolsRelease: old.proofToolsRelease } : {};
146710
146797
  writeSetupConfig(home, { ...base, ...keep });
146798
+ try {
146799
+ writeMark = (deps.timingLog ?? createTimingLog)(`${walletFile}.timing.log`, { component: "setup" }).start({ startedAt: setupStartedAt });
146800
+ for (const [phase, outcome, at] of heldMarks.splice(0)) writeMark(phase, outcome, at);
146801
+ } catch {
146802
+ }
146711
146803
  onStage("proof-tools");
146712
146804
  let tools;
146713
- if (release) {
146714
- tools = await installProofTools({
146715
- facilitator,
146716
- toolsRoot: join30(home, "proof-tools"),
146717
- expected,
146718
- fetchImpl: deps.fetchImpl,
146719
- onProgress: (progress3) => onStage("proof-tools", progress3)
146805
+ let warm;
146806
+ let warmCode;
146807
+ const warmAllowed = typeof deps.startWarm === "function" && !(tor && !inTorRun());
146808
+ const startWarm = (proofToolsPath) => {
146809
+ if (warm !== void 0 || !warmAllowed) return;
146810
+ try {
146811
+ warm = deps.startWarm({ walletFile, passphrase: passphrase2, proofToolsPath, program: identity.program, facilitator }) ?? null;
146812
+ } catch {
146813
+ warm = null;
146814
+ }
146815
+ if (!warm) return;
146816
+ mark("attest-start");
146817
+ warm.exited.then((code2) => {
146818
+ if (warmCode !== void 0) return;
146819
+ warmCode = code2;
146820
+ mark("attest-end", code2 === 0 ? "ok" : `exit${code2}`);
146821
+ }, () => {
146720
146822
  });
146721
- } else {
146722
- const folder = join30(home, "proof-tools", old.proofToolsRelease.dir);
146723
- tools = { ...old.proofToolsRelease, folder, downloaded: 0, ...toolPaths(folder) };
146823
+ };
146824
+ try {
146825
+ if (release) {
146826
+ tools = await installProofTools({
146827
+ facilitator,
146828
+ toolsRoot: join30(home, "proof-tools"),
146829
+ expected,
146830
+ fetchImpl: deps.fetchImpl,
146831
+ onProgress: (progress3) => onStage("proof-tools", progress3),
146832
+ mark: (phase, outcome) => mark(`tools-${phase}`, outcome),
146833
+ onFileWritten: ({ path, file }) => {
146834
+ if (path === "proof-tools.json") startWarm(file);
146835
+ }
146836
+ });
146837
+ } else {
146838
+ const folder = join30(home, "proof-tools", old.proofToolsRelease.dir);
146839
+ tools = { ...old.proofToolsRelease, folder, downloaded: 0, ...toolPaths(folder) };
146840
+ }
146841
+ } finally {
146842
+ if (warm && warmCode === void 0) {
146843
+ warmCode = "stopped";
146844
+ mark("attest-end", "stopped");
146845
+ await Promise.resolve().then(() => warm.stop()).catch(() => {
146846
+ });
146847
+ }
146724
146848
  }
146725
146849
  onStage("config");
146726
146850
  const config = {
@@ -146744,8 +146868,198 @@ async function runSetup(options, deps = {}) {
146744
146868
  passphraseGenerated,
146745
146869
  proofTools: { dir: tools.dir, downloaded: tools.downloaded, folder: tools.folder },
146746
146870
  platform: platform.wsl ? "windows+wsl" : "linux",
146747
- warnings
146871
+ warnings,
146872
+ ...warmCode === 0 ? { firstBalanceReady: true } : {}
146873
+ });
146874
+ }
146875
+
146876
+ // wallet/src/setup/setupWarm.mjs
146877
+ import { spawn as spawn5 } from "node:child_process";
146878
+
146879
+ // wallet/src/history/keepWarm.mjs
146880
+ init_fs();
146881
+ init_chain2();
146882
+ init_proxy();
146883
+ init_recoveredPayment();
146884
+ init_rpcDefault();
146885
+ init_store();
146886
+ init_incremental();
146887
+ init_walletHistory();
146888
+ import { spawn as spawn4 } from "node:child_process";
146889
+ import { randomInt as randomInt7 } from "node:crypto";
146890
+ import { resolve as resolve27 } from "node:path";
146891
+ var KEEP_WARM_PARENT_ENV = "SHINJUKU_KEEP_WARM_PARENT";
146892
+ var KEEP_WARM_ONCE_PARENT_ENV = "SHINJUKU_KEEP_WARM_ONCE_PARENT";
146893
+ function watchSetupParentPipe({ stdin = process.stdin, exit = (code2) => process.exit(code2) } = {}) {
146894
+ const parentGone = () => exit(1);
146895
+ for (const event of ["end", "close", "error"]) stdin.on(event, parentGone);
146896
+ stdin.resume();
146897
+ return () => {
146898
+ for (const event of ["end", "close", "error"]) stdin.off(event, parentGone);
146899
+ stdin.destroy();
146900
+ };
146901
+ }
146902
+ var KEEP_WARM_MIN_MS = 18e4;
146903
+ var KEEP_WARM_MAX_MS = 3e5;
146904
+ async function keepWarmOnce(values, { io, env = process.env }) {
146905
+ const started = Date.now();
146906
+ const walletPath2 = resolve27(values.get("--wallet"));
146907
+ const passphrase2 = assertPassphrase(values.has("--passphrase-file") ? readFileSync(resolve27(values.get("--passphrase-file")), "utf8").trim() : String(env.SHIELDED_WALLET_PASSPHRASE ?? ""));
146908
+ const store = openWalletStore(walletPath2, passphrase2);
146909
+ const connection = connect2(resolveRpcUrl2({
146910
+ rpcFile: values.get("--rpc-file"),
146911
+ origin: values.get("--memo-service"),
146912
+ readFile: (path) => readFileSync(resolve27(path), "utf8").trim()
146913
+ }).url, "finalized");
146914
+ const proofTools = loadP03PublicPaymentProofTools(resolve27(values.get("--proof-tools")));
146915
+ await loadWalletP03History({
146916
+ store,
146917
+ connection: connectSplit(connection, historyRpcUrl(values.get("--history-rpc"))),
146918
+ programId: values.get("--program"),
146919
+ pool: store.state.pool,
146920
+ deploymentIdentity: proofTools.deploymentIdentity,
146921
+ forceRead: true
146922
+ });
146923
+ io.err(`keep-warm: the pool history is current (${((Date.now() - started) / 1e3).toFixed(1)} s); a payment in the next ${HISTORY_WARM_FRESH_MS / 6e4} minutes reads no pool history while the pool does not move
146924
+ `);
146925
+ }
146926
+ async function keepWarmMain(args, values, { io, env = process.env, entry } = {}) {
146927
+ if (values.has("--once")) {
146928
+ await keepWarmOnce(values, { io, env });
146929
+ return 0;
146930
+ }
146931
+ if (typeof entry !== "string" || !entry) throw new Error("keep_warm_entry_missing");
146932
+ const proxy = childRunProxy(env);
146933
+ let stopped = false;
146934
+ let child;
146935
+ let wake;
146936
+ const stop3 = () => {
146937
+ stopped = true;
146938
+ child?.kill("SIGTERM");
146939
+ wake?.();
146940
+ };
146941
+ process.on("SIGINT", stop3);
146942
+ process.on("SIGTERM", stop3);
146943
+ if (env[KEEP_WARM_PARENT_ENV] === "1") {
146944
+ process.stdin.on("end", stop3);
146945
+ process.stdin.on("close", stop3);
146946
+ process.stdin.on("error", stop3);
146947
+ process.stdin.resume();
146948
+ }
146949
+ try {
146950
+ while (!stopped) {
146951
+ const code2 = await new Promise((done) => {
146952
+ child = spawn4(process.execPath, [...process.execArgv, entry, ...proxy.args, "keep-warm", ...args, "--once"], {
146953
+ env: proxy.env,
146954
+ stdio: ["ignore", "ignore", "inherit"],
146955
+ windowsHide: true
146956
+ });
146957
+ child.on("error", () => done(1));
146958
+ child.on("exit", (exitCode) => done(exitCode ?? 1));
146959
+ });
146960
+ child = void 0;
146961
+ if (stopped) break;
146962
+ if (code2 !== 0) io.err(`keep-warm: this refresh failed (exit ${code2}); the next one runs at its usual time
146963
+ `);
146964
+ const gap = randomInt7(KEEP_WARM_MIN_MS, KEEP_WARM_MAX_MS + 1);
146965
+ io.err(`keep-warm: next refresh in ${Math.round(gap / 1e3)} s (stop with Ctrl-C)
146966
+ `);
146967
+ await new Promise((done) => {
146968
+ const timer = setTimeout(done, gap);
146969
+ wake = () => {
146970
+ clearTimeout(timer);
146971
+ done();
146972
+ };
146973
+ });
146974
+ wake = void 0;
146975
+ }
146976
+ } finally {
146977
+ process.off("SIGINT", stop3);
146978
+ process.off("SIGTERM", stop3);
146979
+ }
146980
+ return 0;
146981
+ }
146982
+
146983
+ // wallet/src/setup/setupWarm.mjs
146984
+ init_proxy();
146985
+ var SETUP_WARM_STOP_WAIT_MS = 5e3;
146986
+ function killProcessTree(child, { platform = process.platform, run: run5 = spawn5 } = {}) {
146987
+ if (!Number.isSafeInteger(child?.pid)) return;
146988
+ if (platform === "win32") {
146989
+ try {
146990
+ const killer = run5("taskkill", ["/T", "/F", "/PID", String(child.pid)], { windowsHide: true, stdio: "ignore" });
146991
+ killer?.on?.("error", () => {
146992
+ });
146993
+ killer?.unref?.();
146994
+ } catch {
146995
+ }
146996
+ return;
146997
+ }
146998
+ try {
146999
+ child.kill("SIGTERM");
147000
+ } catch {
147001
+ }
147002
+ }
147003
+ function startSetupWarm({
147004
+ entry,
147005
+ walletFile,
147006
+ passphrase: passphrase2,
147007
+ passphraseEnv,
147008
+ proofToolsPath,
147009
+ program,
147010
+ facilitator,
147011
+ env = process.env,
147012
+ spawnImpl = spawn5,
147013
+ killTree = killProcessTree
147014
+ }) {
147015
+ const proxy = childRunProxy(env);
147016
+ const child = spawnImpl(process.execPath, [
147017
+ ...process.execArgv,
147018
+ entry,
147019
+ ...proxy.args,
147020
+ "keep-warm",
147021
+ "--once",
147022
+ "--wallet",
147023
+ walletFile,
147024
+ "--proof-tools",
147025
+ proofToolsPath,
147026
+ "--program",
147027
+ program,
147028
+ "--memo-service",
147029
+ facilitator
147030
+ ], {
147031
+ env: { ...proxy.env, [passphraseEnv]: passphrase2, [KEEP_WARM_ONCE_PARENT_ENV]: "1" },
147032
+ stdio: ["pipe", "ignore", "ignore"],
147033
+ windowsHide: true
146748
147034
  });
147035
+ let ended = false;
147036
+ const exited = new Promise((resolve38) => {
147037
+ child.on("error", () => {
147038
+ ended = true;
147039
+ resolve38(1);
147040
+ });
147041
+ child.on("exit", (code2) => {
147042
+ ended = true;
147043
+ resolve38(code2 ?? 1);
147044
+ });
147045
+ });
147046
+ child.stdin?.on?.("error", () => {
147047
+ });
147048
+ return {
147049
+ exited,
147050
+ async stop() {
147051
+ try {
147052
+ child.stdin?.end?.();
147053
+ } catch {
147054
+ }
147055
+ if (!ended) killTree(child);
147056
+ let timer;
147057
+ await Promise.race([exited, new Promise((resolve38) => {
147058
+ timer = setTimeout(resolve38, SETUP_WARM_STOP_WAIT_MS);
147059
+ })]);
147060
+ clearTimeout(timer);
147061
+ }
147062
+ };
146749
147063
  }
146750
147064
 
146751
147065
  // wallet/src/cli/shinjukuWallet.mjs
@@ -146777,7 +147091,7 @@ init_proxy();
146777
147091
  init_rpcDefault();
146778
147092
  init_secretFile();
146779
147093
  init_serviceUrl();
146780
- import { resolve as resolve27 } from "node:path";
147094
+ import { resolve as resolve28 } from "node:path";
146781
147095
  import { fileURLToPath as fileURLToPath19 } from "node:url";
146782
147096
  var USAGE3 = "shinjuku-wallet merge --wallet <encrypted-file> --passphrase-file <file> --program <address> [--dry-run] [--rpc-file <file>] --proof-tools <manifest> --profile <public-profile.json> --facilitator <https-origin> [--history-rpc <own|url>]";
146783
147097
  var VALUED = ["wallet", "passphrase-file", "program", "rpc-file", "proof-tools", "profile", "facilitator", "history-rpc"];
@@ -146820,8 +147134,8 @@ async function main5(args = process.argv.slice(2)) {
146820
147134
  const origin = dryRun ? void 0 : new URL(options.facilitator);
146821
147135
  if (origin && (origin.protocol !== "https:" && !isOnionOrigin(origin) || origin.pathname !== "/" || origin.search)) fail41("facilitator_origin_invalid");
146822
147136
  const historyUrl = historyRpcUrl(options["history-rpc"]);
146823
- const walletPath2 = resolve27(options.wallet);
146824
- const passphrase2 = assertPassphrase(readSecretText(resolve27(options["passphrase-file"]), "--passphrase-file"));
147137
+ const walletPath2 = resolve28(options.wallet);
147138
+ const passphrase2 = assertPassphrase(readSecretText(resolve28(options["passphrase-file"]), "--passphrase-file"));
146825
147139
  let release;
146826
147140
  try {
146827
147141
  release = await acquireWalletProcessLease(walletLockPath(walletPath2));
@@ -146840,13 +147154,13 @@ async function main5(args = process.argv.slice(2)) {
146840
147154
  const connection = connect2(resolveRpcUrl2({
146841
147155
  rpcFile: options["rpc-file"],
146842
147156
  origin: origin.origin,
146843
- readFile: (path) => readFileSync(resolve27(path), "utf8").trim()
147157
+ readFile: (path) => readFileSync(resolve28(path), "utf8").trim()
146844
147158
  }).url, "finalized");
146845
- const proofTools = loadP03PublicPaymentProofTools(resolve27(options["proof-tools"]));
147159
+ const proofTools = loadP03PublicPaymentProofTools(resolve28(options["proof-tools"]));
146846
147160
  steps = {
146847
147161
  connection,
146848
147162
  proofTools,
146849
- profile: JSON.parse(readFileSync(resolve27(options.profile), "utf8")),
147163
+ profile: JSON.parse(readFileSync(resolve28(options.profile), "utf8")),
146850
147164
  timing: createTimingLog(`${walletPath2}.timing.log`, { component: "payer" })
146851
147165
  };
146852
147166
  }
@@ -146944,7 +147258,7 @@ async function main5(args = process.argv.slice(2)) {
146944
147258
  await release();
146945
147259
  }
146946
147260
  }
146947
- if (process.argv[1] && resolve27(process.argv[1]) === fileURLToPath19(new URL("__bundled_source__/wallet/src/merge/cli.mjs", import.meta.url).href)) {
147261
+ if (process.argv[1] && resolve28(process.argv[1]) === fileURLToPath19(new URL("__bundled_source__/wallet/src/merge/cli.mjs", import.meta.url).href)) {
146948
147262
  main5().catch((error) => {
146949
147263
  console.error(describeCliErrorWithHint(error));
146950
147264
  process.exitCode = 1;
@@ -146953,7 +147267,7 @@ if (process.argv[1] && resolve27(process.argv[1]) === fileURLToPath19(new URL("_
146953
147267
 
146954
147268
  // wallet/src/item/buyItem.mjs
146955
147269
  init_fs();
146956
- import { resolve as resolve28 } from "node:path";
147270
+ import { resolve as resolve29 } from "node:path";
146957
147271
 
146958
147272
  // src/shared/blindVoucher.ts
146959
147273
  init_sha256();
@@ -147445,8 +147759,8 @@ async function main6(args = process.argv.slice(2)) {
147445
147759
  }
147446
147760
  if (REQUIRED3.some((key) => !options[key])) throw new Error("p03_item_cli_arguments_missing");
147447
147761
  const historyUrl = historyRpcUrl(options["history-rpc"]);
147448
- const walletPath2 = resolve28(options.wallet);
147449
- const passphrase2 = assertPassphrase(readSecretText(resolve28(options["passphrase-file"]), "--passphrase-file"));
147762
+ const walletPath2 = resolve29(options.wallet);
147763
+ const passphrase2 = assertPassphrase(readSecretText(resolve29(options["passphrase-file"]), "--passphrase-file"));
147450
147764
  const timing = createTimingLog(`${walletPath2}.timing.log`, { component: "payer" }).start({ startedAt: performance.timeOrigin });
147451
147765
  timing("process-start", void 0, performance.timeOrigin);
147452
147766
  if (proxyProvenAt() !== void 0) timing("proxy-proven", void 0, proxyProvenAt());
@@ -147463,15 +147777,15 @@ async function main6(args = process.argv.slice(2)) {
147463
147777
  const connection = connect2(resolveRpcUrl2({
147464
147778
  rpcFile: options["rpc-file"],
147465
147779
  origin: options["memo-service"],
147466
- readFile: (path) => readFileSync(resolve28(path), "utf8").trim()
147780
+ readFile: (path) => readFileSync(resolve29(path), "utf8").trim()
147467
147781
  }).url, "finalized");
147468
147782
  const earlySource = resolveHistorySource(connectSplit(connection, historyUrl), store.state.pool);
147469
147783
  if (earlySource.source === "pinned") earlySource.connection.historyRpcWarm?.();
147470
147784
  connection.getSlot("finalized").catch(() => {
147471
147785
  });
147472
- const proofTools = loadP03PublicPaymentProofTools(resolve28(options["proof-tools"]));
147786
+ const proofTools = loadP03PublicPaymentProofTools(resolve29(options["proof-tools"]));
147473
147787
  timing("proof-tools");
147474
- const playToken = options["play-token-file"] ? readFileSync(resolve28(options["play-token-file"]), "utf8").trim() : void 0;
147788
+ const playToken = options["play-token-file"] ? readFileSync(resolve29(options["play-token-file"]), "utf8").trim() : void 0;
147475
147789
  if (playToken !== void 0 && !/^sjp_[A-Za-z0-9_-]{16,200}$/.test(playToken)) throw new Error("p03_item_play_token_invalid");
147476
147790
  const walkHistory = async () => {
147477
147791
  const history = await loadWalletP03History({
@@ -147518,100 +147832,6 @@ async function main6(args = process.argv.slice(2)) {
147518
147832
  }
147519
147833
  }
147520
147834
 
147521
- // wallet/src/history/keepWarm.mjs
147522
- init_fs();
147523
- init_chain2();
147524
- init_proxy();
147525
- init_recoveredPayment();
147526
- init_rpcDefault();
147527
- init_store();
147528
- init_incremental();
147529
- init_walletHistory();
147530
- import { spawn as spawn4 } from "node:child_process";
147531
- import { randomInt as randomInt7 } from "node:crypto";
147532
- import { resolve as resolve29 } from "node:path";
147533
- var KEEP_WARM_PARENT_ENV = "SHINJUKU_KEEP_WARM_PARENT";
147534
- var KEEP_WARM_MIN_MS = 18e4;
147535
- var KEEP_WARM_MAX_MS = 3e5;
147536
- async function keepWarmOnce(values, { io, env = process.env }) {
147537
- const started = Date.now();
147538
- const walletPath2 = resolve29(values.get("--wallet"));
147539
- const passphrase2 = assertPassphrase(values.has("--passphrase-file") ? readFileSync(resolve29(values.get("--passphrase-file")), "utf8").trim() : String(env.SHIELDED_WALLET_PASSPHRASE ?? ""));
147540
- const store = openWalletStore(walletPath2, passphrase2);
147541
- const connection = connect2(resolveRpcUrl2({
147542
- rpcFile: values.get("--rpc-file"),
147543
- origin: values.get("--memo-service"),
147544
- readFile: (path) => readFileSync(resolve29(path), "utf8").trim()
147545
- }).url, "finalized");
147546
- const proofTools = loadP03PublicPaymentProofTools(resolve29(values.get("--proof-tools")));
147547
- await loadWalletP03History({
147548
- store,
147549
- connection: connectSplit(connection, historyRpcUrl(values.get("--history-rpc"))),
147550
- programId: values.get("--program"),
147551
- pool: store.state.pool,
147552
- deploymentIdentity: proofTools.deploymentIdentity,
147553
- forceRead: true
147554
- });
147555
- io.err(`keep-warm: the pool history is current (${((Date.now() - started) / 1e3).toFixed(1)} s); a payment in the next ${HISTORY_WARM_FRESH_MS / 6e4} minutes reads no pool history while the pool does not move
147556
- `);
147557
- }
147558
- async function keepWarmMain(args, values, { io, env = process.env, entry } = {}) {
147559
- if (values.has("--once")) {
147560
- await keepWarmOnce(values, { io, env });
147561
- return 0;
147562
- }
147563
- if (typeof entry !== "string" || !entry) throw new Error("keep_warm_entry_missing");
147564
- const proxy = childRunProxy(env);
147565
- let stopped = false;
147566
- let child;
147567
- let wake;
147568
- const stop3 = () => {
147569
- stopped = true;
147570
- child?.kill("SIGTERM");
147571
- wake?.();
147572
- };
147573
- process.on("SIGINT", stop3);
147574
- process.on("SIGTERM", stop3);
147575
- if (env[KEEP_WARM_PARENT_ENV] === "1") {
147576
- process.stdin.on("end", stop3);
147577
- process.stdin.on("close", stop3);
147578
- process.stdin.on("error", stop3);
147579
- process.stdin.resume();
147580
- }
147581
- try {
147582
- while (!stopped) {
147583
- const code2 = await new Promise((done) => {
147584
- child = spawn4(process.execPath, [...process.execArgv, entry, ...proxy.args, "keep-warm", ...args, "--once"], {
147585
- env: proxy.env,
147586
- stdio: ["ignore", "ignore", "inherit"],
147587
- windowsHide: true
147588
- });
147589
- child.on("error", () => done(1));
147590
- child.on("exit", (exitCode) => done(exitCode ?? 1));
147591
- });
147592
- child = void 0;
147593
- if (stopped) break;
147594
- if (code2 !== 0) io.err(`keep-warm: this refresh failed (exit ${code2}); the next one runs at its usual time
147595
- `);
147596
- const gap = randomInt7(KEEP_WARM_MIN_MS, KEEP_WARM_MAX_MS + 1);
147597
- io.err(`keep-warm: next refresh in ${Math.round(gap / 1e3)} s (stop with Ctrl-C)
147598
- `);
147599
- await new Promise((done) => {
147600
- const timer = setTimeout(done, gap);
147601
- wake = () => {
147602
- clearTimeout(timer);
147603
- done();
147604
- };
147605
- });
147606
- wake = void 0;
147607
- }
147608
- } finally {
147609
- process.off("SIGINT", stop3);
147610
- process.off("SIGTERM", stop3);
147611
- }
147612
- return 0;
147613
- }
147614
-
147615
147835
  // wallet/src/cli/shinjukuWallet.mjs
147616
147836
  init_cli3();
147617
147837
 
@@ -149809,7 +150029,7 @@ init_deposit();
149809
150029
  init_fs();
149810
150030
  init_balance();
149811
150031
  init_deposit();
149812
- import { spawn as spawn5 } from "node:child_process";
150032
+ import { spawn as spawn6 } from "node:child_process";
149813
150033
  import { randomBytes as randomBytes25, randomInt as randomInt9 } from "node:crypto";
149814
150034
  import { tmpdir as tmpdir4 } from "node:os";
149815
150035
  import { join as join33, resolve as resolve31 } from "node:path";
@@ -150064,7 +150284,7 @@ async function runStep(ctx, argv2) {
150064
150284
  const file = join33(ctx.tempDir, `step-${randomBytes25(8).toString("hex")}.json`);
150065
150285
  const held = [];
150066
150286
  let last;
150067
- const proc = spawn5(process.execPath, [...process.execArgv, ctx.entry, ...ctx.proxyArgs, ...argv2], {
150287
+ const proc = spawn6(process.execPath, [...process.execArgv, ctx.entry, ...ctx.proxyArgs, ...argv2], {
150068
150288
  env: { ...ctx.childEnv, [RESULT_FILE_ENV]: file },
150069
150289
  stdio: ["ignore", "ignore", "pipe"],
150070
150290
  windowsHide: true
@@ -151557,7 +151777,7 @@ function startKeepWarm(options, env = process.env) {
151557
151777
  options.memoServiceUrl,
151558
151778
  ...options.historyRpc ? ["--history-rpc", options.historyRpc] : []
151559
151779
  ];
151560
- const child = spawn6(process.execPath, [...process.execArgv, CLI_FILE, ...proxy.args, ...warmArgs], {
151780
+ const child = spawn7(process.execPath, [...process.execArgv, CLI_FILE, ...proxy.args, ...warmArgs], {
151561
151781
  env: {
151562
151782
  ...proxy.env,
151563
151783
  [PASSPHRASE_ENV2]: options.passphrase,
@@ -151577,6 +151797,11 @@ function startKeepWarm(options, env = process.env) {
151577
151797
  });
151578
151798
  return child;
151579
151799
  }
151800
+ function setupWarmStarter(deps) {
151801
+ if (deps.startSetupWarm) return deps.startSetupWarm;
151802
+ if (!process.argv[1] || resolve37(process.argv[1]) !== CLI_FILE) return void 0;
151803
+ return (options) => startSetupWarm({ ...options, entry: CLI_FILE, passphraseEnv: PASSPHRASE_ENV2, env: deps.env ?? process.env });
151804
+ }
151580
151805
  function mcpServerOptions(values, deps) {
151581
151806
  const options = payerSessionOptions(values, deps);
151582
151807
  let pool2;
@@ -152143,7 +152368,7 @@ Copy it to two offline places now; it is the only way to restore this wallet.
152143
152368
  lastStage = stage;
152144
152369
  io.err(`${STAGE_TEXT[stage]}...
152145
152370
  `);
152146
- } }, setupDependencies(deps), inference);
152371
+ } }, { ...setupDependencies(deps), startWarm: setupWarmStarter(deps) }, inference);
152147
152372
  } catch (error) {
152148
152373
  if (/^(setup_[a-z_]+|secret_file_utf16): /.test(String(error?.message))) throw new PublicFailure(error.message);
152149
152374
  throw error;
@@ -152154,7 +152379,9 @@ Copy it to two offline places now; it is the only way to restore this wallet.
152154
152379
  ` limits ${capText(summary.caps.maxPayment, usdcText3)} per payment, ${capText(summary.caps.maxSession, usdcText3)} in any 24 hours, ${capText(summary.caps.maxTotal, usdcText3)} for the life of the wallet${summary.tor ? "; Tor on" : ""}`,
152155
152380
  ` config ${summary.configPath}`,
152156
152381
  ` passphrase ${summary.passphraseFile}${summary.passphraseGenerated ? " (a new random passphrase; only you can read the file; it is never printed)" : ""}`,
152157
- ` proof tools ${summary.proofTools.folder} (${summary.proofTools.downloaded ? `${summary.proofTools.downloaded} files downloaded, every hash checked` : "already here, every hash checked"})`
152382
+ ` proof tools ${summary.proofTools.folder} (${summary.proofTools.downloaded ? `${summary.proofTools.downloaded} files downloaded, every hash checked` : "already here, every hash checked"})`,
152383
+ // The setup warm ended well (setup/setupWarm.mjs); nothing is said when it did not.
152384
+ ...summary.firstBalanceReady ? [" balance prepared during setup: your first balance after a deposit shows sooner"] : []
152158
152385
  ];
152159
152386
  if (summary.wallet.status === "created") {
152160
152387
  lines.push(
@@ -155254,8 +155481,11 @@ ${sellerLine}${landedLine}${whyLine}${ambiguousLine}${blockingLine}${hint ? `hin
155254
155481
  // wallet/bin/shinjuku-wallet.mjs
155255
155482
  init_proxy();
155256
155483
  var argv = process.argv.slice(2);
155484
+ var wrapper = runNetworkMode() === null && (argv.includes("--tor") || argv.includes("--proxy"));
155485
+ var stopSetupWatch = process.env[KEEP_WARM_ONCE_PARENT_ENV] === "1" && !wrapper ? watchSetupParentPipe() : void 0;
155257
155486
  var mcpRefused = async (options) => (await Promise.resolve().then(() => (init_torMissingMcp(), torMissingMcp_exports))).serveTorMissingMcp(options);
155258
155487
  var code = isHelpRequest(argv) ? await runShinjukuWallet(argv) : await proxyEntry(argv, runShinjukuWallet, { mcpRefused });
155488
+ stopSetupWatch?.();
155259
155489
  process.exitCode = code;
155260
155490
  if (code !== 0) setTimeout(() => process.exit(code), 2e3).unref();
155261
155491
  else if (mcpServerEndedHere()) setTimeout(() => process.exit(code), 0).unref();