shinjuku-shielded 0.3.184 → 0.3.185

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
@@ -6,13 +6,13 @@ answers privately, in a terminal chat or for your agent app. Its `mcp`
6
6
  command runs a local MCP server (stdio) for your agent. Your keys never
7
7
  leave your machine.
8
8
 
9
- This is version 0.3.184. The npm packages `shinjuku-shield` and
9
+ This is version 0.3.185. The npm packages `shinjuku-shield` and
10
10
  `shinjuku-shielded` hold the same files. The command is `shinjuku`.
11
11
 
12
12
  ## Set up
13
13
 
14
14
  ```sh
15
- npx -y shinjuku@0.3.184 setup
15
+ npx -y shinjuku@0.3.185 setup
16
16
  ```
17
17
 
18
18
  Setup offers to install the `shinjuku` command and, on Windows, adds npm's
@@ -35,13 +35,13 @@ Every wallet command works after `shinjuku`, for example `shinjuku balance`,
35
35
  Claude Code:
36
36
 
37
37
  ```sh
38
- claude mcp add --scope user shinjuku -- npx -y --no-audit --no-fund shinjuku-shield@0.3.184 mcp
38
+ claude mcp add --scope user shinjuku -- npx -y --no-audit --no-fund shinjuku-shield@0.3.185 mcp
39
39
  ```
40
40
 
41
41
  Claude Desktop (`claude_desktop_config.json`) or Cursor (`~/.cursor/mcp.json`):
42
42
 
43
43
  ```json
44
- { "mcpServers": { "shinjuku": { "command": "npx", "args": ["-y", "--no-audit", "--no-fund", "shinjuku-shield@0.3.184", "mcp"] } } }
44
+ { "mcpServers": { "shinjuku": { "command": "npx", "args": ["-y", "--no-audit", "--no-fund", "shinjuku-shield@0.3.185", "mcp"] } } }
45
45
  ```
46
46
 
47
47
  On native Windows, if the host cannot find `npx`, use `"command": "cmd"` and
@@ -54,7 +54,7 @@ Codex (the Codex app and Codex CLI read the same file, `~/.codex/config.toml`):
54
54
  ```toml
55
55
  [mcp_servers.shinjuku]
56
56
  command = "npx"
57
- args = ["-y", "--no-audit", "--no-fund", "shinjuku-shield@0.3.184", "mcp"]
57
+ args = ["-y", "--no-audit", "--no-fund", "shinjuku-shield@0.3.185", "mcp"]
58
58
  startup_timeout_sec = 120
59
59
  tool_timeout_sec = 300
60
60
  ```
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": "fed76293d7f682c50f249284a7f4bbf14d2d6c7d8926c052c6ef1f683419b8dd",
5
- "bytes": 9349716,
6
- "sourceCommit": "37820c4cf40bdbd57dece9d1b739e1c541f534ed",
4
+ "sha256": "cab378d1d911f907711de448e5c6525febcd0e73ff8988efcb4ae7d1fa82e961",
5
+ "bytes": 9351549,
6
+ "sourceCommit": "0e77401ed1e90cd6fa9035028ac5098ae6abbb6e",
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",
@@ -1038,5 +1038,5 @@
1038
1038
  "version": "1.8.0"
1039
1039
  }
1040
1040
  ],
1041
- "publishedAt": "2026-11-06T16:14:51.926Z"
1041
+ "publishedAt": "2026-11-06T17:17:10.158Z"
1042
1042
  }
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "shinjuku-shielded",
3
- "version": "0.3.184",
3
+ "version": "0.3.185",
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": "fed76293",
7
- "shinjukuSha256": "fed76293d7f682c50f249284a7f4bbf14d2d6c7d8926c052c6ef1f683419b8dd",
6
+ "shinjukuRelease": "cab378d1",
7
+ "shinjukuSha256": "cab378d1d911f907711de448e5c6525febcd0e73ff8988efcb4ae7d1fa82e961",
8
8
  "license": "SEE LICENSE IN LICENSE.txt",
9
9
  "author": "Shinjuku Shielded",
10
10
  "homepage": "https://github.com/ShinjukuStaition/shinjuku-shield#readme",
@@ -588,6 +588,16 @@ function processLockAddress(name, platform = process.platform) {
588
588
  if (platform === "linux") return `\0shinjuku-lock-${hash12}`;
589
589
  return join2(tmpdir2(), `shinjuku-lock-${hash12.slice(0, 32)}.sock`);
590
590
  }
