shinjuku-shielded 0.3.62 → 0.3.64

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/README.md CHANGED
@@ -7,7 +7,7 @@ local MCP server (stdio) for your agent. Your keys never leave your machine.
7
7
  ## Set up
8
8
 
9
9
  ```sh
10
- npx -y shinjuku-shielded setup
10
+ npx -y --no-audit --no-fund shinjuku-shielded setup
11
11
  ```
12
12
 
13
13
  Setup makes the wallet on this machine, a private passphrase file, and the
@@ -21,13 +21,13 @@ server to that host's config.
21
21
  Claude Code:
22
22
 
23
23
  ```sh
24
- claude mcp add --scope user shinjuku-shielded -- npx -y shinjuku-shielded mcp
24
+ claude mcp add --scope user shinjuku-shielded -- npx -y --no-audit --no-fund shinjuku-shielded mcp
25
25
  ```
26
26
 
27
27
  Claude Desktop (`claude_desktop_config.json`) or Cursor (`~/.cursor/mcp.json`):
28
28
 
29
29
  ```json
30
- { "mcpServers": { "shinjuku-shielded": { "command": "npx", "args": ["-y", "shinjuku-shielded", "mcp"] } } }
30
+ { "mcpServers": { "shinjuku-shielded": { "command": "npx", "args": ["-y", "--no-audit", "--no-fund", "shinjuku-shielded", "mcp"] } } }
31
31
  ```
32
32
 
33
33
  On native Windows, if the host cannot find `npx`, use `"command": "cmd"` and
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": "d9319f9cc0d4e5deebfa15e1ac35bee0bc4f4ffb95cd4f58e400ee322ac11076",
5
- "bytes": 12167009,
6
- "sourceCommit": "ae2f0123e2d006af49b3e33fd15ac30dd0d95222",
4
+ "sha256": "f7b2fe093da4904a611ef95fb52e7888ad1f23b2f41681474d1bd9bef75a71f8",
5
+ "bytes": 12179295,
6
+ "sourceCommit": "98688d76628c9d7aa02f0215b371e30999e852fa",
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-22T06:56:59.253Z"
1285
+ "publishedAt": "2026-10-22T09:31:31.971Z"
1286
1286
  }
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "shinjuku-shielded",
3
- "version": "0.3.62",
3
+ "version": "0.3.64",
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": "d9319f9c",
7
- "shinjukuSha256": "d9319f9cc0d4e5deebfa15e1ac35bee0bc4f4ffb95cd4f58e400ee322ac11076",
6
+ "shinjukuRelease": "f7b2fe09",
7
+ "shinjukuSha256": "f7b2fe093da4904a611ef95fb52e7888ad1f23b2f41681474d1bd9bef75a71f8",
8
8
  "license": "SEE LICENSE IN LICENSE.txt",
9
9
  "author": "Shinjuku Shielded",
10
10
  "homepage": "https://github.com/ShinjukuStaition/shinjuku-mcp#readme",
