shinjuku-shielded 0.3.67 → 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": "4d9b6de27c68f9fb53c414d063679fde5a62eb26a2a46f13bebfde9a4d74b042",
5
- "bytes": 12186827,
6
- "sourceCommit": "fb9acd3df41de84537c71fc80913c41a37568bf4",
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-22T12:44:47.481Z"
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.67",
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": "4d9b6de2",
7
- "shinjukuSha256": "4d9b6de27c68f9fb53c414d063679fde5a62eb26a2a46f13bebfde9a4d74b042",
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",
@@ -65046,6 +65069,8 @@ var init_errorCodes = __esm({
65046
65069
  "quote_commitment_mismatch",
65047
65070
  "quote_expired",
65048
65071
  "quote_expired_before_submission",
65072
+ // An idle float merge gave way to a buyer payment before its send (payResource deps.yieldBeforeSend).
65073
+ "yielded_before_submission",
65049
65074
  "quote_life_short_requote",
65050
65075
  "quote_file_invalid_json",
65051
65076
  "quote_file_required",
@@ -95975,7 +96000,7 @@ function withSellerResource(xPayment, record) {
95975
96000
  return patched;
95976
96001
  }
95977
96002
  function floatFetch(base, seen) {
95978
- const wrapper = async (target, init = {}) => {
96003
+ const wrapper2 = async (target, init = {}) => {
95979
96004
  const response = await base(target, floatInit(init));
95980
96005
  const paid = Object.keys(init.headers ?? {}).some((name) => name.toLowerCase() === "payment-signature");
95981
96006
  if (paid || response.status === 402 || response.status < 400) return response;
@@ -95997,7 +96022,7 @@ function floatFetch(base, seen) {
95997
96022
  };
95998
96023
  return new Response(null, { status: 400 });
95999
96024
  };
96000
- return Object.defineProperty(wrapper, "baseFetch", { value: base });
96025
+ return Object.defineProperty(wrapper2, "baseFetch", { value: base });
96001
96026
  }
96002
96027
  function floatRefusalError(refusal3, record) {
96003
96028
  const extra = {
@@ -98020,6 +98045,10 @@ async function payResourceOnce({
98020
98045
  walkHistory: finality.walkHistory
98021
98046
  });
98022
98047
  mark("submit-refused-checked");
98048
+ if (record.refused === void 0 && deps.yieldBeforeSend?.() === true) {
98049
+ mark("submit-yielded");
98050
+ fail19("yielded_before_submission");
98051
+ }
98023
98052
  }
98024
98053
  const landed = record.refused?.landed !== void 0;
98025
98054
  const shortHeader = record.state !== "submitted" && !landed ? await deps.memoUpload?.shortHeader(record.paymentHeader) : void 0;
@@ -102123,7 +102152,7 @@ function createAnchorReader({ connection, profile }) {
102123
102152
  if (requireCapacity && (state.terminal || state.paymentCount >= state.policy.maxPayments)) fail21("pool_not_ready");
102124
102153
  const chainTimestamp = clock2.data.readBigInt64LE(32);
102125
102154
  if (chainTimestamp < 0n) fail21("chain_clock_invalid");
102126
- const anchors = state.anchors.map((a) => ({ epoch: a.epoch, anchorIndex: a.index, anchorRoot: bigint(a.root) }));
102155
+ const anchors = state.validAnchors.map((a) => ({ epoch: a.epoch, anchorIndex: a.index, anchorRoot: bigint(a.root) }));
102127
102156
  const current = anchors.find((a) => a.epoch === chainTimestamp / 300n);
102128
102157
  if (requireCapacity && !current) fail21("anchor_not_ready");
102129
102158
  const selected = current ?? anchors[0];
@@ -105378,7 +105407,8 @@ async function downloadSet({ fetchImpl, base, entries, budget, onFile, onBytes =
105378
105407
  } }) {
105379
105408
  const stop3 = new AbortController();
105380
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 }));
105381
- 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));
105382
105412
  const inFlight = /* @__PURE__ */ new Set();
