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 +5 -5
- package/manifest.json +4 -4
- package/package.json +3 -3
- package/shinjuku-wallet.mjs +56 -13
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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": "
|
|
5
|
-
"bytes":
|
|
6
|
-
"sourceCommit": "
|
|
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-
|
|
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.
|
|
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": "
|
|
7
|
-
"shinjukuSha256": "
|
|
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",
|
package/shinjuku-wallet.mjs
CHANGED
|
@@ -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
|
|
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
|
|
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 (!
|
|
156634
|
-
|
|
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
|
|
156723
|
-
|
|
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
|
}
|