@@ -42754,6 +42754,7 @@ async function routeFacilitatorsOverOnion(argv2, {
42754
42754
  live: onions.length,
42755
42755
  spares,
42756
42756
  waitMs: routeWaitMs,
42757
+ label: origin,
42757
42758
  onSpares: () => err(`tor: no onion of ${origin} has answered yet; its ${spares.length} spare onions ${spareHosts} join (Tor may still be fetching the onion addresses)
42758
42759
  `),
42759
42760
  onNone: () => err(`tor: no onion of ${origin} answered its start probe (${liveOnions(group).length} tried); its requests go to its onions in turn and wait for them (Tor may still be building circuits)
@@ -42774,7 +42775,7 @@ async function routeFacilitatorsOverOnion(argv2, {
42774
42775
  }
42775
42776
  }
42776
42777
  for (const [origin, onions] of Object.entries(PINNED_HISTORY_ONIONS)) {
42777
- const group = { onions, path: HISTORY_PROBE_PATH, onNone: () => err(`tor: no history-proxy onion answered its start probe (${onions.length} tried); the pool history reads go to the pinned onion ${new URL(onions[0]).host.slice(0, 8)}... and wait for it
42778
+ const group = { onions, path: HISTORY_PROBE_PATH, label: "the history proxy", onNone: () => err(`tor: no history-proxy onion answered its start probe (${onions.length} tried); the pool history reads go to the pinned onion ${new URL(onions[0]).host.slice(0, 8)}... and wait for it
42778
42779
  `) };
42779
42780
  groups.set(onions.join(" "), group);
42780
42781
  routes.set(origin, group);
@@ -42783,6 +42784,33 @@ async function routeFacilitatorsOverOnion(argv2, {
42783
42784
  } };
42784
42785
  for (const [origin, group] of routes) routedOrigins.set(origin, group.onions);
42785
42786
  const aborts = [];
42787
+ let stopped = false;
42788
+ const race = (group, onions, options) => {
42789
+ let unanswered2 = false;
42790
+ const onNone = options.onNone;
42791
+ const raced = raceOnions(onions, {
42792
+ fetchImpl,
42793
+ timeoutMs: raceTimeoutMs,
42794
+ ...group.path ? { path: group.path } : {},
42795
+ ...options,
42796
+ onNone: () => {
42797
+ unanswered2 = true;
42798
+ onNone?.();
42799
+ }
42800
+ });
42801
+ group.pending = raced.winner.then((onion) => {
42802
+ group.winner = onion;
42803
+ group.pending = void 0;
42804
+ if (!unanswered2 && !raced.stopped) err(`tor: the onion ${hostOf(onion)} of ${group.label} answered first; it serves this run's requests to it
42805
+ `);
42806
+ return onion;
42807
+ });
42808
+ aborts.push(() => {
42809
+ raced.stopped = true;
42810
+ raced.abort();
42811
+ });
42812
+ return raced;
42813
+ };
42786
42814
  for (const group of groups.values()) {
42787
42815
  routedGroups.push(group);
42788
42816
  if (group.onions.length === 1) {
@@ -42791,24 +42819,33 @@ async function routeFacilitatorsOverOnion(argv2, {
42791
42819
  continue;
42792
42820
  }
42793
42821
  const spares = group.spares ?? [];
42794
- const race = raceOnions(liveOnions(group), {
42795
- fetchImpl,
42796
- timeoutMs: raceTimeoutMs,
42797
- ...group.path ? { path: group.path } : {},
42822
+ group.startSpares = race(group, liveOnions(group), {
42798
42823
  ...group.onNone ? { onNone: group.onNone } : {},
42799
42824
  ...spares.length > 0 ? { spares, spareAfterMs, onSpares: () => {
42800
42825
  group.live = group.onions.length;
42801
42826
  group.onSpares?.();
42802
42827
  } } : {}
42803
- });
42804
- group.startSpares = race.startSpares;
42805
- group.pending = race.winner.then((onion) => {
42806
- group.winner = onion;
42807
- group.pending = void 0;
42808
- return onion;
42809
- });
42810
- aborts.push(race.abort);
42811
- }
42828
+ }).startSpares;
42829
+ }
42830
+ const moveOn = (group, onion, why) => {
42831
+ if (stopped || group.winner !== onion || group.pending) return;
42832
+ group.moves = (group.moves ?? 0) + 1;
42833
+ const max = group.onions.length;
42834
+ if (group.moves > max) {
42835
+ if (group.moves === max + 1) err(`tor: no onion of ${group.label} answered after ${max} moves; this run keeps ${hostOf(onion)} and retries there
42836
+ `);
42837
+ return;
42838
+ }
42839
+ (group.down ??= /* @__PURE__ */ new Set()).add(onion);
42840
+ const fresh = group.onions.filter((other) => !group.down.has(other));
42841
+ const others = fresh.length > 0 ? fresh : group.onions.filter((other) => other !== onion);
42842
+ group.live = group.onions.length;
42843
+ group.winner = void 0;
42844
+ err(`tor: the onion ${hostOf(onion)} of ${group.label} gave no answer (${why}); its requests move to the first of ${others.map(hostOf).join(", ")} to answer (move ${group.moves} of ${max})
42845
+ `);
42846
+ race(group, others, { onNone: () => err(`tor: no other onion of ${group.label} answered; its requests go to ${hostOf(others[0])} and wait for it
42847
+ `) });
42848
+ };
42812
42849
  const original = globalThis.fetch;
42813
42850
  const urlOf = (value) => {
42814
42851
  try {
@@ -42821,17 +42858,30 @@ async function routeFacilitatorsOverOnion(argv2, {
42821
42858
  const url = typeof input === "string" || input instanceof URL ? urlOf(String(input)) : input instanceof Request ? urlOf(input.url) : void 0;
42822
42859
  const group = url && routes.get(url.origin);
42823
42860
  if (!group) return original(input, init);
42861
+ const signal = init?.signal ?? (input instanceof Request ? input.signal : void 0);
42824
42862
  const send3 = (onion) => {
42825
42863
  if (onion === void 0) {
42826
42864
  group.startSpares?.();
42827
- const live = liveOnions(group);
42865
+ const up = liveOnions(group).filter((other) => !group.down?.has(other));
42866
+ const live = up.length > 0 ? up : liveOnions(group);
42828
42867
  onion = live[(group.sent = (group.sent ?? 0) + 1) % live.length];
42829
42868
  }
42830
42869
  const target = `${onion}${url.pathname}${url.search}`;
42831
- return original(input instanceof Request ? new Request(target, input) : target, onionInit(init));
42870
+ const sent = original(input instanceof Request ? new Request(target, input) : target, onionInit(init));
42871
+ if (group.onions.length < 2) return sent;
42872
+ return sent.then((response) => {
42873
+ if (onion === group.winner) {
42874
+ group.moves = 0;
42875
+ group.down?.clear();
42876
+ }
42877
+ return response;
42878
+ }, (error) => {
42879
+ const why = noAnswer(error, signal);
42880
+ if (why) moveOn(group, onion, why);
42881
+ throw error;
42882
+ });
42832
42883
  };
42833
42884
  if (group.winner) return send3(group.winner);
42834
- const signal = init?.signal ?? (input instanceof Request ? input.signal : void 0);
42835
42885
  if (!group.waitMs) return untilAborted(group.pending, signal).then(send3);
42836
42886
  let timer;
42837
42887
  const bound = new Promise((resolve38) => {
@@ -42843,12 +42893,13 @@ async function routeFacilitatorsOverOnion(argv2, {
42843
42893
  return {
42844
42894
  routes: new Map([...routes].map(([origin, group]) => [origin, group.onions])),
42845
42895
  stop: () => {
42896
+ stopped = true;
42846
42897
  for (const abort of aborts) abort();
42847
42898
  closeOnionDispatchers();
42848
42899
  }
42849
42900
  };
42850
42901
  }
42851
- 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, routedGroups, liveOnions, routedOnions, routedOrigins, onionsOfOrigin, routesOverOnion, GLOBAL_DISPATCHER, onionDispatchers;
42902
+ 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, routedGroups, liveOnions, hostOf, noAnswer, routedOnions, routedOrigins, onionsOfOrigin, routesOverOnion, GLOBAL_DISPATCHER, onionDispatchers;
42852
42903
  var init_facilitatorOnion = __esm({
42853
42904
  "wallet/src/net/facilitatorOnion.mjs"() {
42854
42905
  "use strict";
@@ -42888,6 +42939,12 @@ var init_facilitatorOnion = __esm({
42888
42939
  SPARE_AFTER_MS = ROUTE_WAIT_MS;
42889
42940
  routedGroups = [];
42890
42941
  liveOnions = (group) => group.onions.slice(0, group.live ?? group.onions.length);
42942
+ hostOf = (onion) => `${new URL(onion).host.slice(0, 8)}...`;
42943
+ noAnswer = (error, signal) => {
42944
+ if (signal?.aborted) return signal.reason?.name === "TimeoutError" ? "no answer before the request's timeout" : void 0;
42945
+ if (error?.name === "TimeoutError") return "no answer before the request's timeout";
42946
+ return error instanceof TypeError ? "the stream failed" : void 0;
42947
+ };
42891
42948
  routedOnions = () => [...new Set(routedGroups.flatMap((group) => group.winner ? [group.winner] : liveOnions(group)))];
42892
42949
  routedOrigins = /* @__PURE__ */ new Map();
42893
42950
  onionsOfOrigin = (origin) => routedOrigins.get(origin) ?? PINNED_FACILITATOR_ONIONS[origin] ?? [];
@@ -46874,11 +46931,11 @@ function childRunProxy(env = process.env) {
46874
46931
  return { args, env: clean5 };
46875
46932
  }
46876
46933
  function mayMoveTorCircuit(why = "rate") {
46877
- if (torRotations < TOR_MAX_ROTATIONS && canSwitchTorTag()) return true;
46878
- if (!torRotationsRefused) {
46879
- torRotationsRefused = true;
46934
+ if (torMoves[why] < TOR_MAX_ROTATIONS && canSwitchTorTag()) return true;
46935
+ if (!torMovesRefused[why]) {
46936
+ torMovesRefused[why] = true;
46880
46937
  const what = why === "stall" ? "a request stalled until its timeout" : "the RPC answered HTTP 429";
46881
- process.stderr.write(torRotations >= TOR_MAX_ROTATIONS ? why === "stall" ? `tor: a request stalled again after ${TOR_MAX_ROTATIONS} new circuits; this run keeps its circuit and retries there
46938
+ process.stderr.write(torMoves[why] >= TOR_MAX_ROTATIONS ? why === "stall" ? `tor: a request stalled again after ${TOR_MAX_ROTATIONS} new circuits in a row; this run keeps its circuit and retries there until one answers
46882
46939
  ` : `tor: the RPC still answers HTTP 429 after ${TOR_MAX_ROTATIONS} new circuits; this run keeps its circuit and waits as the RPC asks
46883
46940
  ` : `tor: ${what}, and Node ${process.versions.node} cannot move a run to a new Tor circuit (it has no http.setGlobalProxyFromEnv and no proxy dispatcher of its own); this run keeps its circuit
46884
46941
  `);
@@ -46950,12 +47007,19 @@ function noteAnswer(response) {
46950
47007
  rpcAnswered += 1;
46951
47008
  lastAnswerAt = Date.now();
46952
47009
  }
47010
+ function noteCircuitAnswer(response, circuit) {
47011
+ if (!response.ok || torMoves.stall === 0 || circuit !== torCircuitId) return;
47012
+ torMoves.stall = 0;
47013
+ torMovesRefused.stall = false;
47014
+ process.stderr.write(`tor: the new circuit answered, so this run may again move to a new circuit (up to ${TOR_MAX_ROTATIONS} in a row) when a request stalls
47015
+ `);
47016
+ }
46953
47017
  async function moveToNewTorCircuit(why = "rate") {
46954
47018
  if (!mayMoveTorCircuit(why)) return false;
46955
47019
  switchTorTag();
46956
- torRotations += 1;
46957
- process.stderr.write(why === "stall" ? `tor: a request on this circuit stalled until its timeout, so this run moved to a new Tor circuit (${torRotations} of ${TOR_MAX_ROTATIONS})
46958
- ` : `tor: this circuit kept answering HTTP 429 after the full wait the RPC asked for, so this run moved to a new Tor circuit (${torRotations} of ${TOR_MAX_ROTATIONS})
47020
+ torMoves[why] += 1;
47021
+ process.stderr.write(why === "stall" ? `tor: a request on this circuit stalled until its timeout, so this run moved to a new Tor circuit (${torMoves.stall} of ${TOR_MAX_ROTATIONS} in a row)
47022
+ ` : `tor: this circuit kept answering HTTP 429 after the full wait the RPC asked for, so this run moved to a new Tor circuit (${torMoves.rate} of ${TOR_MAX_ROTATIONS})
46959
47023
  `);
46960
47024
  return true;
46961
47025
  }
@@ -47021,8 +47085,10 @@ async function rpcFetch(input, init) {
47021
47085
  });
47022
47086
  const post = typeof init?.body === "string" ? describeRpcPost(input, init.body) : void 0;
47023
47087
  if (!post?.resendable) {
47088
+ const startedOn = torCircuitId;
47024
47089
  const response = await fetch2(input, init);
47025
47090
  noteAnswer(response);
47091
+ noteCircuitAnswer(response, startedOn);
47026
47092
  markRefusal(response, post);
47027
47093
  return response;
47028
47094
  }
@@ -47038,6 +47104,7 @@ async function rpcFetch(input, init) {
47038
47104
  const circuit = torCircuitId;
47039
47105
  const response = await fetch2(input, init);
47040
47106
  noteAnswer(response);
47107
+ noteCircuitAnswer(response, circuit);
47041
47108
  markRefusal(response, post);
47042
47109
  if (response.status !== 429) return response;
47043
47110
  await response.body?.cancel().catch(() => {
@@ -47141,7 +47208,7 @@ async function proxyEntry(argv2, run5, { err = (text3) => process.stderr.write(t
47141
47208
  }
47142
47209
  return reexec(options.args, options.mode, options.proxy);
47143
47210
  }
47144
- var TOR_HTTP_TUNNEL, TOR_CHECK, PROOF_TIMEOUT_MS, LOCAL_PROOF_TIMEOUT_MS, LOCAL_PROOF_MAX_BYTES, torProvenAt, proxyProvenAt, MARK, TOR_RUN_STARTED_ENV, ownProxyRefused, ONION_V3, RETRY_AFTER_CAP_MS, RETRY_AFTER_FLOOR_MS, RETRY_AFTER_DEFAULT_MS, RPC_NO_ANSWER_LIMIT_MS, RPC_PACING_CAP_MS, PACING_NOTICE_EVERY_MS, PACING_RATE_WINDOW_MS, TOR_MAX_ROTATIONS, runStartedAt, rpcNotBefore, pacingWaiters, pacingSince, pacedMs, rpcAnswered, lastAnswerAt, readSteps, pacingNoticeAt, pacingSamples, torRotations, torCircuitId, torRotationsRefused, pendingMove, inTorRun, runNetworkMode, isOnionOrigin, ProxyUsageError, isOnionHost, TOR_EXPERT_BUNDLE, TUNNEL_LINE, TOR_INSTALL, OS_NAMES, osKey, torNotRunningMessage, NOTICE, withRunTag, proxyEnv, pacedSoFar, RESENDABLE_METHOD, torCircuit, GLOBAL_DISPATCHER2, laneDispatchers, paymentWarmStop;
47211
+ var TOR_HTTP_TUNNEL, TOR_CHECK, PROOF_TIMEOUT_MS, LOCAL_PROOF_TIMEOUT_MS, LOCAL_PROOF_MAX_BYTES, torProvenAt, proxyProvenAt, MARK, TOR_RUN_STARTED_ENV, ownProxyRefused, ONION_V3, RETRY_AFTER_CAP_MS, RETRY_AFTER_FLOOR_MS, RETRY_AFTER_DEFAULT_MS, RPC_NO_ANSWER_LIMIT_MS, RPC_PACING_CAP_MS, PACING_NOTICE_EVERY_MS, PACING_RATE_WINDOW_MS, TOR_MAX_ROTATIONS, runStartedAt, rpcNotBefore, pacingWaiters, pacingSince, pacedMs, rpcAnswered, lastAnswerAt, readSteps, pacingNoticeAt, pacingSamples, torMoves, torCircuitId, torMovesRefused, pendingMove, inTorRun, runNetworkMode, isOnionOrigin, ProxyUsageError, isOnionHost, TOR_EXPERT_BUNDLE, TUNNEL_LINE, TOR_INSTALL, OS_NAMES, osKey, torNotRunningMessage, NOTICE, withRunTag, proxyEnv, pacedSoFar, RESENDABLE_METHOD, torCircuit, GLOBAL_DISPATCHER2, laneDispatchers, paymentWarmStop;
47145
47212
  var init_proxy = __esm({
47146
47213
  "wallet/src/net/proxy.mjs"() {
47147
47214
  "use strict";
@@ -47175,9 +47242,9 @@ var init_proxy = __esm({
47175
47242
  lastAnswerAt = runStartedAt;
47176
47243
  readSteps = /* @__PURE__ */ new Set();
47177
47244
  pacingSamples = [];
47178
- torRotations = 0;
47245
+ torMoves = { rate: 0, stall: 0 };
47179
47246
  torCircuitId = 0;
47180
- torRotationsRefused = false;
47247
+ torMovesRefused = { rate: false, stall: false };
47181
47248
  inTorRun = () => String(process.env[MARK] ?? "").startsWith("tor ");
47182
47249
  runNetworkMode = () => {
47183
47250
  const mode = String(process.env[MARK] ?? "").split(" ")[0];
@@ -50846,7 +50913,7 @@ function markHistoryChoice(own, choice) {
50846
50913
  function connectSplit(own, historyUrl, commitment = "finalized", { pause: pause3 = pauseFor, notice = noticeOnStderr } = {}) {
50847
50914
  if (historyUrl === void 0) return markHistoryChoice(own, "default");
50848
50915
  if (historyUrl === HISTORY_RPC_OWN) return markHistoryChoice(own, "own");
50849
- const history = connect2(historyUrl, commitment, { timeoutMs: HISTORY_RPC_REQUEST_TIMEOUT_MS });
50916
+ const history = connect2(historyUrl, commitment, { timeoutMs: HISTORY_RPC_REQUEST_TIMEOUT_MS, wrapFetch: trackHistoryAnswers });
50850
50917
  const ownRouted = COUNTED_RPC_METHODS.filter((name) => !HISTORY_RPC_METHODS.includes(name));
50851
50918
  const counts = Object.freeze({
50852
50919
  history: Object.fromEntries([...HISTORY_RPC_METHODS, "getTransactions"].map((name) => [name, 0])),
@@ -51561,7 +51628,7 @@ function depositIntentAddress2({ programId, pool: pool2, depositPublicInputBytes
51561
51628
  programId
51562
51629
  )[0];
51563
51630
  }
51564
- var import_web395, POOL_STATE_LEN2, POOL_STATE_LEN_RING2, POOL_STATE_LEN_RING_642, ANCHOR_MODE_RING2, ANCHOR_RING_HEADER2, ANCHOR_RING_FIRST_SLOT2, ANCHOR_RING_SLOT_LEN2, POOL_LAYOUTS, POOL_STATE_LEN_V22, BUFFER_HEADER_LEN2, MEMO_BUNDLE_BYTES2, PAYLOAD_LENGTH2, PAYLOAD_LENGTH_V22, TRANSITION_KIND2, INSTRUCTION2, COUNTED_RPC_METHODS, HISTORY_RPC_METHODS, PINNED_HISTORY_PROXIES, PINNED_HISTORY_HTTPS, HISTORY_RPC_OWN, historyRpcErrors, HISTORY_RPC_BEHIND_WAIT_MS, HISTORY_RPC_REQUEST_TIMEOUT_MS, HISTORY_RPC_BEHIND_FAST_MS, HISTORY_RPC_BEHIND_FAST_TRIES, HISTORY_RPC_BEHIND_RETRY_STEPS_MS, HISTORY_RPC_BEHIND_CODE, ED25519_SPKI_PREFIX, SIGNATURE_BYTES, VERSION_1_PREFIX, HISTORY_CROSS_CHECK_COUNT, runTransactions, warmedSources, bytes323, MEMO_BATCH_MAX, MEMO_LANES, MEMO_HEDGE_AFTER_MS, MEMO_ATTEMPTS, MEMO_MAX_WAIT_SECONDS, MEMO_RATE_LIMIT_BUDGET_SECONDS, memoGatesByFetch, MEMO_ANSWER_TIMEOUT_MS, MEMO_BODY_TIMEOUT_MS, pauseFor, noticeOnStderr, memoDigestHex, memoFailureText, prefetchedMemosByFetch, MEMO_PREFETCH_LIFE_MS;
51631
+ var import_web395, POOL_STATE_LEN2, POOL_STATE_LEN_RING2, POOL_STATE_LEN_RING_642, ANCHOR_MODE_RING2, ANCHOR_RING_HEADER2, ANCHOR_RING_FIRST_SLOT2, ANCHOR_RING_SLOT_LEN2, POOL_LAYOUTS, POOL_STATE_LEN_V22, BUFFER_HEADER_LEN2, MEMO_BUNDLE_BYTES2, PAYLOAD_LENGTH2, PAYLOAD_LENGTH_V22, TRANSITION_KIND2, INSTRUCTION2, COUNTED_RPC_METHODS, HISTORY_RPC_METHODS, PINNED_HISTORY_PROXIES, PINNED_HISTORY_HTTPS, HISTORY_RPC_OWN, historyRpcErrors, HISTORY_RPC_BEHIND_WAIT_MS, HISTORY_RPC_REQUEST_TIMEOUT_MS, HISTORY_SOURCE_SILENT_MS, historySilentSince, historyRequestsSent, historySourceState, trackHistoryAnswers, HISTORY_RPC_BEHIND_FAST_MS, HISTORY_RPC_BEHIND_FAST_TRIES, HISTORY_RPC_BEHIND_RETRY_STEPS_MS, HISTORY_RPC_BEHIND_CODE, ED25519_SPKI_PREFIX, SIGNATURE_BYTES, VERSION_1_PREFIX, HISTORY_CROSS_CHECK_COUNT, runTransactions, warmedSources, bytes323, MEMO_BATCH_MAX, MEMO_LANES, MEMO_HEDGE_AFTER_MS, MEMO_ATTEMPTS, MEMO_MAX_WAIT_SECONDS, MEMO_RATE_LIMIT_BUDGET_SECONDS, memoGatesByFetch, MEMO_ANSWER_TIMEOUT_MS, MEMO_BODY_TIMEOUT_MS, pauseFor, noticeOnStderr, memoDigestHex, memoFailureText, prefetchedMemosByFetch, MEMO_PREFETCH_LIFE_MS;
51565
51632
  var init_chain2 = __esm({
51566
51633
  "wallet/src/chain.mjs"() {
51567
51634
  "use strict";
@@ -51661,6 +51728,16 @@ var init_chain2 = __esm({
51661
51728
  historyRpcErrors = /* @__PURE__ */ new WeakSet();
51662
51729
  HISTORY_RPC_BEHIND_WAIT_MS = 6e4;
51663
51730
  HISTORY_RPC_REQUEST_TIMEOUT_MS = 2e4;
51731
+ HISTORY_SOURCE_SILENT_MS = 6e4;
51732
+ historyRequestsSent = 0;
51733
+ historySourceState = () => ({ silentSince: historySilentSince, sent: historyRequestsSent });
51734
+ trackHistoryAnswers = (fetch2) => async (input, init) => {
51735
+ historyRequestsSent += 1;
51736
+ historySilentSince ??= Date.now();
51737
+ const response = await fetch2(input, init);
51738
+ historySilentSince = void 0;
51739
+ return response;
51740
+ };
51664
51741
  HISTORY_RPC_BEHIND_FAST_MS = 150;
51665
51742
  HISTORY_RPC_BEHIND_FAST_TRIES = 12;
51666
51743
  HISTORY_RPC_BEHIND_RETRY_STEPS_MS = Object.freeze([500, 1e3, 2e3, 5e3]);
@@ -53871,6 +53948,24 @@ function parseE1TreeHeader(header) {
53871
53948
  bufferSize: u642(72)
53872
53949
  };
53873
53950
  }
53951
+ function programDataAddressOf(program) {
53952
+ const key = b58(program);
53953
+ let address5 = PROGRAMDATA_ADDRESSES.get(key);
53954
+ if (address5 === void 0) {
53955
+ address5 = import_web396.PublicKey.findProgramAddressSync([new import_web396.PublicKey(key).toBuffer()], BPF_LOADER_UPGRADEABLE_PROGRAM_ID)[0];
53956
+ PROGRAMDATA_ADDRESSES.set(key, address5);
53957
+ }
53958
+ return address5;
53959
+ }
53960
+ function reuseOptionRefused(connection) {
53961
+ const endpoint2 = connection.rpcEndpoint;
53962
+ return typeof endpoint2 === "string" ? REUSE_REFUSED_ENDPOINTS.has(endpoint2) : REUSE_REFUSED_CONNECTIONS.has(connection);
53963
+ }
53964
+ function rememberReuseOptionRefused(connection) {
53965
+ const endpoint2 = connection.rpcEndpoint;
53966
+ if (typeof endpoint2 === "string") REUSE_REFUSED_ENDPOINTS.add(endpoint2);
53967
+ else REUSE_REFUSED_CONNECTIONS.add(connection);
53968
+ }
53874
53969
  function slicesRefused(connection) {
53875
53970
  const endpoint2 = connection.rpcEndpoint;
53876
53971
  return typeof endpoint2 === "string" ? SLICES_REFUSED_ENDPOINTS.has(endpoint2) : SLICES_REFUSED_CONNECTIONS.has(connection);
@@ -53884,20 +53979,41 @@ function slicesMethodMissing(error) {
53884
53979
  const message = String(error?.message ?? "");
53885
53980
  return /^(404|405|501)\b/.test(message) || /-3260[12]\b/.test(message);
53886
53981
  }
53887
- function slicedAccountBytes(value, accountIndex) {
53982
+ function slicedAccountBytes(value, accountIndex, slices = POOL_SLICES) {
53888
53983
  if (value === null || typeof value !== "object" || typeof value.owner !== "string" || !Number.isSafeInteger(value.space) || value.space < 0 || !Array.isArray(value.data) || value.data.length !== 2 || value.data[1] !== "base64" || typeof value.data[0] !== "string") {
53889
53984
  return void 0;
53890
53985
  }
53891
53986
  const bytes2 = Buffer.from(value.data[0], "base64");
53892
53987
  if (bytes2.toString("base64") !== value.data[0]) return void 0;
53893
53988
  let expected = 0;
53894
- for (const [index, offset, length] of POOL_SLICES) {
53989
+ for (const [index, offset, length] of slices) {
53895
53990
  if (index === accountIndex) expected += Math.max(0, Math.min(offset + length, value.space) - offset);
53896
53991
  }
53897
53992
  return bytes2.length === expected ? bytes2 : void 0;
53898
53993
  }
53899
- function slicedSnapshot(result, program, pool2, tree) {
53900
- if (result === null || typeof result !== "object" || !Array.isArray(result.value) || result.value.length !== 2) return void 0;
53994
+ function slicedSnapshot(result, program, pool2, tree, programData) {
53995
+ if (result === null || typeof result !== "object" || !Array.isArray(result.value) || result.value.length !== (programData === void 0 ? 2 : 3)) return void 0;
53996
+ const snapshot = slicedPoolSnapshot(result, program, pool2, tree);
53997
+ if (snapshot === void 0 || programData === void 0) return snapshot;
53998
+ const value = result.value[2];
53999
+ const data = slicedAccountBytes(value, 2, POOL_SLICES_WITH_PROGRAMDATA);
54000
+ const newest = result.newestSignature;
54001
+ if (data === void 0 || typeof value.executable !== "boolean" || newest === null || typeof newest !== "object" || typeof newest.signature !== "string" || !Number.isSafeInteger(newest.slot)) {
54002
+ return snapshot;
54003
+ }
54004
+ return withPoolStateOf(snapshot, Object.freeze({
54005
+ ...snapshot,
54006
+ programDataReuse: Object.freeze({
54007
+ slot: snapshot.slot,
54008
+ address: programData.toBase58(),
54009
+ owner: value.owner,
54010
+ executable: value.executable,
54011
+ data,
54012
+ newestSignature: newest.signature
54013
+ })
54014
+ }));
54015
+ }
54016
+ function slicedPoolSnapshot(result, program, pool2, tree) {
53901
54017
  const [poolValue, treeValue] = result.value;
53902
54018
  const poolBytes2 = slicedAccountBytes(poolValue, 0);
53903
54019
  if (poolBytes2 === void 0 || poolValue.space > REFRESH_READ_BYTES) return void 0;
@@ -53926,22 +54042,37 @@ function slicedSnapshot(result, program, pool2, tree) {
53926
54042
  async function readFinalizedPoolSliced(connection, program, pool2) {
53927
54043
  if (typeof connection._rpcRequest !== "function" || slicesRefused(connection)) return void 0;
53928
54044
  const tree = new import_web396.PublicKey(e1TreeAddress2(b58(pool2), b58(program)));
54045
+ const programData = reuseOptionRefused(connection) ? void 0 : programDataAddressOf(program);
54046
+ const params = programData === void 0 ? [[b58(pool2), tree.toBase58()], { commitment: "finalized", slices: POOL_SLICES }] : [
54047
+ [b58(pool2), tree.toBase58(), programData.toBase58()],
54048
+ { commitment: "finalized", slices: POOL_SLICES_WITH_PROGRAMDATA, newestSignature: 2 }
54049
+ ];
53929
54050
  let response;
53930
54051
  try {
53931
- response = await connection._rpcRequest(P03_POOL_SLICES_METHOD, [[b58(pool2), tree.toBase58()], { commitment: "finalized", slices: POOL_SLICES }]);
54052
+ response = await connection._rpcRequest(P03_POOL_SLICES_METHOD, params);
53932
54053
  } catch (error) {
54054
+ if (programData !== void 0 && /-32602\b/.test(String(error?.message ?? ""))) {
54055
+ rememberReuseOptionRefused(connection);
54056
+ markPhase("pool-sliced-reuse-refused");
54057
+ return readFinalizedPoolSliced(connection, program, pool2);
54058
+ }
53933
54059
  if (slicesMethodMissing(error)) rememberSlicesRefused(connection);
53934
54060
  markPhase(`pool-sliced-fallback-${reuseRefusalCause(error)}`);
53935
54061
  return void 0;
53936
54062
  }
53937
54063
  if (response?.error !== void 0) {
54064
+ if (programData !== void 0 && response.error?.code === -32602) {
54065
+ rememberReuseOptionRefused(connection);
54066
+ markPhase("pool-sliced-reuse-refused");
54067
+ return readFinalizedPoolSliced(connection, program, pool2);
54068
+ }
53938
54069
  if (response.error?.code === -32601 || response.error?.code === -32602) rememberSlicesRefused(connection);
53939
54070
  markPhase("pool-sliced-fallback-refused");
53940
54071
  return void 0;
53941
54072
  }
53942
54073
  let snapshot;
53943
54074
  try {
53944
- snapshot = slicedSnapshot(response?.result, program, pool2, tree);
54075
+ snapshot = slicedSnapshot(response?.result, program, pool2, tree, programData);
53945
54076
  } catch {
53946
54077
  snapshot = void 0;
53947
54078
  }
@@ -54052,13 +54183,14 @@ async function readProgramDataHeader({ connection, address: address5, snapshotSl
54052
54183
  minContextSlot: snapshotSlot,
54053
54184
  dataSlice: { offset: 0, length: 45 }
54054
54185
  }));
54055
- const observedSlot = safeSlot(account2?.context?.slot, "programdata_snapshot_slot");
54056
- const value = account2?.value;
54186
+ assertProgramDataHeader(safeSlot(account2?.context?.slot, "programdata_snapshot_slot"), account2?.value, { snapshotSlot, deployedAtSlot });
54187
+ }
54188
+ function assertProgramDataHeader(observedSlot, value, { snapshotSlot, deployedAtSlot }) {
54057
54189
  if (observedSlot < snapshotSlot || !value || !canonicalKey(value.owner, "programdata_owner").equals(BPF_LOADER_UPGRADEABLE_PROGRAM_ID) || value.executable === true) {
54058
54190
  throw new Error("p03_history_programdata_account_invalid");
54059
54191
  }
54060
54192
  const data = Buffer.from(value.data);
54061
- if (data.length < 45 || data.readUInt32LE(0) !== 3 || data.readBigUInt64LE(4) !== deployedAtSlot) {
54193
+ if (data.length < PROGRAMDATA_HEADER_BYTES || data.readUInt32LE(0) !== 3 || data.readBigUInt64LE(4) !== deployedAtSlot) {
54062
54194
  throw new Error("p03_history_programdata_identity_invalid");
54063
54195
  }
54064
54196
  }
@@ -54127,7 +54259,11 @@ async function programDataCoverageFor({
54127
54259
  // so one RPC answers both, at or after snapshotSlot, with no history-source floor below it
54128
54260
  // (2026-10-16 c1s: the signature read on the proxy cost a -32016 retry, about 0.2 s).
54129
54261
  // The full attestation and its newest signature keep `connection`. Absent: `connection`.
54130
- reuseConnection = connection
54262
+ reuseConnection = connection,
54263
+ // The pool snapshot's `programDataReuse` (readFinalizedPoolSliced, 2026-10-22): the same two facts
54264
+ // from the same RPC as the pool account, at its slot. Used instead of the two reads only when it
54265
+ // is at `snapshotSlot` and names the cached attestation's address; checked exactly as they are.
54266
+ reuseAnswer
54131
54267
  }) {
54132
54268
  if (deploymentIdentity === void 0) return { coverage: void 0, attestation: void 0, reused: false };
54133
54269
  let priorRefused = false;
@@ -54135,27 +54271,43 @@ async function programDataCoverageFor({
54135
54271
  const key = coverageKey({ program, initialization, deploymentIdentity });
54136
54272
  if (key !== void 0 && prior?.key === key && typeof prior.newestSignature === "string" && prior.coverage?.throughFinalizedSlot <= BigInt(snapshotSlot)) {
54137
54273
  const address5 = new import_web396.PublicKey(prior.coverage.programDataAddress);
54138
- for (let attempt = 1; ; attempt += 1) {
54274
+ const deployedAtSlot = BigInt(prior.coverage.deployedAtSlot);
54275
+ const reuse = (signature2) => {
54276
+ const coverage2 = Object.freeze({ ...prior.coverage, throughFinalizedSlot: BigInt(snapshotSlot) });
54277
+ return { coverage: coverage2, attestation: { key, newestSignature: signature2, coverage: coverage2 }, reused: true };
54278
+ };
54279
+ const pooled = reuseAnswer !== void 0 && reuseAnswer.slot === snapshotSlot && reuseAnswer.address === address5.toBase58() ? reuseAnswer : void 0;
54280
+ if (pooled !== void 0) {
54139
54281
  try {
54140
- const [, newest2] = await Promise.all([
54141
- readProgramDataHeader({
54142
- connection: reuseConnection,
54143
- address: address5,
54144
- snapshotSlot,
54145
- deployedAtSlot: BigInt(prior.coverage.deployedAtSlot)
54146
- }),
54147
- newestSignature(reuseConnection, address5, snapshotSlot)
54148
- ]);
54149
- if (newest2.signature === prior.newestSignature) {
54150
- const coverage2 = Object.freeze({ ...prior.coverage, throughFinalizedSlot: BigInt(snapshotSlot) });
54151
- return { coverage: coverage2, attestation: { key, newestSignature: newest2.signature, coverage: coverage2 }, reused: true };
54282
+ assertProgramDataHeader(pooled.slot, pooled, { snapshotSlot, deployedAtSlot });
54283
+ if (pooled.newestSignature === prior.newestSignature) {
54284
+ markPhase("attest-reuse-in-pool-read");
54285
+ return reuse(pooled.newestSignature);
54152
54286
  }
54153
54287
  cause = "programdata_newest_signature_changed";
54154
- break;
54155
54288
  } catch (error) {
54156
54289
  cause = reuseRefusalCause(error);
54157
- if (attempt >= 2 || typeof onReuseRetry !== "function" || !isTransientRpcError(error)) break;
54158
- await onReuseRetry({ cause });
54290
+ }
54291
+ } else {
54292
+ for (let attempt = 1; ; attempt += 1) {
54293
+ try {
54294
+ const [, newest2] = await Promise.all([
54295
+ readProgramDataHeader({
54296
+ connection: reuseConnection,
54297
+ address: address5,
54298
+ snapshotSlot,
54299
+ deployedAtSlot
54300
+ }),
54301
+ newestSignature(reuseConnection, address5, snapshotSlot)
54302
+ ]);
54303
+ if (newest2.signature === prior.newestSignature) return reuse(newest2.signature);
54304
+ cause = "programdata_newest_signature_changed";
54305
+ break;
54306
+ } catch (error) {
54307
+ cause = reuseRefusalCause(error);
54308
+ if (attempt >= 2 || typeof onReuseRetry !== "function" || !isTransientRpcError(error)) break;
54309
+ await onReuseRetry({ cause });
54310
+ }
54159
54311
  }
54160
54312
  }
54161
54313
  priorRefused = true;
@@ -55603,7 +55755,7 @@ function base58Decode(value) {
55603
55755
  while (zeros < value.length && value[zeros] === "1") zeros += 1;
55604
55756
  return Uint8Array.from(Buffer.concat([Buffer.alloc(zeros), body]));
55605
55757
  }
55606
- var import_web396, b58Cache, b58, REPLAY_STORE_INDEXED, CLOSE_REPLAY_TREE_TAG, EXTEND_ANCHOR_RING_TAG, WIDEN_ANCHOR_RING_TAG, WIDE_ANCHOR_RING_POOL_BYTES, LINK_SUCCESSOR_TAG, IMPORT_REPLAY_LEAVES_TAG, SETTLE_MOVE_TAG, SWEEP_PREDECESSOR_VAULT_TAG, RELINK_SUCCESSOR_TAG, ROTATE_PAYMENT_SETTLER_TAG, IMPORT_A_LEAF_BYTES, IMPORT_MEMBERSHIP_BYTES, IMPORT_PRESENT_SHIFT, IMPORT_MAX_ENTRIES, MOVE_HEAD_BYTES, MOVE_INSERTED_VALUES, DEFAULT_KEY, FIELD_BYTES2, PRIMARY_PROOF_BYTES, SUBTREE_LEAVES, PAGE_SIZE, FIELD_MODULUS3, BPF_LOADER_UPGRADEABLE_PROGRAM_ID, SYSTEM_PROGRAM, TEST_EXECUTABLES, derivationMemo, memo, reviewedExecutables, isProgramDataIdentityError, ASSUMED_ORIGINAL_EXECUTABLE, AUTHENTICATED_HISTORY_REPORTS, HISTORY_ATTESTATIONS, SNAPSHOT_POOL_STATES, REPORT_POOL_STATES, hasExecutableEvidence, P03_FINALIZED_HISTORY_SOURCE_MODEL, P03_PROGRAMDATA_COVERAGE_SOURCE_MODEL, P03_RUN_RECOVER_UNAVAILABLE_FROM_CHAIN, PROFILES, P03_SETTLEMENT_TAGS, P03_INLINE_SETTLEMENT_TAGS, P03_PAYMENT_REPLAY_INDICES, NO_CONTEXTS, REFRESH_READ_BYTES, E1_TREE_HEADER_BYTES, E1_TREE_MAGIC, E1_CHANGELOG_BYTES, E1_CHANGELOGS_OFFSET, E1_RIGHTMOST_OFFSET, E1_LEAF_COUNT_OFFSET, E1_CANOPY_OFFSET, E1_CANOPY_NODES, P03_POOL_SLICES_METHOD, POOL_SLICES, SLICED_ROOTS_OFFSET, SLICED_LEAVES_OFFSET, SLICES_REFUSED_ENDPOINTS, SLICES_REFUSED_CONNECTIONS, HISTORY_FETCH_CONCURRENCY, HISTORY_BULK_TRANSACTIONS, HISTORY_BULK_ADDRESSES, TRANSIENT_RPC_ATTEMPTS, TRANSIENT_RPC_BASE_DELAY_MS, LAGGING_NODE_STEP_OF_BASE, LAGGING_NODE_MAX_RETRIES, LAGGING_NODE_FAST_RETRIES, LAGGING_NODE_SLOW_STEP_OF_BASE, LAGGING_NODE_RPC_CODES, lastVerifiedE1Tree, e1ReplayCounts, e1TreeCandidate;
55758
+ var import_web396, b58Cache, b58, REPLAY_STORE_INDEXED, CLOSE_REPLAY_TREE_TAG, EXTEND_ANCHOR_RING_TAG, WIDEN_ANCHOR_RING_TAG, WIDE_ANCHOR_RING_POOL_BYTES, LINK_SUCCESSOR_TAG, IMPORT_REPLAY_LEAVES_TAG, SETTLE_MOVE_TAG, SWEEP_PREDECESSOR_VAULT_TAG, RELINK_SUCCESSOR_TAG, ROTATE_PAYMENT_SETTLER_TAG, IMPORT_A_LEAF_BYTES, IMPORT_MEMBERSHIP_BYTES, IMPORT_PRESENT_SHIFT, IMPORT_MAX_ENTRIES, MOVE_HEAD_BYTES, MOVE_INSERTED_VALUES, DEFAULT_KEY, FIELD_BYTES2, PRIMARY_PROOF_BYTES, SUBTREE_LEAVES, PAGE_SIZE, FIELD_MODULUS3, BPF_LOADER_UPGRADEABLE_PROGRAM_ID, SYSTEM_PROGRAM, TEST_EXECUTABLES, derivationMemo, memo, reviewedExecutables, isProgramDataIdentityError, ASSUMED_ORIGINAL_EXECUTABLE, AUTHENTICATED_HISTORY_REPORTS, HISTORY_ATTESTATIONS, SNAPSHOT_POOL_STATES, REPORT_POOL_STATES, hasExecutableEvidence, P03_FINALIZED_HISTORY_SOURCE_MODEL, P03_PROGRAMDATA_COVERAGE_SOURCE_MODEL, P03_RUN_RECOVER_UNAVAILABLE_FROM_CHAIN, PROFILES, P03_SETTLEMENT_TAGS, P03_INLINE_SETTLEMENT_TAGS, P03_PAYMENT_REPLAY_INDICES, NO_CONTEXTS, REFRESH_READ_BYTES, E1_TREE_HEADER_BYTES, E1_TREE_MAGIC, E1_CHANGELOG_BYTES, E1_CHANGELOGS_OFFSET, E1_RIGHTMOST_OFFSET, E1_LEAF_COUNT_OFFSET, E1_CANOPY_OFFSET, E1_CANOPY_NODES, P03_POOL_SLICES_METHOD, POOL_SLICES, PROGRAMDATA_HEADER_BYTES, POOL_SLICES_WITH_PROGRAMDATA, SLICED_ROOTS_OFFSET, SLICED_LEAVES_OFFSET, SLICES_REFUSED_ENDPOINTS, SLICES_REFUSED_CONNECTIONS, REUSE_REFUSED_ENDPOINTS, REUSE_REFUSED_CONNECTIONS, PROGRAMDATA_ADDRESSES, HISTORY_FETCH_CONCURRENCY, HISTORY_BULK_TRANSACTIONS, HISTORY_BULK_ADDRESSES, TRANSIENT_RPC_ATTEMPTS, TRANSIENT_RPC_BASE_DELAY_MS, LAGGING_NODE_STEP_OF_BASE, LAGGING_NODE_MAX_RETRIES, LAGGING_NODE_FAST_RETRIES, LAGGING_NODE_SLOW_STEP_OF_BASE, LAGGING_NODE_RPC_CODES, lastVerifiedE1Tree, e1ReplayCounts, e1TreeCandidate;
55607
55759
  var init_walk = __esm({
55608
55760
  "wallet/src/history/walk.mjs"() {
55609
55761
  "use strict";
@@ -55878,10 +56030,15 @@ var init_walk = __esm({
55878
56030
  ...Array.from({ length: E1.bufferSize }, (_, index) => Object.freeze([1, E1_CHANGELOGS_OFFSET + E1_CHANGELOG_BYTES * index, 32])),
55879
56031
  Object.freeze([1, E1_LEAF_COUNT_OFFSET, 4])
55880
56032
  ]);
56033
+ PROGRAMDATA_HEADER_BYTES = 45;
56034
+ POOL_SLICES_WITH_PROGRAMDATA = Object.freeze([...POOL_SLICES, Object.freeze([2, 0, PROGRAMDATA_HEADER_BYTES])]);
55881
56035
  SLICED_ROOTS_OFFSET = E1_TREE_HEADER_BYTES;
55882
56036
  SLICED_LEAVES_OFFSET = SLICED_ROOTS_OFFSET + 32 * E1.bufferSize;
55883
56037
  SLICES_REFUSED_ENDPOINTS = /* @__PURE__ */ new Set();
55884
56038
  SLICES_REFUSED_CONNECTIONS = /* @__PURE__ */ new WeakSet();
56039
+ REUSE_REFUSED_ENDPOINTS = /* @__PURE__ */ new Set();
56040
+ REUSE_REFUSED_CONNECTIONS = /* @__PURE__ */ new WeakSet();
56041
+ PROGRAMDATA_ADDRESSES = /* @__PURE__ */ new Map();
55885
56042
  HISTORY_FETCH_CONCURRENCY = 4;
55886
56043
  HISTORY_BULK_TRANSACTIONS = 256;
55887
56044
  HISTORY_BULK_ADDRESSES = 256;
@@ -57762,6 +57919,8 @@ async function compactP03HistoryReportRun({
57762
57919
  getAccountInfoAndContext: (...args) => boundedOwnRead(() => own.getAccountInfoAndContext(...args)),
57763
57920
  getSignaturesForAddress: (...args) => boundedOwnRead(() => own.getSignaturesForAddress(...args))
57764
57921
  }))(connection.historyRpcOwnConnection) },
57922
+ // The same two facts from the pool account's own read, when it carried them (readFinalizedPoolSliced).
57923
+ ...snapshot2.programDataReuse === void 0 ? {} : { reuseAnswer: snapshot2.programDataReuse },
57765
57924
  program,
57766
57925
  initialization: initialization2,
57767
57926
  snapshotSlot: snapshot2.slot,
@@ -58781,9 +58940,32 @@ function walletHistoryHomeMarks(store) {
58781
58940
  function latestPrewarmedWalletHistory() {
58782
58941
  return latestPrewarm;
58783
58942
  }
58943
+ function untilHistorySourceSilent(walking, startedAt) {
58944
+ const sentBefore = historySourceState().sent;
58945
+ let timer;
58946
+ const silent = new Promise((_resolve, reject) => {
58947
+ const check = () => {
58948
+ const { silentSince, sent } = historySourceState();
58949
+ if (sent > sentBefore && silentSince !== void 0 && Date.now() - Math.max(silentSince, startedAt) >= HISTORY_SOURCE_SILENT_MS) {
58950
+ markPhase("history-source-silent");
58951
+ reject(new Error("history_rpc_failed", { cause: new Error(
58952
+ `history_source_silent: the history source answered no request for ${HISTORY_SOURCE_SILENT_MS / 1e3} s`
58953
+ ) }));
58954
+ return;
58955
+ }
58956
+ timer = setTimeout(check, 1e3);
58957
+ timer.unref?.();
58958
+ };
58959
+ timer = setTimeout(check, 1e3);
58960
+ timer.unref?.();
58961
+ });
58962
+ walking.catch(() => {
58963
+ });
58964
+ return Promise.race([walking, silent]).finally(() => clearTimeout(timer));
58965
+ }
58784
58966
  async function loadWalletP03HistoryNow(args) {
58785
58967
  const startedAt = Date.now();
58786
- const report = await walkWalletP03HistoryNow(args);
58968
+ const report = await untilHistorySourceSilent(walkWalletP03HistoryNow(args), startedAt);
58787
58969
  if (report !== null && typeof report === "object" && !REPORT_STARTED_AT.has(report)) REPORT_STARTED_AT.set(report, startedAt);
58788
58970
  return report;
58789
58971
  }
@@ -63977,6 +64159,7 @@ var init_errorCodes = __esm({
63977
64159
  "history_rpc_failed",
63978
64160
  "history_rpc_invalid",
63979
64161
  "history_shared_walk_slow",
64162
+ "history_source_silent",
63980
64163
  "house_budget_exhausted",
63981
64164
  "house_deposit_above_pool_cap",
63982
64165
  "house_deposit_below_minimum",
@@ -75474,12 +75657,23 @@ async function readFinalizedClock(connection) {
75474
75657
  return Number(timestamp);
75475
75658
  }
75476
75659
  function startFinalizedChainTime(connection, { reuseRecent = false } = {}) {
75660
+ const keyed = typeof connection === "object" && connection !== null;
75477
75661
  const recentClock = () => {
75478
- const last = typeof connection === "object" && connection !== null ? lastClockAnswers.get(connection) : void 0;
75662
+ const last = keyed ? lastClockAnswers.get(connection) : void 0;
75479
75663
  const age = last === void 0 ? Infinity : performance.now() - last.arrivedAt;
75480
75664
  return age <= PROOF_CHAIN_TIME_REUSE_MS ? { time: last.time, age } : void 0;
75481
75665
  };
75482
75666
  const recent = reuseRecent ? recentClock() : void 0;
75667
+ const inFlight = reuseRecent && recent === void 0 && keyed ? clockReadsInFlight.get(connection) : void 0;
75668
+ if (inFlight !== void 0 && performance.now() - inFlight.startedAt <= PROOF_CHAIN_TIME_REUSE_MS) {
75669
+ return async () => {
75670
+ const answer = await inFlight.answer.catch(() => void 0);
75671
+ const age = answer?.time === void 0 ? Infinity : performance.now() - answer.arrivedAt;
75672
+ if (age > EARLY_CHAIN_TIME_MAX_AGE_MS) return readFinalizedClock(connection);
75673
+ markPhase("chain-time-joined");
75674
+ return answer.time + Math.floor(age / 1e3);
75675
+ };
75676
+ }
75483
75677
  if (recent !== void 0) {
75484
75678
  let fallback;
75485
75679
  const timer = setTimeout(() => {
@@ -75504,6 +75698,16 @@ function startFinalizedChainTime(connection, { reuseRecent = false } = {}) {
75504
75698
  });
75505
75699
  early.catch(() => {
75506
75700
  });
75701
+ if (keyed) {
75702
+ const entry = { startedAt, answer: early.then((time) => ({ time, arrivedAt })) };
75703
+ entry.answer.catch(() => {
75704
+ });
75705
+ clockReadsInFlight.set(connection, entry);
75706
+ early.finally(() => {
75707
+ if (clockReadsInFlight.get(connection) === entry) clockReadsInFlight.delete(connection);
75708
+ }).catch(() => {
75709
+ });
75710
+ }
75507
75711
  return async () => {
75508
75712
  const now = performance.now();
75509
75713
  if (arrivedAt === void 0 && now - startedAt > EARLY_CHAIN_TIME_MAX_AGE_MS) return readFinalizedClock(connection);
@@ -75946,7 +76150,7 @@ function assertProvedPaymentBinding(proved, { poolDomain, inputAccountCommitment
75946
76150
  fail15("proved_request_binding_invalid");
75947
76151
  }
75948
76152
  }
75949
- var import_web3106, MODEL_DIR3, seedBytes5, EARLY_CHAIN_TIME_MAX_AGE_MS, settledNoteExits, PROOF_CHAIN_TIME_REUSE_MS, lastClockAnswers, lastProofRecoveries, lastProofRecovery;
76153
+ var import_web3106, MODEL_DIR3, seedBytes5, EARLY_CHAIN_TIME_MAX_AGE_MS, settledNoteExits, PROOF_CHAIN_TIME_REUSE_MS, lastClockAnswers, clockReadsInFlight, lastProofRecoveries, lastProofRecovery;
75950
76154
  var init_prepareRecoveredPayment = __esm({
75951
76155
  "wallet/src/pay/prepareRecoveredPayment.mjs"() {
75952
76156
  "use strict";
@@ -75970,6 +76174,7 @@ var init_prepareRecoveredPayment = __esm({
75970
76174
  settledNoteExits = /* @__PURE__ */ new Map();
75971
76175
  PROOF_CHAIN_TIME_REUSE_MS = 5e3;
75972
76176
  lastClockAnswers = /* @__PURE__ */ new WeakMap();
76177
+ clockReadsInFlight = /* @__PURE__ */ new WeakMap();
75973
76178
  lastProofRecoveries = /* @__PURE__ */ new Map();
75974
76179
  lastProofRecovery = (store) => lastProofRecoveries.get(store.path);
75975
76180
  }
@@ -97516,7 +97721,7 @@ async function payResourceOnce({
97516
97721
  mark("challenge");
97517
97722
  }
97518
97723
  const { requirement, recipient } = validateChallenge(record.paymentRequired, store, url, maximumAtomic, method);
97519
- const chainTime2 = await (chainTimeRead ?? startFinalizedChainTime(connection))();
97724
+ const chainTime2 = await withPhaseScope(mark, "quote", () => (chainTimeRead ?? startFinalizedChainTime(connection))());
97520
97725
  chainTimeRead = void 0;
97521
97726
  if (!requoted && Number.isSafeInteger(chainTime2) && Number(requirement.extra.validBefore) - chainTime2 < QUOTE_MARGIN_SECONDS && store.readWal(`resource-proof-${requestKey}`)?.proved === void 0) {
97522
97727
  requote();
@@ -103224,7 +103429,7 @@ import { dirname as dirname18, isAbsolute as isAbsolute6, join as join18, resolv
103224
103429
  function retiredPoolText(pool2) {
103225
103430
  const next = RETIRED_POOLS[pool2];
103226
103431
  if (!next) return void 0;
103227
- return `pool ${pool2} is retired: the production facilitator now runs pool ${next}, and nothing serves the old pool. It held no user balance when it was retired. Your old wallet file stays where it is; run npx -y shinjuku-shielded@latest setup to make a wallet for the new pool`;
103432
+ return `pool ${pool2} is retired: the production facilitator now runs pool ${next}, and nothing serves the old pool. It held no user balance when it was retired. Your old wallet file stays where it is; run npx -y --no-audit --no-fund shinjuku-shielded@latest setup to make a wallet for the new pool`;
103228
103433
  }
103229
103434
  function setupHome(env = process.env) {
103230
103435
  return resolve18(env.SHIELDED_WALLET_HOME || join18(homedir2(), ".carbon-shielded-wallet"));
@@ -103327,7 +103532,7 @@ function mcpFlagsFromConfig(home, config) {
103327
103532
  }
103328
103533
  function mcpServerEntry({ home, env = process.env } = {}) {
103329
103534
  const custom2 = env.SHIELDED_WALLET_HOME ? { env: { SHIELDED_WALLET_HOME: home } } : {};
103330
- return { command: "npx", args: ["-y", NPX_PACKAGE, "mcp"], ...custom2 };
103535
+ return { command: "npx", args: ["-y", ...NPX_INSTALL_FLAGS, NPX_PACKAGE, "mcp"], ...custom2 };
103331
103536
  }
103332
103537
  function claudeCodeArgs({ home, env = process.env, platform = process.platform } = {}) {
103333
103538
  return [
@@ -103341,6 +103546,7 @@ function claudeCodeArgs({ home, env = process.env, platform = process.platform }
103341
103546
  ...platform === "win32" ? ["cmd", "/c"] : [],
103342
103547
  "npx",
103343
103548
  "-y",
103549
+ ...NPX_INSTALL_FLAGS,
103344
103550
  NPX_PACKAGE,
103345
103551
  "mcp"
103346
103552
  ];
@@ -103390,6 +103596,11 @@ function hostConfigText({ home, env = process.env, platform = process.platform }
103390
103596
  ...json3.split("\n").map((line) => ` ${line}`)
103391
103597
  ].join("\n");
103392
103598
  }
103599
+ function isOlderSetupEntry(existing, entry) {
103600
+ if (!isPlainObject3(existing) || entry.command !== "npx" || !Array.isArray(entry.args)) return false;
103601
+ const older = { ...entry, args: entry.args.filter((arg) => !NPX_INSTALL_FLAGS.includes(arg)) };
103602
+ return older.args.length !== entry.args.length && sameJson(existing, older);
103603
+ }
103393
103604
  function restrictToOwnerWindows(file, { run: run5 = execFileSync2 } = {}) {
103394
103605
  const system32 = join18(process.env.SystemRoot || "C:/Windows", "System32");
103395
103606
  try {
@@ -103422,7 +103633,7 @@ function addToJsonHost(file, entry, { now = /* @__PURE__ */ new Date(), force =
103422
103633
  const existing = current.mcpServers?.[MCP_SERVER_NAME];
103423
103634
  if (existing !== void 0) {
103424
103635
  if (sameJson(existing, entry)) return { file, changed: false };
103425
- if (!force) {
103636
+ if (!force && !isOlderSetupEntry(existing, entry)) {
103426
103637
  throw new Error(`setup_host_config_conflict: the host's config file already has a different "${MCP_SERVER_NAME}" server, so setup left it alone; rerun setup with --force to replace it (the old file is backed up first), or edit it by hand`);
103427
103638
  }
103428
103639
  }
@@ -103469,7 +103680,7 @@ function addToJsonHost(file, entry, { now = /* @__PURE__ */ new Date(), force =
103469
103680
  }
103470
103681
  return { file, changed: true, ...backup ? { backup } : {} };
103471
103682
  }
103472
- var import_web3118, CONFIG_SCHEMA, CONFIG_FILE, NPX_PACKAGE, MCP_SERVER_NAME, P03_BINDING2, PRODUCTION, RETIRED_POOLS, NO_LIMIT_ATOMIC2, DEFAULT_CAPS, OLD_DEFAULT_SETUP_CAPS, OLD_DEFAULT_WALLET_BUDGETS, capText, POSITIVE_ATOMIC2, configPath, homeWalletPath, invalid3, isPubkey, HOST_TARGETS, WINDOWS_SHELL_CODE, isPlainObject3, sameJson;
103683
+ var import_web3118, CONFIG_SCHEMA, CONFIG_FILE, NPX_PACKAGE, NPX_INSTALL_FLAGS, MCP_SERVER_NAME, P03_BINDING2, PRODUCTION, RETIRED_POOLS, NO_LIMIT_ATOMIC2, DEFAULT_CAPS, OLD_DEFAULT_SETUP_CAPS, OLD_DEFAULT_WALLET_BUDGETS, capText, POSITIVE_ATOMIC2, configPath, homeWalletPath, invalid3, isPubkey, HOST_TARGETS, WINDOWS_SHELL_CODE, isPlainObject3, sameJson;
103473
103684
  var init_config2 = __esm({
103474
103685
  "wallet/src/setup/config.mjs"() {
103475
103686
  "use strict";
@@ -103479,6 +103690,7 @@ var init_config2 = __esm({
103479
103690
  CONFIG_SCHEMA = "shinjuku-shielded/config/v1";
103480
103691
  CONFIG_FILE = "config.json";
103481
103692
  NPX_PACKAGE = "shinjuku-shielded";
103693
+ NPX_INSTALL_FLAGS = Object.freeze(["--no-audit", "--no-fund"]);
103482
103694
  MCP_SERVER_NAME = "shinjuku-shielded";
103483
103695
  P03_BINDING2 = "carbon-shielded-exact/svm-v3";
103484
103696
  PRODUCTION = Object.freeze({
@@ -104634,7 +104846,7 @@ function canonicalJson(value) {
104634
104846
  }
104635
104847
  function channelPublicKey(publicKeyHex = CHANNEL_PUBLIC_KEY_HEX) {
104636
104848
  if (typeof publicKeyHex !== "string" || !HEX642.test(publicKeyHex)) {
104637
- throw fail25("wallet_channel_key_unset", "this wallet build carries no release-channel key, so it trusts only the proof-tool set it pins. Update the wallet: npx -y shinjuku-shielded@latest setup");
104849
+ throw fail25("wallet_channel_key_unset", "this wallet build carries no release-channel key, so it trusts only the proof-tool set it pins. Update the wallet: npx -y --no-audit --no-fund shinjuku-shielded@latest setup");
104638
104850
  }
104639
104851
  return createPublicKey5({ key: Buffer.concat([ED25519_SPKI_PREFIX3, Buffer.from(publicKeyHex, "hex")]), format: "der", type: "spki" });
104640
104852
  }
@@ -105387,7 +105599,7 @@ var init_proofTools = __esm({
105387
105599
  sumsSha256: "a9af32df6b7ff7e3243bd607b7ff582da5732fa422f28afd9b8bc3e9f0d6c741"
105388
105600
  })
105389
105601
  });
105390
- UPDATE_NEXT = "update the wallet: npx -y shinjuku-shielded@latest setup";
105602
+ UPDATE_NEXT = "update the wallet: npx -y --no-audit --no-fund shinjuku-shielded@latest setup";
105391
105603
  HEX643 = /^[0-9a-f]{64}$/;
105392
105604
  DIR2 = /^[0-9a-f]{8}$/;
105393
105605
  SUMS_LINE = /^([0-9a-f]{64}) [ *]([A-Za-z0-9._/-]{1,200})$/;
@@ -106667,7 +106879,7 @@ async function poolProofTools({ home, config, entry, release, facilitator, trust
106667
106879
  });
106668
106880
  } catch (error) {
106669
106881
  if (!UNTRUSTED.test(String(error?.message))) throw error;
106670
- throw fail32("wallet_move_proof_tools_untrusted", `the facilitator names proof-tool set ${set.dir} (SHA256SUMS ${set.sumsSha256}) for pool ${entry.pool}, and neither this wallet build's pin nor the signed release channel vouches for it; nothing was downloaded or moved. Update the wallet (npx -y shinjuku-shielded@latest), or (advanced) after you checked that set out of band run shinjuku-wallet move --trust-proof-tools ${set.sumsSha256} (repeat the flag once per set)`);
106882
+ throw fail32("wallet_move_proof_tools_untrusted", `the facilitator names proof-tool set ${set.dir} (SHA256SUMS ${set.sumsSha256}) for pool ${entry.pool}, and neither this wallet build's pin nor the signed release channel vouches for it; nothing was downloaded or moved. Update the wallet (npx -y --no-audit --no-fund shinjuku-shielded@latest), or (advanced) after you checked that set out of band run shinjuku-wallet move --trust-proof-tools ${set.sumsSha256} (repeat the flag once per set)`);
106671
106883
  }
106672
106884
  }
106673
106885
  const tools = await (deps.installProofTools ?? installProofTools)({ facilitator, toolsRoot: join23(home, "proof-tools"), expected: trusted, fetchImpl });
@@ -106803,7 +107015,7 @@ var init_migration = __esm({
106803
107015
  fail32 = (code2, detail) => new Error(`${code2}: ${detail}`);
106804
107016
  releaseInvalid = (why) => fail32(
106805
107017
  "wallet_move_release_invalid",
106806
- `the facilitator's release document names its pools in a shape this wallet does not accept (${why}); nothing was moved. Update the wallet (npx -y shinjuku-shielded@latest), then run shinjuku-wallet move again`
107018
+ `the facilitator's release document names its pools in a shape this wallet does not accept (${why}); nothing was moved. Update the wallet (npx -y --no-audit --no-fund shinjuku-shielded@latest), then run shinjuku-wallet move again`
106807
107019
  );
106808
107020
  isPubkey2 = (value) => {
106809
107021
  try {
@@ -108027,7 +108239,7 @@ function refusalSay(a, tool, again) {
108027
108239
  return unshown ? "Not sent. This app answered the send question before you could see it. Use an app that shows the question." : "Not sent. The send was not confirmed.";
108028
108240
  }
108029
108241
  if (code2 === "mcp_setup_declined" && unshown) {
108030
- return "Not set up. This app cannot show the setup question. Run npx -y shinjuku-shielded setup in a terminal, then restart this app.";
108242
+ return "Not set up. This app cannot show the setup question. Run npx -y --no-audit --no-fund shinjuku-shielded setup in a terminal, then restart this app.";
108031
108243
  }
108032
108244
  if (code2 === "mcp_setup_declined") return "Not set up. The setup was not confirmed; nothing was created.";
108033
108245
  if (code2 === "mcp_tool_disabled") return "Nothing was paid or moved. This tool is off; only your owner can turn it on when starting the wallet.";
@@ -108135,8 +108347,8 @@ function addFundsHeldSay(entries, have = "") {
108135
108347
  if (!nowAny && waiting === 0n) return "";
108136
108348
  const lead = (text3) => have ? `${have}; ${text3}` : `${text3[0].toUpperCase()}${text3.slice(1)}`;
108137
108349
  const now = !nowUnknown ? `${usdcText(nowHeld)} USDC is becoming private now` : nowHeld > 0n ? `${usdcText(nowHeld)} USDC and an amount still being read are becoming private now` : "an amount still being read is becoming private now";
108138
- const later = startMinutes !== null ? `within about 1 minute of your next wallet request${startMinutes > 0 ? ` after about ${minutesText(startMinutes)}` : ""}` : minutesKnown && minutes !== null ? `in about ${minutesText(minutes)}` : "in a few minutes";
108139
- const askLater = startMinutes !== null && startMinutes > 0 ? `a random privacy wait ends in about ${minutesText(startMinutes)}: ask then; it is private 1 minute later` : null;
108350
+ const later = startMinutes !== null ? "in about 1 minute (or at your next ask)" : minutesKnown && minutes !== null ? `in about ${minutesText(minutes)}` : "in a few minutes";
108351
+ const askLater = startMinutes !== null && startMinutes > 0 ? `a random privacy wait ends in about ${minutesText(startMinutes)}: ask then, and again 1 minute later` : null;
108140
108352
  if (nowAny && waiting > 0n) return askLater ? `${lead(`${now}; ${usdcText(waiting)} USDC more is in a random privacy wait: ask in about ${minutesText(startMinutes)}`)}.` : `${lead(`${now}, and ${usdcText(waiting)} USDC more ${later}`)}.`;
108141
108353
  if (nowAny) return `${lead(now)}. Nothing to do.`;
108142
108354
  const arrived = askLater ? `${usdcText(waiting)} USDC arrived; ${askLater}` : `${usdcText(waiting)} USDC arrived and becomes private ${later === "in a few minutes" ? "within a few minutes of your next wallet request" : later}`;
@@ -109679,7 +109891,7 @@ var init_job = __esm({
109679
109891
  ],
109680
109892
  wallet_move_proof_tools_untrusted: [
109681
109893
  "the facilitator names a proof-tool set for a pool of this move that neither this wallet build's pin nor the signed release channel vouches for (see proofToolSet); nothing was downloaded or moved",
109682
- "update the wallet (npx -y shinjuku-shielded@latest), or (advanced) after you checked that set out of band run shinjuku-wallet move --trust-proof-tools <its SHA256SUMS hash>, once per set"
109894
+ "update the wallet (npx -y --no-audit --no-fund shinjuku-shielded@latest), or (advanced) after you checked that set out of band run shinjuku-wallet move --trust-proof-tools <its SHA256SUMS hash>, once per set"
109683
109895
  ],
109684
109896
  wallet_move_proof_tools_unavailable: [
109685
109897
  "the proof tools of a pool of this move could not be downloaded or checked (see toolsCode); nothing was moved, and the tools recorded before stay",
@@ -109736,7 +109948,7 @@ var init_job = __esm({
109736
109948
  wallet_succession_leg_in_flight: ["a move to the new pool is on its way; your money is safe and counts once in your balance", "nothing to do; it lands in about a minute"],
109737
109949
  wallet_succession_target_untrusted: [
109738
109950
  "the switch record names a new pool this wallet does not trust, so nothing moves; your money is safe in the old pool",
109739
- "tell the operator; update the wallet (npx -y shinjuku-shielded@latest)"
109951
+ "tell the operator; update the wallet (npx -y --no-audit --no-fund shinjuku-shielded@latest)"
109740
109952
  ],
109741
109953
  wallet_succession_leg_conflict: ["another copy of this wallet used the same money in the new pool, so this move stopped; nothing was paid", "tell the operator"]
109742
109954
  });
@@ -116433,7 +116645,7 @@ function floatRefusal(error) {
116433
116645
  return [
116434
116646
  code2,
116435
116647
  `Shinjuku refused to forward this seller's payment terms${why}; nothing was paid`,
116436
- "Nothing was paid. Do not retry this URL unchanged. If Shinjuku's words name this wallet's pool, tell your owner to run npx -y shinjuku-shielded@latest setup"
116648
+ "Nothing was paid. Do not retry this URL unchanged. If Shinjuku's words name this wallet's pool, tell your owner to run npx -y --no-audit --no-fund shinjuku-shielded@latest setup"
116437
116649
  ];
116438
116650
  }
116439
116651
  default:
@@ -118640,7 +118852,7 @@ ${canonical5}`;
118640
118852
  return refuse11(
118641
118853
  code2,
118642
118854
  rest || "your private connection (the Tor proxy) is not answering; nothing was paid",
118643
- `Nothing was paid and nothing was sent. Start Tor (or run npx -y shinjuku-shielded@latest setup again), then call ${tool} again with request_id "${requestId}" and ${same2} (it never pays twice)`,
118855
+ `Nothing was paid and nothing was sent. Start Tor (or run npx -y --no-audit --no-fund shinjuku-shielded@latest setup again), then call ${tool} again with request_id "${requestId}" and ${same2} (it never pays twice)`,
118644
118856
  { requestId, paid: false }
118645
118857
  );
118646
118858
  } else if (code2.startsWith("wallet_quote_refused_") || code2.startsWith("fetch_")) {
@@ -118648,7 +118860,8 @@ ${canonical5}`;
118648
118860
  } else {
118649
118861
  next = inference ? `the outcome is not known to be final: ${resume}. Or close an unsent payment with wallet_cancel request_id "${requestId}"; wallet_receipts lists it if it was paid` : `the outcome is not known to be final: call x402_pay again with request_id "${requestId}" (it never pays twice), or close an unsent payment with wallet_cancel request_id "${requestId}"; wallet_receipts lists it if it was paid`;
118650
118862
  }
118651
- return refuse11(code2, rest || "the payment did not finish", next, { requestId });
118863
+ const plainRest = /^[a-z0-9]+(_[a-z0-9]+)+$/.test(rest ?? "") ? PLAIN_REASONS.find(([match]) => match.test(rest))?.[1] : void 0;
118864
+ return refuse11(code2, plainRest ? `the payment did not finish: ${plainRest}` : rest || "the payment did not finish", next, { requestId });
118652
118865
  }
118653
118866
  const linkHeldSeen = /* @__PURE__ */ new Map();
118654
118867
  const LINK_HELD_FRESH_MS = 6e4;
@@ -119044,7 +119257,7 @@ ${canonical5}`;
119044
119257
  const arrivingAll = addFundsOpen.filter((link2) => link2.landed !== true && (link2.state === "shielding" || /^[1-9][0-9]*$/.test(String(link2.heldAtomic ?? ""))));
119045
119258
  const arrivingLine = (arriving) => {
119046
119259
  const amount = /^[1-9][0-9]*$/.test(String(arriving.shieldingAtomic ?? "")) ? `${usdcText2(arriving.shieldingAtomic)} USDC` : /^[1-9][0-9]*$/.test(String(arriving.heldAtomic ?? "")) ? `${usdcText2(arriving.heldAtomic)} USDC` : "USDC (an amount still being read)";
119047
- const when = arriving.state === "shielding" && !arriving.startsAtNextRequest ? "is becoming private now (its deposit transaction was sent; about 1 minute)" : arriving.startsInMinutes > 0 ? `waits about ${minutesText2(arriving.startsInMinutes)} (a random wait hides the link to the deposit); call wallet_balance again after that, and it becomes private within about 1 minute of that request; no step for the user` : "becomes private: its deposit started with this request and takes about 1 minute; if this wallet process ends first, the next wallet request continues it";
119260
+ const when = arriving.state === "shielding" && !arriving.startsAtNextRequest ? "is becoming private now (its deposit transaction was sent; about 1 minute)" : arriving.startsInMinutes > 0 ? `waits about ${minutesText2(arriving.startsInMinutes)} (a random wait hides the link to the deposit); call wallet_balance again after that (that request starts the deposit), and once more about 1 minute later if it is not private yet (a host that ends this process after each answer needs that one); no step for the user` : "becomes private: its deposit started with this request and takes about 1 minute; if this wallet process ends first, the next wallet request continues it";
119048
119261
  return `${amount} arrived at add-funds address "${arriving.requestId}" and ${when}`;
119049
119262
  };
119050
119263
  if (arrivingAll.length === 1) {
@@ -119120,7 +119333,7 @@ ${canonical5}`;
119120
119333
  } catch {
119121
119334
  }
119122
119335
  const sessionLeft = sessionLeftShown(policy, countStore);
119123
- const sessionSummary = `Spending limits: ${capWords(policy.limits.maxPaymentAtomic)} per payment and ${capWords(policy.limits.maxSessionAtomic)} in any 24 hours, for this wallet (every MCP process counts; a pool upgrade starts a new 24-hour count)${sessionLeft === null ? "" : ` (${usdcText2(sessionLeft)} USDC left now)`}; ${usdcText2(policy.sessionSpentAtomic) ?? "0"} USDC paid in the last 24 hours. They come from this MCP server's launch line in the host (--max-payment and --max-session, in USDC like 0.05), else from the limits setup recorded. To change them, edit those flags in the host's MCP entry, or run npx -y shinjuku-shielded setup --yes --max-payment <usdc> --max-session <usdc> in a terminal; then restart the host. The wallet file also holds its own limits (--max-payment, and --max-cumulative for all payments together): npx -y shinjuku-shielded limits shows and changes them`;
119336
+ const sessionSummary = `Spending limits: ${capWords(policy.limits.maxPaymentAtomic)} per payment and ${capWords(policy.limits.maxSessionAtomic)} in any 24 hours, for this wallet (every MCP process counts; a pool upgrade starts a new 24-hour count)${sessionLeft === null ? "" : ` (${usdcText2(sessionLeft)} USDC left now)`}; ${usdcText2(policy.sessionSpentAtomic) ?? "0"} USDC paid in the last 24 hours. They come from this MCP server's launch line in the host (--max-payment and --max-session, in USDC like 0.05), else from the limits setup recorded. To change them, edit those flags in the host's MCP entry, or run npx -y --no-audit --no-fund shinjuku-shielded setup --yes --max-payment <usdc> --max-session <usdc> in a terminal; then restart the host. The wallet file also holds its own limits (--max-payment, and --max-cumulative for all payments together): npx -y --no-audit --no-fund shinjuku-shielded limits shows and changes them`;
119124
119337
  return json2({
119125
119338
  ok: true,
119126
119339
  ...reportPublic,
@@ -119915,7 +120128,10 @@ ${canonical5}`;
119915
120128
  function jobFailure(kind, job, error, linkHeld = /* @__PURE__ */ new Map()) {
119916
120129
  const line = describeError(error, { fallback: KINDS[kind].failCode, safeText: SAFE_TEXT });
119917
120130
  let code2 = line.split(/[\s:;(]/, 1)[0];
119918
- let detail = line.slice(code2.length).replace(/^[:;]\s*/, "").trim() || `the ${KINDS[kind].noun} did not finish`;
120131
+ const plain = PLAIN_REASONS.find(([match]) => match.test(code2))?.[1];
120132
+ let detail = line.slice(code2.length).replace(/^[:;]\s*/, "").trim() || (plain ? `the ${KINDS[kind].noun} did not finish: ${plain}` : `the ${KINDS[kind].noun} did not finish`);
120133
+ const plainDetail = /^[a-z0-9]+(_[a-z0-9]+)+$/.test(detail) ? PLAIN_REASONS.find(([match]) => match.test(detail))?.[1] : void 0;
120134
+ if (plainDetail) detail = `the ${KINDS[kind].noun} did not finish: ${plainDetail}`;
119919
120135
  let next;
119920
120136
  let joinStage = false;
119921
120137
  const joinAt = () => job.joinAtMs ??= joinStartOf(job);
@@ -122782,7 +122998,7 @@ ${canonical5}`;
122782
122998
  const torRefusal = () => refuse11(
122783
122999
  "inference_tor_required",
122784
123000
  "inference sends the prompt to usePod and the model's provider, so this wallet sends it only from a --tor or --proxy run, where they see the proxy's exit and not this machine's IP. This MCP server was started without --tor or --proxy; nothing was sent or paid",
122785
- "Tell the user to add --tor to this MCP server's launch line in the host (for example `npx -y shinjuku-shielded mcp --tor`, with Tor's HTTPTunnelPort 127.0.0.1:9080 on), or --proxy http://host:port for an HTTP proxy they trust, then restart the server and call inference_chat again"
123001
+ "Tell the user to add --tor to this MCP server's launch line in the host (for example `npx -y --no-audit --no-fund shinjuku-shielded mcp --tor`, with Tor's HTTPTunnelPort 127.0.0.1:9080 on), or --proxy http://host:port for an HTTP proxy they trust, then restart the server and call inference_chat again"
122786
123002
  );
122787
123003
  const inferenceModels = {
122788
123004
  name: "inference_models",
@@ -124067,6 +124283,9 @@ var init_tools = __esm({
124067
124283
  [/^mcp_balance_unknown$|no_spendable_account/, "the balance could not be read yet"],
124068
124284
  [/insufficient/, "an open payment held part of the balance"],
124069
124285
  [POOL_LAYOUT_CODE, "this wallet version cannot read the pool (a newer version can)"],
124286
+ // ab-18 2026-10-22: a 445 s unshield answered only "the unshield did not finish".
124287
+ [/^history_source_silent$/, "the pool's public history source answered nothing for 60 s (with --tor, a slow or dead Tor circuit)"],
124288
+ [/^history_rpc_failed$|compact_history_source_unavailable/, "the pool's public history did not answer in time (with --tor, a slow or dead Tor circuit)"],
124070
124289
  [/memo_service|relay|facilitator|unavailable|rate_limited|fetch|timeout|timed_out|network|socket|econn|rpc|blockhash/i, "the facilitator or the network did not answer"],
124071
124290
  [/prove|proof|prover/, "the private proof did not finish"]
124072
124291
  ];
@@ -124178,7 +124397,7 @@ var init_tools = __esm({
124178
124397
  "inference_models",
124179
124398
  "wallet_receive_shielded"
124180
124399
  ]);
124181
- SETUP_TERMINAL_NEXT = "Tell the user to run `npx -y shinjuku-shielded setup` in a terminal on this machine, then restart this MCP server in the host";
124400
+ SETUP_TERMINAL_NEXT = "Tell the user to run `npx -y --no-audit --no-fund shinjuku-shielded setup` in a terminal on this machine, then restart this MCP server in the host";
124182
124401
  SETUP_POLL_NEXT = `call shinjuku_setup again in ${POLL_SECONDS3} s for the status (it never creates a second wallet)`;
124183
124402
  PRIVATE_INFERENCE_WHY = "Your agent then buys AI answers from usePod, paid from your shielded balance over Tor; usePod and the model see the prompt, not who paid.";
124184
124403
  PRIVATE_INFERENCE_NEXT = " Private inference is on: config.json records Tor, so restart this MCP server in the host now; it then runs behind Tor (Tor must run with HTTPTunnelPort 127.0.0.1:9080), and until then every wallet tool and inference_chat stay refused. After the restart: fund the wallet with wallet_add_funds (it gives a one-time address; USDC sent there from any wallet becomes private a few minutes after it arrives, at the next wallet call; no other step), then call inference_chat (with no prompt it lists the models; a short qwen3-8-flash answer costs about 0.001 USDC, 0.011 USDC when usePod offers only its standard payment).";
@@ -124510,11 +124729,11 @@ function startUpdateNotice({ facilitator, log = () => {
124510
124729
  const ready = check === false ? Promise.resolve() : Promise.resolve().then(() => check({ facilitator })).then((found) => {
124511
124730
  if (!found) return;
124512
124731
  update3 = found;
124513
- log(`MCP_UPDATE_AVAILABLE release=${found.current} running=${found.running}: restart this MCP server to load it (a fixed-version host: npx -y ${NPX_PACKAGE}@latest mcp); nothing was downloaded`);
124732
+ log(`MCP_UPDATE_AVAILABLE release=${found.current} running=${found.running}: restart this MCP server to load it (a fixed-version host: npx -y --no-audit --no-fund ${NPX_PACKAGE}@latest mcp); nothing was downloaded`);
124514
124733
  }, () => {
124515
124734
  });
124516
124735
  let shown = false;
124517
- const field4 = () => ({ available: true, release: update3.current, running: update3.running, command: `npx -y ${NPX_PACKAGE}@latest mcp`, detail: updateNoticeLine(update3) });
124736
+ const field4 = () => ({ available: true, release: update3.current, running: update3.running, command: `npx -y --no-audit --no-fund ${NPX_PACKAGE}@latest mcp`, detail: updateNoticeLine(update3) });
124518
124737
  return {
124519
124738
  ready,
124520
124739
  current: () => update3,
@@ -125178,7 +125397,7 @@ var init_stdioServer = __esm({
125178
125397
  UPDATE_NOTICE_TOOLS = Object.freeze(["wallet_balance", "x402_pay", "inference_chat"]);
125179
125398
  UPDATE_NOTICE_MAX_TEXT = 262144;
125180
125399
  UPDATE_NOTICE_TEXT = "A new wallet version is ready. Restart this MCP server in your app (or restart the app): each start loads the latest version. Nothing was downloaded or changed yet, and this version keeps working until then.";
125181
- updateNoticeLine = (update3) => `Tell the user: ${UPDATE_NOTICE_TEXT} (release ${update3.current}; this wallet runs ${update3.running}; a host that starts a fixed version runs npx -y ${NPX_PACKAGE}@latest mcp instead.)`;
125400
+ updateNoticeLine = (update3) => `Tell the user: ${UPDATE_NOTICE_TEXT} (release ${update3.current}; this wallet runs ${update3.running}; a host that starts a fixed version runs npx -y --no-audit --no-fund ${NPX_PACKAGE}@latest mcp instead.)`;
125182
125401
  LAUNCH_NOTICE_TOOLS = Object.freeze(["wallet_balance", "wallet_status"]);
125183
125402
  withLaunchLine = (instructions2, line) => !line ? instructions2 : () => `${typeof instructions2 === "function" ? instructions2() : instructions2} Tell the user: ${line}`;
125184
125403
  capRequired = (detail) => {
@@ -146015,7 +146234,7 @@ function identityOf(facilitator, release, successors = []) {
146015
146234
  const pool2 = successors.includes(served.pool) ? served.pool : PRODUCTION.pool;
146016
146235
  for (const [name, value] of Object.entries(served)) {
146017
146236
  if (value !== null && value !== void 0 && value !== (name === "pool" ? pool2 : PRODUCTION[name])) {
146018
- throw fail40("setup_identity_mismatch", `the production facilitator's release names another ${name} than this wallet build, and no signed succession links it; nothing was created. Run npx -y shinjuku-shielded@latest setup; if the latest build says the same, the facilitator is not serving the production pool`);
146237
+ throw fail40("setup_identity_mismatch", `the production facilitator's release names another ${name} than this wallet build, and no signed succession links it; nothing was created. Run npx -y --no-audit --no-fund shinjuku-shielded@latest setup; if the latest build says the same, the facilitator is not serving the production pool`);
146019
146238
  }
146020
146239
  }
146021
146240
  return { pool: pool2, program: PRODUCTION.program, network: PRODUCTION.network, asset: PRODUCTION.asset };
@@ -151328,7 +151547,7 @@ async function runMcpFirstRun(values, deps) {
151328
151547
  ` : "Shinjuku Shielded is not set up on this machine yet (no config.json, wallet, passphrase file, or proof tools).\n");
151329
151548
  const answer = String(await deps.ask("Set up Shinjuku Shielded now? (y/n) ")).trim();
151330
151549
  if (!/^y(es)?$/i.test(answer)) {
151331
- throw new PublicFailure("mcp_not_set_up: the wallet is not set up, so the MCP server did not start and nothing was created; run shinjuku-wallet setup (npx -y shinjuku-shielded setup) when you are ready");
151550
+ throw new PublicFailure("mcp_not_set_up: the wallet is not set up, so the MCP server did not start and nothing was created; run shinjuku-wallet setup (npx -y --no-audit --no-fund shinjuku-shielded setup) when you are ready");
151332
151551
  }
151333
151552
  const setupValues = new Map(Object.entries(setupOptionsOf(values, home)).filter(([key]) => key !== "home").map(([key, value]) => [`--${key.replace(/[A-Z]/g, (c) => `-${c.toLowerCase()}`)}`, value]));
151334
151553
  await runSetupCommand(setupValues, deps);
@@ -151576,6 +151795,7 @@ function addToHosts(targets, home, deps, { force = false } = {}) {
151576
151795
  const status = deps.runClaudeCli(claudeCodeArgs(options));
151577
151796
  io.out(status === 0 ? "Added to Claude Code (user scope).\n" : `Claude Code did not take the server (claude CLI exit ${status}); run it yourself:
151578
151797
  ${claudeCodeCommand(options)}
151798
+ (if it says the server already exists, run claude mcp remove --scope user ${MCP_SERVER_NAME} first, then the line above)
151579
151799
  `);
151580
151800
  continue;
151581
151801
  }
@@ -151624,7 +151844,7 @@ async function runSetupCommand(values, deps) {
151624
151844
  if (interactive && !deps.stdinIsTTY()) {
151625
151845
  const line = ["setup", "--yes", ...setupArgvOf(values), ...childRunProxy(deps.env).args].map(shellWord).join(" ");
151626
151846
  throw new UsageError(
151627
- `setup asks its questions in a terminal; in a script or a pipe pass --yes: npx -y shinjuku-shielded ${line} (add any of --max-payment, --max-session, --max-cumulative, --prefer-tor, --private-inference)`,
151847
+ `setup asks its questions in a terminal; in a script or a pipe pass --yes: npx -y --no-audit --no-fund shinjuku-shielded ${line} (add any of --max-payment, --max-session, --max-cumulative, --prefer-tor, --private-inference)`,
151628
151848
  COMMAND_BY_NAME.get("setup")
151629
151849
  );
151630
151850
  }
@@ -151639,7 +151859,7 @@ async function runSetupCommand(values, deps) {
151639
151859
  ...introduced ? [] : [
151640
151860
  "Shinjuku Shielded: a self-custody wallet that pays x402 URLs privately from a shielded USDC balance.",
151641
151861
  "Setup makes the wallet on this machine (your keys never leave it), downloads and checks the proof tools, and writes config.json.",
151642
- "An agent host then starts it with one command: npx -y shinjuku-shielded mcp",
151862
+ "An agent host then starts it with one command: npx -y --no-audit --no-fund shinjuku-shielded mcp",
151643
151863
  ""
151644
151864
  ],
151645
151865
  old ? `Status: ${missing.includes("pool-retired") ? `set up before for a retired pool: ${retiredPoolText(old.pool).split("; run ")[0]}. This run moves config.json to the new pool and makes its wallet` : missing.length ? `set up before; missing now: ${missing.join(", ")}` : "set up; every piece is checked again"} (home ${home}).` : `Home: ${home}`,
@@ -152424,7 +152644,7 @@ var COMMANDS = [
152424
152644
  `${CLI2} mcp --max-payment 0.05 --max-session 0.2 --max-shield 2 --unshield-to <your public address> --max-unshield 1 --exit-proof-tools exit-proof-tools.json --profile public-profile.json ${PAYER_SESSION_BASE}`
152425
152645
  ],
152426
152646
  notes: [
152427
- `Zero config: after ${CLI2} setup (npx -y shinjuku-shielded setup), mcp with no --pool and no --wallet reads config.json from SHIELDED_WALLET_HOME (default ~/.carbon-shielded-wallet): the wallet, the passphrase file, the proof tools, the caps, and Tor. A flag on the command line still wins. Agent host config: npx -y shinjuku-shielded mcp (Claude Code: claude mcp add --scope user shinjuku-shielded -- npx -y shinjuku-shielded mcp). Before setup, mcp in a terminal asks to run setup; started by an agent host (stdin is not a terminal), it serves SETUP MODE: shinjuku_setup and wallet_status, and every money tool answers wallet_not_set_up. shinjuku_setup asks the user to confirm in the host (MCP elicitation; never a secret), runs setup in the background (the same call answers its stage), then switches the same server to the wallet tools (notifications/tools/list_changed). A host without elicitation is told to run setup in a terminal.`,
152647
+ `Zero config: after ${CLI2} setup (npx -y --no-audit --no-fund shinjuku-shielded setup), mcp with no --pool and no --wallet reads config.json from SHIELDED_WALLET_HOME (default ~/.carbon-shielded-wallet): the wallet, the passphrase file, the proof tools, the caps, and Tor. A flag on the command line still wins. Agent host config: npx -y --no-audit --no-fund shinjuku-shielded mcp (Claude Code: claude mcp add --scope user shinjuku-shielded -- npx -y --no-audit --no-fund shinjuku-shielded mcp). Before setup, mcp in a terminal asks to run setup; started by an agent host (stdin is not a terminal), it serves SETUP MODE: shinjuku_setup and wallet_status, and every money tool answers wallet_not_set_up. shinjuku_setup asks the user to confirm in the host (MCP elicitation; never a secret), runs setup in the background (the same call answers its stage), then switches the same server to the wallet tools (notifications/tools/list_changed). A host without elicitation is told to run setup in a terminal.`,
152428
152648
  `Add it to an agent host with one line, for example Claude Code: claude mcp add shinjuku-pay -- node shinjuku-wallet.mjs mcp --max-payment 0.05 --max-session 0.2 --tor ${PAYER_SESSION_BASE} (the passphrase comes from ${PASSPHRASE_ENV2} or --passphrase-file; never a tool argument).`,
152429
152649
  `Claude Desktop, or any MCP host that takes a JSON config (claude_desktop_config.json: "mcpServers"), with absolute paths (yours differ; on Windows write C:/Users/you/...): {"mcpServers":{"shinjuku-pay":{"command":"node","args":["/home/you/shinjuku/shinjuku-wallet.mjs","mcp","--max-payment","0.05","--max-session","0.2","--pool","${GUIDE.pool}","--passphrase-file","/home/you/shinjuku/passphrase.txt","--proof-tools","/home/you/shinjuku/proof-tools.json","--program","${GUIDE.program}","--memo-service","${GUIDE.facilitator}","--tor"],"env":{"SHIELDED_WALLET_HOME":"/home/you/.shielded-wallet"}}}}. A host starts the server from its own folder, so a relative path does not work there. Without --rpc-file the RPC reads go to the facilitator relay.`,
152430
152650
  "Payments, in this order: shielded-exact (needs --proof-tools), then standard exact through Shinjuku (you pay Shinjuku privately, price + a small fee; Shinjuku pays the seller). A seller that offers only scheme confidential (hidden amounts) is refused, and nothing is paid: hidden-amount payments are retired (the program behind them closed on 2026-10-11).",
@@ -152462,9 +152682,9 @@ var COMMANDS = [
152462
152682
  bool2("--private-inference", 'answer yes to "Set your LLM to private inference now?": your agent buys AI answers from usePod, paid from your shielded balance over Tor. Records inference.enabled and Tor (as --prefer-tor) in config.json, and prints the path to the first private call. Without it, --yes keeps what config.json records'),
152463
152683
  flag2("--passphrase-file", "<file>", "your own passphrase file (8 or more characters); default: setup writes a new random passphrase to <home>/passphrase.txt, readable by you alone. Needed for a wallet that exists already"),
152464
152684
  flag2("--facilitator", "<https origin>", `the facilitator whose release, pool, and proof tools setup uses; default ${GUIDE.facilitator}`, { check: "origin" }),
152465
- flag2("--add-to", "<claude-code|claude-desktop|cursor>", "also add the server (npx -y shinjuku-shielded mcp) to this agent host's config; repeat it for more. Without it, setup prints the configs", { repeat: true }),
152685
+ flag2("--add-to", "<claude-code|claude-desktop|cursor>", "also add the server (npx -y --no-audit --no-fund shinjuku-shielded mcp) to this agent host's config; repeat it for more. Without it, setup prints the configs", { repeat: true }),
152466
152686
  bool2("--force", "with --add-to: replace a different shinjuku-shielded entry already in a JSON host config (the old file is backed up first, mode 0600)"),
152467
- flag2("--trust-proof-tools", "<sha256>", "ADVANCED: install the proof-tool set whose SHA256SUMS has this SHA-256 instead of the set this wallet build pins (needed for a facilitator the build does not pin). Check the set out of band first; the normal fix for a new set is npx -y shinjuku-shielded@latest setup")
152687
+ flag2("--trust-proof-tools", "<sha256>", "ADVANCED: install the proof-tool set whose SHA256SUMS has this SHA-256 instead of the set this wallet build pins (needed for a facilitator the build does not pin). Check the set out of band first; the normal fix for a new set is npx -y --no-audit --no-fund shinjuku-shielded@latest setup")
152468
152688
  ],
152469
152689
  examples: [
152470
152690
  `${CLI2} setup --yes`,
@@ -152472,20 +152692,20 @@ var COMMANDS = [
152472
152692
  `${CLI2} setup --yes --private-inference`
152473
152693
  ],
152474
152694
  notes: [
152475
- "npx -y shinjuku-shielded setup runs the same command. Without --yes it asks in the terminal: the caps (Enter keeps the default), Tor, and private inference.",
152695
+ "npx -y --no-audit --no-fund shinjuku-shielded setup runs the same command. Without --yes it asks in the terminal: the caps (Enter keeps the default), Tor, and private inference.",
152476
152696
  `When Tor is recorded or asked for (a yes, --tor, --prefer-tor, or --private-inference), setup itself runs behind Tor: the release, the proof-tool downloads, and the RPC requests go over Tor, so the facilitator never sees this machine's IP address make the wallet. config.json then records Tor for mcp ("tor": true), so the MCP runs behind Tor too. Tor must run first (torrc: HTTPTunnelPort 127.0.0.1:9080); --no-tor runs it without Tor.`,
152477
152697
  `Private inference (a yes, or --private-inference): ${PRIVATE_INFERENCE_WHY} Setup records Tor, then prints five steps with real commands: add-funds (it shields the USDC), the first call (${CLI2} infer - --model qwen3-8-flash ... --tor, about 0.0011 USDC = 1100 atomic; its --max-payment must cover the 10000 = 0.01 USDC ceiling plus the fee), infer serve for an OpenAI client, and an MCP restart for inference_chat. In a terminal it then offers to run add-funds; it never pays an inference call.`,
152478
152698
  "The wallet home is SHIELDED_WALLET_HOME, default ~/.carbon-shielded-wallet (every command of this CLI uses it). setup writes there: config.json, passphrase.txt (mode 0600; on Windows an access list of your account alone), the wallet (<pool>/wallet.json, made by init with the production pool, program, network, and USDC), a recovery file recovery-<time>.txt, and proof-tools/<dir>/.",
152479
152699
  "The passphrase is never printed and no MCP tool takes or returns it. The recovery file holds the seed and the key: copy it to two offline places, then delete it from this machine.",
152480
- "The proof tools are the set this wallet build PINS (its SHA256SUMS hash is in the wallet; --trust-proof-tools replaces it). A facilitator whose /api/wallet/release names another set is refused (setup_proof_tools_pin_mismatch: update the wallet, npx -y shinjuku-shielded@latest setup). SHA256SUMS must have the pinned SHA-256, and every file must have the SHA-256 its line names, as /skill.md section 7b; bin/ and house/bin/ get the execute bit. A file that does not match is not kept. Each download has a hard size limit.",
152700
+ "The proof tools are the set this wallet build PINS (its SHA256SUMS hash is in the wallet; --trust-proof-tools replaces it). A facilitator whose /api/wallet/release names another set is refused (setup_proof_tools_pin_mismatch: update the wallet, npx -y --no-audit --no-fund shinjuku-shielded@latest setup). SHA256SUMS must have the pinned SHA-256, and every file must have the SHA-256 its line names, as /skill.md section 7b; bin/ and house/bin/ get the execute bit. A file that does not match is not kept. Each download has a hard size limit.",
152481
152701
  "Your own --passphrase-file must be private: on Linux and macOS setup refuses a file that group or other may read or write, or that another user owns (setup_passphrase_file_insecure: chmod 600 <file>). On Windows setup cannot read the access list; it accepts the file with a warning.",
152482
152702
  "--add-to for Claude Desktop or Cursor: a host config whose mcpServers is not a JSON object, or that has a different shinjuku-shielded entry (without --force), is left alone. Otherwise the old file is copied to <file>.bak-<time> (mode 0600 on Linux and macOS; on Windows the folder's access list) and the new file replaces it in one rename.",
152483
152703
  "The provers are Linux programs. Linux: ready. Windows: the wallet runs them through WSL; setup checks that wsl.exe runs (wsl --install -d Ubuntu otherwise). macOS: not supported; setup says so and creates nothing.",
152484
152704
  "Run it again at any time: it never changes an existing wallet, keeps the recorded caps unless you pass new ones, checks every proof-tool file again, downloads what is missing or newer, and rewrites config.json.",
152485
- "Then mcp needs no flags: npx -y shinjuku-shielded mcp reads config.json (a flag on the command line still wins). Before setup, mcp in a terminal offers to run setup; started by an agent host, it serves shinjuku_setup, which runs this same setup after you confirm in the host.",
152705
+ "Then mcp needs no flags: npx -y --no-audit --no-fund shinjuku-shielded mcp reads config.json (a flag on the command line still wins). Before setup, mcp in a terminal offers to run setup; started by an agent host, it serves shinjuku_setup, which runs this same setup after you confirm in the host.",
152486
152706
  "A command that takes --pool (balance, recover, deposit, add-funds, and others) takes it, and the passphrase of this home's wallet, from config.json when you leave them out: shinjuku-wallet balance needs no flags. A pocket command (pocket list, scan, reshield, release, fill) takes this home's --wallet and passphrase file the same way, and --program, --proof-tools, --facilitator when it needs them. A flag or SHIELDED_WALLET_PASSPHRASE still wins; init and restore never use config.json, and move reads it itself."
152487
152707
  ],
152488
- next: `start it from your agent host with npx -y shinjuku-shielded mcp (or ${CLI2} mcp), then ask your agent "what is my balance"`,
152708
+ next: `start it from your agent host with npx -y --no-audit --no-fund shinjuku-shielded mcp (or ${CLI2} mcp), then ask your agent "what is my balance"`,
152489
152709
  run: (args, values, deps, io) => deps.setupMain(values, { ...deps, io })
152490
152710
  },
152491
152711
  {
@@ -152851,7 +153071,7 @@ var COMMANDS = [
152851
153071
  flags: [
152852
153072
  bool2("--dry-run", "show what would move from local files only: no network call, nothing changes"),
152853
153073
  flag2("--rpc-file", "<file>", RPC_FILE_ABOUT),
152854
- flag2("--trust-proof-tools", "<sha256>", "ADVANCED: trust the proof-tool set whose SHA256SUMS has this SHA-256 for a pool of this move, when neither this wallet build's pin nor the signed release channel vouches for it (wallet_move_proof_tools_untrusted names the set). Repeat it once per set. Check each set out of band first; the normal fix is npx -y shinjuku-shielded@latest", { repeat: true })
153074
+ flag2("--trust-proof-tools", "<sha256>", "ADVANCED: trust the proof-tool set whose SHA256SUMS has this SHA-256 for a pool of this move, when neither this wallet build's pin nor the signed release channel vouches for it (wallet_move_proof_tools_untrusted names the set). Repeat it once per set. Check each set out of band first; the normal fix is npx -y --no-audit --no-fund shinjuku-shielded@latest", { repeat: true })
152855
153075
  ],
152856
153076
  examples: [`${CLI2} move --dry-run`, `${CLI2} move`],
152857
153077
  notes: [
@@ -153075,9 +153295,9 @@ function overviewText() {
153075
153295
  `Usage: ${CLI2} <command> [flags]`,
153076
153296
  ` ${CLI2} help <command> one command, with an example that works`,
153077
153297
  "",
153078
- "Start here (one command): npx -y shinjuku-shielded setup",
153298
+ "Start here (one command): npx -y --no-audit --no-fund shinjuku-shielded setup",
153079
153299
  " It makes the wallet, a private passphrase file, the checked proof tools, and config.json, and prints the lines for your agent host",
153080
- " (the host then runs npx -y shinjuku-shielded mcp). Then ask your agent to add funds (wallet_add_funds, from 0.01 USDC).",
153300
+ " (the host then runs npx -y --no-audit --no-fund shinjuku-shielded mcp). Then ask your agent to add funds (wallet_add_funds, from 0.01 USDC).",
153081
153301
  "",
153082
153302
  "Manual set up (advanced, without setup):",
153083
153303
  " export SHIELDED_WALLET_HOME=<a private directory>",
@@ -153104,7 +153324,7 @@ function overviewText() {
153104
153324
  ` facilitator ${GUIDE.facilitator}`,
153105
153325
  "",
153106
153326
  "Exit codes: 0 done; 1 the command ran and failed (one-line reason); 2 the command line is wrong (shows a working example).",
153107
- `Start here: npx -y shinjuku-shielded setup (or ${CLI2} setup), then the agent host runs npx -y shinjuku-shielded mcp, and your agent adds funds with wallet_add_funds (from 0.01 USDC).`,
153327
+ `Start here: npx -y --no-audit --no-fund shinjuku-shielded setup (or ${CLI2} setup), then the agent host runs npx -y --no-audit --no-fund shinjuku-shielded mcp, and your agent adds funds with wallet_add_funds (from 0.01 USDC).`,
153108
153328
  `Manual path, without setup: ${CLI2} help init, then ${CLI2} help add-funds (whole USDC only).`,
153109
153329
  `Lost the wallet file? ${CLI2} help restore (from the init recovery file)`,
153110
153330
  ""
@@ -154434,7 +154654,7 @@ function floatFailureHint(reason, floatError) {
154434
154654
  if (/p03_float_origin_missing/.test(reason)) return "nothing was paid: pass --memo-service, the facilitator that pays standard exact sellers for you";
154435
154655
  if (/p03_float_body_too_large/.test(reason)) return "nothing was paid: this seller's payment terms are larger than 12 KiB, too large to forward. Do not pay this seller";
154436
154656
  if (/p03_float_request_refused/.test(reason)) {
154437
- return "nothing was paid: Shinjuku refused to forward this seller's payment terms (its code follows p03_float_request_refused). Do not retry unchanged; float_body_invalid about refundTo means this wallet is on another pool than the facilitator: run npx -y shinjuku-shielded@latest setup";
154657
+ return "nothing was paid: Shinjuku refused to forward this seller's payment terms (its code follows p03_float_request_refused). Do not retry unchanged; float_body_invalid about refundTo means this wallet is on another pool than the facilitator: run npx -y --no-audit --no-fund shinjuku-shielded@latest setup";
154438
154658
  }
154439
154659
  if (/p03_float_already_paid/.test(reason)) {
154440
154660
  return "Shinjuku records this payment as paid, but this wallet holds no record of that payment: do not pay again. Keep the wallet folder as it is and rerun the same command with the same --request-id";