105383
105413
  let firstError;
105384
105414
  let filesLeft = files.length;
@@ -105575,12 +105605,17 @@ async function installProofTools({
105575
105605
  onProgress = () => {
105576
105606
  },
105577
105607
  progressLine = (text3) => process.stderr.write(text3),
105578
- progressEveryMs = PROGRESS_EVERY_MS
105608
+ progressEveryMs = PROGRESS_EVERY_MS,
105609
+ onFileWritten = () => {
105610
+ },
105611
+ mark = () => {
105612
+ }
105579
105613
  }) {
105580
105614
  const { dir, sumsSha256 } = expected;
105581
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");
105582
105616
  const folder = join21(toolsRoot, dir);
105583
105617
  if (existsSync(folder) && verifyToolsFolder(folder, sumsSha256)) {
105618
+ mark("present");
105584
105619
  return Object.freeze({ dir, sumsSha256, folder, downloaded: 0, ...toolPaths(folder) });
105585
105620
  }
105586
105621
  const base = new URL(`/proof-tools/${dir}/`, facilitator);
@@ -105588,6 +105623,7 @@ async function installProofTools({
105588
105623
  if (sha2569(sums) !== sumsSha256) {
105589
105624
  throw fail26("setup_sums_mismatch", "the downloaded SHA256SUMS does not have the pinned SHA-256, so no proof tool was downloaded");
105590
105625
  }
105626
+ mark("sums");
105591
105627
  const entries = parseSums(sums.toString("utf8"));
105592
105628
  const partial = `${folder}.partial`;
105593
105629
  for (const entry of entries) {
@@ -105621,14 +105657,22 @@ async function installProofTools({
105621
105657
  let bytesDone = 0;
105622
105658
  let downloaded = 0;
105623
105659
  const budget = { left: LIMITS.total };
105660
+ let hashMs = 0;
105624
105661
  const write = (entry, bytes2) => {
105625
105662
  const target = localPath(partial, entry.path);
105626
- 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) {
105627
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`);
105628
105668
  }
105629
105669
  mkdirSync(dirname20(target), { recursive: true, mode: 448 });
105630
105670
  writeFileSync(target, bytes2, { flag: "wx", mode: 384 });
105631
105671
  if (executable(entry.path)) chmodSync(target, 493);
105672
+ try {
105673
+ onFileWritten({ path: entry.path, file: target });
105674
+ } catch {
105675
+ }
105632
105676
  };
105633
105677
  for (const { entry, bytes: bytes2 } of kept) {
105634
105678
  write(entry, bytes2);
@@ -105662,20 +105706,35 @@ async function installProofTools({
105662
105706
  }, progressEveryMs);
105663
105707
  ticker.unref?.();
105664
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}`);
105665
105718
  try {
105666
105719
  await downloadSet({ fetchImpl, base, entries: missing, budget, onBytes: (count2) => {
105667
105720
  arrived += count2;
105721
+ markQuarters();
105668
105722
  }, onFile: (entry, bytes2) => {
105669
105723
  write(entry, bytes2);
105670
105724
  bytesDone += bytes2.length;
105671
105725
  downloaded += 1;
105726
+ mark("file", `f${kept.length + downloaded}_of_${entries.length}`);
105672
105727
  onProgress({ filesDone: kept.length + downloaded, filesTotal: entries.length, bytesDone });
105673
105728
  } });
105674
105729
  } finally {
105675
105730
  clearInterval(ticker);
105676
105731
  }
105732
+ if (quarter < 4) mark("download-100");
105733
+ mark("file-hashes", `ms${hashMs}`);
105677
105734
  writeFileSync(join21(partial, "SHA256SUMS"), sums, { flag: "wx", mode: 384 });
105735
+ mark("hash-check-start");
105678
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");
105679
105738
  if (existsSync(folder)) rmSync(folder, { recursive: true, force: true });
105680
105739
  renameSync(partial, folder);
105681
105740
  return Object.freeze({ dir, sumsSha256, folder, downloaded, ...toolPaths(folder) });
@@ -106225,6 +106284,18 @@ function facilitatorAnchor(origin, fetchImpl = fetch) {
106225
106284
  fail29(`anchor_refused_${response.status}`);
106226
106285
  };
106227
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
+ }
106228
106299
  async function exitWhenAnchored(run5, { now = Date.now, sleep: sleep6 = (ms) => new Promise((resolve38) => setTimeout(resolve38, ms)), ring } = {}) {
106229
106300
  const deadline = now() + EXIT_ANCHOR_WAIT_MS;
106230
106301
  for (; ; ) {
@@ -106239,7 +106310,9 @@ async function exitWhenAnchored(run5, { now = Date.now, sleep: sleep6 = (ms) =>
106239
106310
  if (start + waitMs > deadline) throw error;
106240
106311
  const before = subAnchors ? await readRingBefore(ring, start) : void 0;
106241
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");
106242
106314
  await sleepForAnchor(waitMs, { ring, before, now, sleep: sleep6 });
106315
+ markPhase("anchor-wait-done");
106243
106316
  }
106244
106317
  }
106245
106318
  }
@@ -106446,6 +106519,7 @@ var init_cli2 = __esm({
106446
106519
  init_privateSend();
106447
106520
  init_promised();
106448
106521
  init_usdcWords();
106522
+ init_phaseTiming();
106449
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>]";
106450
106524
  REQUIRED2 = [
106451
106525
  "wallet",
@@ -117324,7 +117398,7 @@ async function runUnshield({
117324
117398
  recipientOwner: owner.toBase58(),
117325
117399
  allowForeignRecipient: true,
117326
117400
  relaySubmit: facilitatorExitRelay(facilitatorOrigin2),
117327
- requestAnchor: facilitatorAnchor(facilitatorOrigin2),
117401
+ requestAnchor: markedAnchorRequest(facilitatorAnchor(facilitatorOrigin2)),
117328
117402
  deps: { walkHistory: walk(exitProofTools.deploymentIdentity) }
117329
117403
  }), { ring: { connection: session.connection, pool: store.state.pool } }));
117330
117404
  mark("unshield-exited");
@@ -117384,7 +117458,7 @@ async function runDirectExit({
117384
117458
  recipientOwner: owner.toBase58(),
117385
117459
  allowForeignRecipient: true,
117386
117460
  relaySubmit: facilitatorExitRelay(facilitatorOrigin2),
117387
- requestAnchor: facilitatorAnchor(facilitatorOrigin2),
117461
+ requestAnchor: markedAnchorRequest(facilitatorAnchor(facilitatorOrigin2)),
117388
117462
  deps: { walkHistory: walk(exitProofTools.deploymentIdentity), proveExit }
117389
117463
  }), { ring: { connection: session.connection, pool: store.state.pool } }));
117390
117464
  } catch (error) {
@@ -146358,7 +146432,7 @@ init_cli();
146358
146432
  init_floatPay();
146359
146433
  import { randomBytes as randomBytes33 } from "node:crypto";
146360
146434
  import { dirname as dirname29, join as join36, resolve as resolve37 } from "node:path";
146361
- import { spawn as spawn6 } from "node:child_process";
146435
+ import { spawn as spawn7 } from "node:child_process";
146362
146436
  import { fileURLToPath as fileURLToPath22 } from "node:url";
146363
146437
 
146364
146438
  // wallet/src/fetch/index.mjs
@@ -146381,6 +146455,8 @@ init_recoveryFile();
146381
146455
  init_config2();
146382
146456
  init_proofTools();
146383
146457
  init_proxy();
146458
+ init_facilitatorOnion();
146459
+ init_timing();
146384
146460
  init_migration();
146385
146461
  init_successions();
146386
146462
  init_chain2();
@@ -146506,10 +146582,23 @@ function readPassphrase(path, access) {
146506
146582
  }
146507
146583
  async function runSetup(options, deps = {}) {
146508
146584
  const home = resolve26(options.home);
146509
- const onStage = options.onStage ?? (() => {
146510
- });
146511
146585
  const now = deps.now ?? (() => /* @__PURE__ */ new Date());
146512
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
+ };
146513
146602
  onStage("platform");
146514
146603
  const platform = proverPlatform({ platform: deps.platform, hasWsl: deps.hasWsl });
146515
146604
  if (!platform.ok) throw fail40(platform.code, platform.detail);
@@ -146533,6 +146622,10 @@ async function runSetup(options, deps = {}) {
146533
146622
  } catch (error) {
146534
146623
  releaseError = error;
146535
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);
146536
146629
  let identity;
146537
146630
  if (release) {
146538
146631
  expected = await trustServedSet({ home, facilitator, release, expected, fetchImpl: deps.fetchImpl ?? fetch });
@@ -146702,19 +146795,56 @@ async function runSetup(options, deps = {}) {
146702
146795
  }
146703
146796
  const keep = old?.proofToolsRelease && old.pool === identity.pool ? { proofTools: old.proofTools, exitProofTools: old.exitProofTools, profile: old.profile, proofToolsRelease: old.proofToolsRelease } : {};
146704
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
+ }
146705
146803
  onStage("proof-tools");
146706
146804
  let tools;
146707
- if (release) {
146708
- tools = await installProofTools({
146709
- facilitator,
146710
- toolsRoot: join30(home, "proof-tools"),
146711
- expected,
146712
- fetchImpl: deps.fetchImpl,
146713
- 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
+ }, () => {
146714
146822
  });
146715
- } else {
146716
- const folder = join30(home, "proof-tools", old.proofToolsRelease.dir);
146717
- 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
+ }
146718
146848
  }
146719
146849
  onStage("config");
146720
146850
  const config = {
@@ -146738,8 +146868,198 @@ async function runSetup(options, deps = {}) {
146738
146868
  passphraseGenerated,
146739
146869
  proofTools: { dir: tools.dir, downloaded: tools.downloaded, folder: tools.folder },
146740
146870
  platform: platform.wsl ? "windows+wsl" : "linux",
146741
- 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
146742
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
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
+ };
146743
147063
  }
146744
147064
 
146745
147065
  // wallet/src/cli/shinjukuWallet.mjs
@@ -146771,7 +147091,7 @@ init_proxy();
146771
147091
  init_rpcDefault();
146772
147092
  init_secretFile();
146773
147093
  init_serviceUrl();
146774
- import { resolve as resolve27 } from "node:path";
147094
+ import { resolve as resolve28 } from "node:path";
146775
147095
  import { fileURLToPath as fileURLToPath19 } from "node:url";
146776
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>]";
146777
147097
  var VALUED = ["wallet", "passphrase-file", "program", "rpc-file", "proof-tools", "profile", "facilitator", "history-rpc"];
@@ -146814,8 +147134,8 @@ async function main5(args = process.argv.slice(2)) {
146814
147134
  const origin = dryRun ? void 0 : new URL(options.facilitator);
146815
147135
  if (origin && (origin.protocol !== "https:" && !isOnionOrigin(origin) || origin.pathname !== "/" || origin.search)) fail41("facilitator_origin_invalid");
146816
147136
  const historyUrl = historyRpcUrl(options["history-rpc"]);
146817
- const walletPath2 = resolve27(options.wallet);
146818
- 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"));
146819
147139
  let release;
146820
147140
  try {
146821
147141
  release = await acquireWalletProcessLease(walletLockPath(walletPath2));
@@ -146834,13 +147154,13 @@ async function main5(args = process.argv.slice(2)) {
146834
147154
  const connection = connect2(resolveRpcUrl2({
146835
147155
  rpcFile: options["rpc-file"],
146836
147156
  origin: origin.origin,
146837
- readFile: (path) => readFileSync(resolve27(path), "utf8").trim()
147157
+ readFile: (path) => readFileSync(resolve28(path), "utf8").trim()
146838
147158
  }).url, "finalized");
146839
- const proofTools = loadP03PublicPaymentProofTools(resolve27(options["proof-tools"]));
147159
+ const proofTools = loadP03PublicPaymentProofTools(resolve28(options["proof-tools"]));
146840
147160
  steps = {
146841
147161
  connection,
146842
147162
  proofTools,
146843
- profile: JSON.parse(readFileSync(resolve27(options.profile), "utf8")),
147163
+ profile: JSON.parse(readFileSync(resolve28(options.profile), "utf8")),
146844
147164
  timing: createTimingLog(`${walletPath2}.timing.log`, { component: "payer" })
146845
147165
  };
146846
147166
  }
@@ -146938,7 +147258,7 @@ async function main5(args = process.argv.slice(2)) {
146938
147258
  await release();
146939
147259
  }
146940
147260
  }
146941
- 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)) {
146942
147262
  main5().catch((error) => {
146943
147263
  console.error(describeCliErrorWithHint(error));
146944
147264
  process.exitCode = 1;
@@ -146947,7 +147267,7 @@ if (process.argv[1] && resolve27(process.argv[1]) === fileURLToPath19(new URL("_
146947
147267
 
146948
147268
  // wallet/src/item/buyItem.mjs
146949
147269
  init_fs();
146950
- import { resolve as resolve28 } from "node:path";
147270
+ import { resolve as resolve29 } from "node:path";
146951
147271
 
146952
147272
  // src/shared/blindVoucher.ts
146953
147273
  init_sha256();
@@ -147439,8 +147759,8 @@ async function main6(args = process.argv.slice(2)) {
147439
147759
  }
147440
147760
  if (REQUIRED3.some((key) => !options[key])) throw new Error("p03_item_cli_arguments_missing");
147441
147761
  const historyUrl = historyRpcUrl(options["history-rpc"]);
147442
- const walletPath2 = resolve28(options.wallet);
147443
- 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"));
147444
147764
  const timing = createTimingLog(`${walletPath2}.timing.log`, { component: "payer" }).start({ startedAt: performance.timeOrigin });
147445
147765
  timing("process-start", void 0, performance.timeOrigin);
147446
147766
  if (proxyProvenAt() !== void 0) timing("proxy-proven", void 0, proxyProvenAt());
@@ -147457,15 +147777,15 @@ async function main6(args = process.argv.slice(2)) {
147457
147777
  const connection = connect2(resolveRpcUrl2({
147458
147778
  rpcFile: options["rpc-file"],
147459
147779
  origin: options["memo-service"],
147460
- readFile: (path) => readFileSync(resolve28(path), "utf8").trim()
147780
+ readFile: (path) => readFileSync(resolve29(path), "utf8").trim()
147461
147781
  }).url, "finalized");
147462
147782
  const earlySource = resolveHistorySource(connectSplit(connection, historyUrl), store.state.pool);
147463
147783
  if (earlySource.source === "pinned") earlySource.connection.historyRpcWarm?.();
147464
147784
  connection.getSlot("finalized").catch(() => {
147465
147785
  });
147466
- const proofTools = loadP03PublicPaymentProofTools(resolve28(options["proof-tools"]));
147786
+ const proofTools = loadP03PublicPaymentProofTools(resolve29(options["proof-tools"]));
147467
147787
  timing("proof-tools");
147468
- 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;
147469
147789
  if (playToken !== void 0 && !/^sjp_[A-Za-z0-9_-]{16,200}$/.test(playToken)) throw new Error("p03_item_play_token_invalid");
147470
147790
  const walkHistory = async () => {
147471
147791
  const history = await loadWalletP03History({
@@ -147512,100 +147832,6 @@ async function main6(args = process.argv.slice(2)) {
147512
147832
  }
147513
147833
  }
147514
147834
 
147515
- // wallet/src/history/keepWarm.mjs
147516
- init_fs();
147517
- init_chain2();
147518
- init_proxy();
147519
- init_recoveredPayment();
147520
- init_rpcDefault();
147521
- init_store();
147522
- init_incremental();
147523
- init_walletHistory();
147524
- import { spawn as spawn4 } from "node:child_process";
147525
- import { randomInt as randomInt7 } from "node:crypto";
147526
- import { resolve as resolve29 } from "node:path";
147527
- var KEEP_WARM_PARENT_ENV = "SHINJUKU_KEEP_WARM_PARENT";
147528
- var KEEP_WARM_MIN_MS = 18e4;
147529
- var KEEP_WARM_MAX_MS = 3e5;
147530
- async function keepWarmOnce(values, { io, env = process.env }) {
147531
- const started = Date.now();
147532
- const walletPath2 = resolve29(values.get("--wallet"));
147533
- const passphrase2 = assertPassphrase(values.has("--passphrase-file") ? readFileSync(resolve29(values.get("--passphrase-file")), "utf8").trim() : String(env.SHIELDED_WALLET_PASSPHRASE ?? ""));
147534
- const store = openWalletStore(walletPath2, passphrase2);
147535
- const connection = connect2(resolveRpcUrl2({
147536
- rpcFile: values.get("--rpc-file"),
147537
- origin: values.get("--memo-service"),
147538
- readFile: (path) => readFileSync(resolve29(path), "utf8").trim()
147539
- }).url, "finalized");
147540
- const proofTools = loadP03PublicPaymentProofTools(resolve29(values.get("--proof-tools")));
147541
- await loadWalletP03History({
147542
- store,
147543
- connection: connectSplit(connection, historyRpcUrl(values.get("--history-rpc"))),
147544
- programId: values.get("--program"),
147545
- pool: store.state.pool,
147546
- deploymentIdentity: proofTools.deploymentIdentity,
147547
- forceRead: true
147548
- });
147549
- 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
147550
- `);
147551
- }
147552
- async function keepWarmMain(args, values, { io, env = process.env, entry } = {}) {
147553
- if (values.has("--once")) {
147554
- await keepWarmOnce(values, { io, env });
147555
- return 0;
147556
- }
147557
- if (typeof entry !== "string" || !entry) throw new Error("keep_warm_entry_missing");
147558
- const proxy = childRunProxy(env);
147559
- let stopped = false;
147560
- let child;
147561
- let wake;
147562
- const stop3 = () => {
147563
- stopped = true;
147564
- child?.kill("SIGTERM");
147565
- wake?.();
147566
- };
147567
- process.on("SIGINT", stop3);
147568
- process.on("SIGTERM", stop3);
147569
- if (env[KEEP_WARM_PARENT_ENV] === "1") {
147570
- process.stdin.on("end", stop3);
147571
- process.stdin.on("close", stop3);
147572
- process.stdin.on("error", stop3);
147573
- process.stdin.resume();
147574
- }
147575
- try {
147576
- while (!stopped) {
147577
- const code2 = await new Promise((done) => {
147578
- child = spawn4(process.execPath, [...process.execArgv, entry, ...proxy.args, "keep-warm", ...args, "--once"], {
147579
- env: proxy.env,
147580
- stdio: ["ignore", "ignore", "inherit"],
147581
- windowsHide: true
147582
- });
147583
- child.on("error", () => done(1));
147584
- child.on("exit", (exitCode) => done(exitCode ?? 1));
147585
- });
147586
- child = void 0;
147587
- if (stopped) break;
147588
- if (code2 !== 0) io.err(`keep-warm: this refresh failed (exit ${code2}); the next one runs at its usual time
147589
- `);
147590
- const gap = randomInt7(KEEP_WARM_MIN_MS, KEEP_WARM_MAX_MS + 1);
147591
- io.err(`keep-warm: next refresh in ${Math.round(gap / 1e3)} s (stop with Ctrl-C)
147592
- `);
147593
- await new Promise((done) => {
147594
- const timer = setTimeout(done, gap);
147595
- wake = () => {
147596
- clearTimeout(timer);
147597
- done();
147598
- };
147599
- });
147600
- wake = void 0;
147601
- }
147602
- } finally {
147603
- process.off("SIGINT", stop3);
147604
- process.off("SIGTERM", stop3);
147605
- }
147606
- return 0;
147607
- }
147608
-
147609
147835
  // wallet/src/cli/shinjukuWallet.mjs
147610
147836
  init_cli3();
147611
147837
 
@@ -149803,7 +150029,7 @@ init_deposit();
149803
150029
  init_fs();
149804
150030
  init_balance();
149805
150031
  init_deposit();
149806
- import { spawn as spawn5 } from "node:child_process";
150032
+ import { spawn as spawn6 } from "node:child_process";
149807
150033
  import { randomBytes as randomBytes25, randomInt as randomInt9 } from "node:crypto";
149808
150034
  import { tmpdir as tmpdir4 } from "node:os";
149809
150035
  import { join as join33, resolve as resolve31 } from "node:path";
@@ -150058,7 +150284,7 @@ async function runStep(ctx, argv2) {
150058
150284
  const file = join33(ctx.tempDir, `step-${randomBytes25(8).toString("hex")}.json`);
150059
150285
  const held = [];
150060
150286
  let last;
150061
- 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], {
150062
150288
  env: { ...ctx.childEnv, [RESULT_FILE_ENV]: file },
150063
150289
  stdio: ["ignore", "ignore", "pipe"],
150064
150290
  windowsHide: true
@@ -151551,7 +151777,7 @@ function startKeepWarm(options, env = process.env) {
151551
151777
  options.memoServiceUrl,
151552
151778
  ...options.historyRpc ? ["--history-rpc", options.historyRpc] : []
151553
151779
  ];
151554
- 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], {
151555
151781
  env: {
151556
151782
  ...proxy.env,
151557
151783
  [PASSPHRASE_ENV2]: options.passphrase,
@@ -151571,6 +151797,11 @@ function startKeepWarm(options, env = process.env) {
151571
151797
  });
151572
151798
  return child;
151573
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
+ }
151574
151805
  function mcpServerOptions(values, deps) {
151575
151806
  const options = payerSessionOptions(values, deps);
151576
151807
  let pool2;
@@ -152137,7 +152368,7 @@ Copy it to two offline places now; it is the only way to restore this wallet.
152137
152368
  lastStage = stage;
152138
152369
  io.err(`${STAGE_TEXT[stage]}...
152139
152370
  `);
152140
- } }, setupDependencies(deps), inference);
152371
+ } }, { ...setupDependencies(deps), startWarm: setupWarmStarter(deps) }, inference);
152141
152372
  } catch (error) {
152142
152373
  if (/^(setup_[a-z_]+|secret_file_utf16): /.test(String(error?.message))) throw new PublicFailure(error.message);
152143
152374
  throw error;
@@ -152148,7 +152379,9 @@ Copy it to two offline places now; it is the only way to restore this wallet.
152148
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" : ""}`,
152149
152380
  ` config ${summary.configPath}`,
152150
152381
  ` passphrase ${summary.passphraseFile}${summary.passphraseGenerated ? " (a new random passphrase; only you can read the file; it is never printed)" : ""}`,
152151
- ` 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"] : []
152152
152385
  ];
152153
152386
  if (summary.wallet.status === "created") {
152154
152387
  lines.push(
@@ -155248,8 +155481,11 @@ ${sellerLine}${landedLine}${whyLine}${ambiguousLine}${blockingLine}${hint ? `hin
155248
155481
  // wallet/bin/shinjuku-wallet.mjs
155249
155482
  init_proxy();
155250
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;
155251
155486
  var mcpRefused = async (options) => (await Promise.resolve().then(() => (init_torMissingMcp(), torMissingMcp_exports))).serveTorMissingMcp(options);
155252
155487
  var code = isHelpRequest(argv) ? await runShinjukuWallet(argv) : await proxyEntry(argv, runShinjukuWallet, { mcpRefused });
155488
+ stopSetupWatch?.();
155253
155489
  process.exitCode = code;
155254
155490
  if (code !== 0) setTimeout(() => process.exit(code), 2e3).unref();
155255
155491
  else if (mcpServerEndedHere()) setTimeout(() => process.exit(code), 0).unref();