591
+ async function processLockFree(name) {
592
+ const address4 = processLockAddress(name);
593
+ try {
594
+ (await listen(address4)).close();
595
+ return true;
596
+ } catch (error) {
597
+ if (!["EADDRINUSE", "EACCES"].includes(error?.code)) throw error;
598
+ }
599
+ return process.platform === "darwin" ? deadSocketFile(address4) : false;
600
+ }
591
601
  async function takeProcessLock(name, {
592
602
  onWait = () => {
593
603
  },
@@ -83641,7 +83651,7 @@ var init_p03LoopLag = __esm({
83641
83651
  });
83642
83652
 
83643
83653
  // src/server/payments/shielded/p03IndexedReplay.ts
83644
- var import_web3110, ERROR_KINDS, P03_E1_MOVE_INPUTS, MOVE_VALUE_INDICES, MOVE_HEAD_BYTES3, UPGRADEABLE_LOADER, TOKEN_PROGRAM, E1_CHANGELOG_BYTES2, P03_E1_TREE_READ_BYTES, rpcHttpFetch;
83654
+ var import_web3110, P03_E1_BEHIND_RETRY_MS, P03_E1_BEHIND_RETRIES, P03_E1_BEHIND_POLL_MS, P03_E1_BEHIND_KEEPS, ERROR_KINDS, P03_E1_MOVE_INPUTS, MOVE_VALUE_INDICES, MOVE_HEAD_BYTES3, UPGRADEABLE_LOADER, TOKEN_PROGRAM, E1_CHANGELOG_BYTES2, P03_E1_TREE_READ_BYTES, rpcHttpFetch;
83645
83655
  var init_p03IndexedReplay = __esm({
83646
83656
  "src/server/payments/shielded/p03IndexedReplay.ts"() {
83647
83657
  "use strict";
@@ -83653,6 +83663,10 @@ var init_p03IndexedReplay = __esm({
83653
83663
  init_p03MinContextSlotRetry();
83654
83664
  init_p03LoopLag();
83655
83665
  init_ShieldedSolanaP03Types();
83666
+ P03_E1_BEHIND_RETRY_MS = 1e3;
83667
+ P03_E1_BEHIND_RETRIES = 2;
83668
+ P03_E1_BEHIND_POLL_MS = 200;
83669
+ P03_E1_BEHIND_KEEPS = P03_E1_BEHIND_RETRIES * (1 + Math.floor((P03_E1_BEHIND_RETRY_MS - 1) / P03_E1_BEHIND_POLL_MS));
83656
83670
  ERROR_KINDS = /* @__PURE__ */ new Map([
83657
83671
  [E1_ERROR_CODES2.E1NotInGap, "not-in-gap"],
83658
83672
  [E1_ERROR_CODES2.E1LeafModified, "leaf-modified"],
@@ -156463,15 +156477,18 @@ function freePort() {
156463
156477
  var failure2 = (plain, detail, extra = {}) => Object.assign(new Error(detail ?? plain), { plain, ...extra });
156464
156478
  var sleep4 = (ms) => new Promise((resolvePromise) => setTimeout(resolvePromise, ms));
156465
156479
  var tunnelOf = (port) => `http://127.0.0.1:${port}`;
156466
- function takeLock(home, say2) {
156467
- mkdirSync(managedTorDir(home), { recursive: true, mode: 448 });
156480
+ function lockName(home) {
156468
156481
  let real = home;
156469
156482
  try {
156470
156483
  real = realpathSync.native(home);
156471
156484
  } catch {
156472
156485
  }
156473
156486
  if (process.platform === "win32" || process.platform === "darwin") real = real.toLowerCase();
156474
- return takeProcessLock(`tor-start ${real}`, {
156487
+ return `tor-start ${real}`;
156488
+ }
156489
+ function takeLock(home, say2) {
156490
+ mkdirSync(managedTorDir(home), { recursive: true, mode: 448 });
156491
+ return takeProcessLock(lockName(home), {
156475
156492
  waitEveryMs: Infinity,
156476
156493
  onWait: () => say2("Waiting for Tor, which is starting in the background."),
156477
156494
  lostError: () => failure2("another start took over. Ask again", "the start lock was taken over")
@@ -156532,6 +156549,13 @@ async function installBundle(home, say2) {
156532
156549
  `);
156533
156550
  renameSync(unpacking, target);
156534
156551
  }
156552
+ function bootstrappedSince(home, from) {
156553
+ try {
156554
+ return /Bootstrapped 100%/.test(readFileSync(logFile(home), "utf8").slice(Number.isInteger(from) ? from : 0));
156555
+ } catch {
156556
+ return false;
156557
+ }
156558
+ }
156535
156559
  async function waitBootstrapped(home, alive2, from) {
156536
156560
  const until = Date.now() + BOOTSTRAP_TIMEOUT_MS;
156537
156561
  for (; ; ) {
@@ -156611,9 +156635,27 @@ async function startTor(home, port, say2, assertHeld = () => {
156611
156635
  child.once("exit", () => {
156612
156636
  ended2 = true;
156613
156637
  });
156638
+ let stopped = false;
156639
+ const endStart = () => {
156640
+ if (!ended2) child.kill();
156641
+ try {
156642
+ rmSync(stateFile(home), { force: true });
156643
+ } catch {
156644
+ }
156645
+ };
156646
+ const onStop = (signal) => {
156647
+ stopped = true;
156648
+ if (!bootstrappedSince(home, from)) endStart();
156649
+ if (process.listenerCount(signal) === 1) process.exit(signal === "SIGINT" ? 130 : 143);
156650
+ };
156651
+ const stopSignals = ["SIGINT", "SIGTERM"];
156652
+ for (const signal of stopSignals) process.on(signal, onStop);
156614
156653
  await new Promise((resolvePromise, reject) => {
156615
156654
  child.once("error", (error) => reject(blocked(error)));
156616
156655
  child.once("spawn", resolvePromise);
156656
+ }).catch((error) => {
156657
+ for (const signal of stopSignals) process.off(signal, onStop);
156658
+ throw error;
156617
156659
  });
156618
156660
  child.unref();
156619
156661
  try {
@@ -156628,14 +156670,13 @@ async function startTor(home, port, say2, assertHeld = () => {
156628
156670
  );
156629
156671
  }
156630
156672
  say2("Starting Tor in the background (a few seconds; up to a minute the first time).");
156631
- await waitBootstrapped(home, () => !ended2, from);
156673
+ await waitBootstrapped(home, () => !ended2 && !stopped, from);
156632
156674
  } catch (error) {
156633
- if (!ended2) child.kill();
156634
- try {
156635
- rmSync(stateFile(home), { force: true });
156636
- } catch {
156637
- }
156675
+ if (!stopped || !bootstrappedSince(home, from)) endStart();
156676
+ if (stopped) throw failure2("you stopped the start with Ctrl+C, so Tor was stopped too. Ask again to start it", "the Tor start was stopped (Ctrl+C)");
156638
156677
  throw error;
156678
+ } finally {
156679
+ for (const signal of stopSignals) process.off(signal, onStop);
156639
156680
  }
156640
156681
  }
156641
156682
  async function recordTunnel(home, tunnel) {
@@ -156644,7 +156685,7 @@ async function recordTunnel(home, tunnel) {
156644
156685
  } catch {
156645
156686
  }
156646
156687
  }
156647
- async function ownTorReady(home, state2) {
156688
+ async function ownTorReady(home, state2, { wait: wait2 = true } = {}) {
156648
156689
  if (!state2 || !pidAlive4(state2.pid)) return void 0;
156649
156690
  let now;
156650
156691
  try {
@@ -156656,6 +156697,7 @@ async function ownTorReady(home, state2) {
156656
156697
  let own = await controlCheck(home, state2);
156657
156698
  if (own?.tunnelPort !== state2.port) return void 0;
156658
156699
  if (own.progress < 100) {
156700
+ if (!wait2) return void 0;
156659
156701
  await waitBootstrapped(home, () => pidAlive4(state2.pid), Number.isInteger(state2.logFrom) ? state2.logFrom : 0);
156660
156702
  own = await controlCheck(home, state2);
156661
156703
  if (own?.tunnelPort !== state2.port || own.progress < 100) return void 0;
@@ -156719,8 +156761,9 @@ async function ensureWalletTor(proxy, { env = process.env, platform = process.pl
156719
156761
  const ownPort = ownPortOf(home);
156720
156762
  if (explicit && Number(url.port) !== ownPort) return proxy;
156721
156763
  try {
156722
- const ready = await ownTorReady(home, managedTorState(home));
156723
- if (ready) {
156764
+ const known = managedTorState(home);
156765
+ const ready = await ownTorReady(home, known, { wait: false });
156766
+ if (ready && await processLockFree(lockName(home)) && pidAlive4(known.pid)) {
156724
156767
  await recordTunnel(home, ready);
156725
156768
  return ready;
156726
156769
  }