shinjuku-shielded 0.3.167 → 0.3.168
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 +6 -6
- package/manifest.json +4 -4
- package/package.json +3 -3
- package/shinjuku-wallet.mjs +308 -235
package/README.md
CHANGED
|
@@ -6,19 +6,19 @@ 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.168. 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
|
-
npm install -g shinjuku@0.3.
|
|
15
|
+
npm install -g shinjuku@0.3.168
|
|
16
16
|
shinjuku setup
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
Type the two lines as they are. `npx install shinjuku` does not work: npx
|
|
20
20
|
reads `install` as the name of another npm package. To set up without
|
|
21
|
-
installing, type `npx shinjuku@0.3.
|
|
21
|
+
installing, type `npx shinjuku@0.3.168 setup`.
|
|
22
22
|
|
|
23
23
|
Setup makes the wallet on this machine, a private passphrase file, and the
|
|
24
24
|
checked proof tools (about 191 MB), and writes `config.json`. It also writes
|
|
@@ -36,13 +36,13 @@ Every wallet command works after `shinjuku`, for example `shinjuku balance`,
|
|
|
36
36
|
Claude Code:
|
|
37
37
|
|
|
38
38
|
```sh
|
|
39
|
-
claude mcp add --scope user shinjuku -- npx -y --no-audit --no-fund shinjuku-shield@0.3.
|
|
39
|
+
claude mcp add --scope user shinjuku -- npx -y --no-audit --no-fund shinjuku-shield@0.3.168 mcp
|
|
40
40
|
```
|
|
41
41
|
|
|
42
42
|
Claude Desktop (`claude_desktop_config.json`) or Cursor (`~/.cursor/mcp.json`):
|
|
43
43
|
|
|
44
44
|
```json
|
|
45
|
-
{ "mcpServers": { "shinjuku": { "command": "npx", "args": ["-y", "--no-audit", "--no-fund", "shinjuku-shield@0.3.
|
|
45
|
+
{ "mcpServers": { "shinjuku": { "command": "npx", "args": ["-y", "--no-audit", "--no-fund", "shinjuku-shield@0.3.168", "mcp"] } } }
|
|
46
46
|
```
|
|
47
47
|
|
|
48
48
|
On native Windows, if the host cannot find `npx`, use `"command": "cmd"` and
|
|
@@ -55,7 +55,7 @@ Codex (the Codex app and Codex CLI read the same file, `~/.codex/config.toml`):
|
|
|
55
55
|
```toml
|
|
56
56
|
[mcp_servers.shinjuku]
|
|
57
57
|
command = "npx"
|
|
58
|
-
args = ["-y", "--no-audit", "--no-fund", "shinjuku-shield@0.3.
|
|
58
|
+
args = ["-y", "--no-audit", "--no-fund", "shinjuku-shield@0.3.168", "mcp"]
|
|
59
59
|
startup_timeout_sec = 120
|
|
60
60
|
tool_timeout_sec = 300
|
|
61
61
|
```
|
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": "7320b9c07d69b0d94e0ee25c1821e1f674dde5964c65e84fe3de3be6c1ff7170",
|
|
5
|
+
"bytes": 9306006,
|
|
6
|
+
"sourceCommit": "f3e7665265b2adae937b45163fff7116c6c7bd00",
|
|
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-05T04:16:16.938Z"
|
|
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.168",
|
|
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": "7320b9c0",
|
|
7
|
+
"shinjukuSha256": "7320b9c07d69b0d94e0ee25c1821e1f674dde5964c65e84fe3de3be6c1ff7170",
|
|
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
|
@@ -53952,28 +53952,175 @@ var init_processLock = __esm({
|
|
|
53952
53952
|
}
|
|
53953
53953
|
});
|
|
53954
53954
|
|
|
53955
|
+
// wallet/src/setup/userPath.mjs
|
|
53956
|
+
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
53957
|
+
import { basename as basename3, join as join8 } from "node:path";
|
|
53958
|
+
function commandFolder({ env = process.env, platform = process.platform } = {}) {
|
|
53959
|
+
const prefix = env.npm_config_global_prefix || env.npm_config_prefix;
|
|
53960
|
+
if (platform === "win32") return prefix || (env.APPDATA ? join8(env.APPDATA, "npm") : void 0);
|
|
53961
|
+
return prefix ? `${String(prefix).replace(/\/+$/, "")}/bin` : void 0;
|
|
53962
|
+
}
|
|
53963
|
+
function commandFileIn(folder, platform = process.platform) {
|
|
53964
|
+
if (!folder) return void 0;
|
|
53965
|
+
const file = join8(folder, platform === "win32" ? `${COMMAND_PACKAGE}.cmd` : COMMAND_PACKAGE);
|
|
53966
|
+
try {
|
|
53967
|
+
if (!statSync(file).isFile()) return void 0;
|
|
53968
|
+
if (platform !== "win32") accessSync(file, constants.X_OK);
|
|
53969
|
+
return file;
|
|
53970
|
+
} catch {
|
|
53971
|
+
return void 0;
|
|
53972
|
+
}
|
|
53973
|
+
}
|
|
53974
|
+
function shellPathEntries({ env = process.env, platform = process.platform } = {}) {
|
|
53975
|
+
const pathValue = env.PATH ?? env.Path ?? env.path ?? "";
|
|
53976
|
+
const entries = String(pathValue).split(platform === "win32" ? ";" : ":");
|
|
53977
|
+
let last = -1;
|
|
53978
|
+
entries.forEach((each, index) => {
|
|
53979
|
+
if (/[\\/]node-gyp-bin[\\/]*$/i.test(each.trim())) last = index;
|
|
53980
|
+
});
|
|
53981
|
+
return entries.slice(last + 1);
|
|
53982
|
+
}
|
|
53983
|
+
function folderOnPath(folder, { env = process.env, platform = process.platform } = {}) {
|
|
53984
|
+
const key = folderKey(folder, platform);
|
|
53985
|
+
return shellPathEntries({ env, platform }).some((each) => each.trim() && folderKey(each, platform) === key);
|
|
53986
|
+
}
|
|
53987
|
+
function addFolderToUserPath(folder, { run: run2 = spawnSync2, env = process.env } = {}) {
|
|
53988
|
+
let result;
|
|
53989
|
+
try {
|
|
53990
|
+
result = run2(
|
|
53991
|
+
"powershell.exe",
|
|
53992
|
+
[
|
|
53993
|
+
"-NoProfile",
|
|
53994
|
+
"-NonInteractive",
|
|
53995
|
+
"-ExecutionPolicy",
|
|
53996
|
+
"Bypass",
|
|
53997
|
+
"-EncodedCommand",
|
|
53998
|
+
Buffer.from(ADD_SCRIPT, "utf16le").toString("base64")
|
|
53999
|
+
],
|
|
54000
|
+
{ windowsHide: true, encoding: "utf8", timeout: 6e4, env: { ...env, SHINJUKU_PATH_FOLDER: folder } }
|
|
54001
|
+
);
|
|
54002
|
+
} catch {
|
|
54003
|
+
return { state: "failed", reason: "Windows PowerShell did not start" };
|
|
54004
|
+
}
|
|
54005
|
+
const line = String(result?.stdout ?? "").trim().split(/\r?\n/).reverse().find((each) => each.startsWith("{"));
|
|
54006
|
+
try {
|
|
54007
|
+
const answer = JSON.parse(line ?? "");
|
|
54008
|
+
if (["present", "added", "failed"].includes(answer?.state)) return answer;
|
|
54009
|
+
} catch {
|
|
54010
|
+
}
|
|
54011
|
+
return { state: "failed", reason: "Windows PowerShell gave no answer" };
|
|
54012
|
+
}
|
|
54013
|
+
function shellProfileLine(folder, { env = process.env, platform = process.platform } = {}) {
|
|
54014
|
+
const shell = basename3(String(env.SHELL ?? ""));
|
|
54015
|
+
if (shell === "fish") return { file: "~/.config/fish/config.fish", line: `fish_add_path '${String(folder).replace(/[\\']/g, "\\$&")}'` };
|
|
54016
|
+
const file = shell === "zsh" ? "~/.zshrc" : shell === "bash" ? platform === "darwin" ? "~/.bash_profile" : "~/.bashrc" : "~/.profile";
|
|
54017
|
+
return { file, line: `export PATH='${String(folder).replace(/'/g, "'\\''")}':"$PATH"` };
|
|
54018
|
+
}
|
|
54019
|
+
function commandPathStep({ env = process.env, platform = process.platform, run: run2 = spawnSync2 } = {}) {
|
|
54020
|
+
const folder = commandFolder({ env, platform });
|
|
54021
|
+
if (!commandFileIn(folder, platform)) return { state: "no-command", folder };
|
|
54022
|
+
if (platform !== "win32") {
|
|
54023
|
+
return folderOnPath(folder, { env, platform }) ? { state: "on-path", folder } : { state: "profile", folder, ...shellProfileLine(folder, { env, platform }) };
|
|
54024
|
+
}
|
|
54025
|
+
return { folder, ...addFolderToUserPath(folder, { run: run2, env }), thisWindow: folderOnPath(folder, { env, platform }) };
|
|
54026
|
+
}
|
|
54027
|
+
function pathStepSays(step) {
|
|
54028
|
+
return ["added", "failed", "profile"].includes(step?.state) || step?.state === "present" && step.thisWindow === false;
|
|
54029
|
+
}
|
|
54030
|
+
function commandPathLines(step, hereLine) {
|
|
54031
|
+
const here3 = ["In this window, type the longer command, for example:", ` ${hereLine}`];
|
|
54032
|
+
if (step?.state === "added") {
|
|
54033
|
+
return [step.broadcast === false ? "Added Shinjuku to your PATH. Sign out of Windows and in again, then type shinjuku in a new window." : "Added Shinjuku to your PATH. Open a new window to type shinjuku.", ...here3];
|
|
54034
|
+
}
|
|
54035
|
+
if (step?.state === "present") return ["Shinjuku is on your PATH. Open a new window to type shinjuku.", ...here3];
|
|
54036
|
+
if (step?.state === "failed") {
|
|
54037
|
+
return [
|
|
54038
|
+
`Setup could not add Shinjuku to your PATH (${step.reason}). To add it yourself: open Start, type environment variables, open "Edit environment variables for your account", pick Path, choose Edit, then New, and paste this folder:`,
|
|
54039
|
+
` ${step.folder}`,
|
|
54040
|
+
"Then open a new window to type shinjuku.",
|
|
54041
|
+
...here3
|
|
54042
|
+
];
|
|
54043
|
+
}
|
|
54044
|
+
if (step?.state === "profile") {
|
|
54045
|
+
return [
|
|
54046
|
+
`Your terminal does not look in the folder where npm put the shinjuku command. Add this line to the end of ${step.file}, then open a new terminal to type shinjuku:`,
|
|
54047
|
+
` ${step.line}`,
|
|
54048
|
+
...here3
|
|
54049
|
+
];
|
|
54050
|
+
}
|
|
54051
|
+
return [];
|
|
54052
|
+
}
|
|
54053
|
+
var folderKey, ADD_SCRIPT;
|
|
54054
|
+
var init_userPath = __esm({
|
|
54055
|
+
"wallet/src/setup/userPath.mjs"() {
|
|
54056
|
+
"use strict";
|
|
54057
|
+
init_fs();
|
|
54058
|
+
init_config();
|
|
54059
|
+
folderKey = (folder, platform) => {
|
|
54060
|
+
const key = String(folder).trim().replace(/^"(.*)"$/, "$1").replace(/[\\/]+$/, "");
|
|
54061
|
+
return platform === "win32" || platform === "darwin" ? key.toLowerCase() : key;
|
|
54062
|
+
};
|
|
54063
|
+
ADD_SCRIPT = String.raw`
|
|
54064
|
+
$ErrorActionPreference = 'Stop'
|
|
54065
|
+
$ProgressPreference = 'SilentlyContinue'
|
|
54066
|
+
$folder = $env:SHINJUKU_PATH_FOLDER
|
|
54067
|
+
function Key([string]$p) { ([Environment]::ExpandEnvironmentVariables($p.Trim().Trim('"'))).TrimEnd('\', '/').ToLowerInvariant() }
|
|
54068
|
+
try {
|
|
54069
|
+
$raw = [Microsoft.Win32.RegistryValueOptions]::DoNotExpandEnvironmentNames
|
|
54070
|
+
$want = Key $folder
|
|
54071
|
+
$machineKey = [Microsoft.Win32.Registry]::LocalMachine.OpenSubKey('SYSTEM\CurrentControlSet\Control\Session Manager\Environment')
|
|
54072
|
+
$machine = if ($machineKey) { [string]$machineKey.GetValue('Path', '', $raw) } else { '' }
|
|
54073
|
+
$key = [Microsoft.Win32.Registry]::CurrentUser.CreateSubKey('Environment')
|
|
54074
|
+
$user = $key.GetValue('Path', $null, $raw)
|
|
54075
|
+
$kind = if ($null -ne $user) { $key.GetValueKind('Path') } else { [Microsoft.Win32.RegistryValueKind]::ExpandString }
|
|
54076
|
+
$entries = @(([string]$user).Split(';')) + @($machine.Split(';'))
|
|
54077
|
+
if (@($entries | Where-Object { $_.Trim() -and (Key $_) -eq $want }).Count -gt 0) {
|
|
54078
|
+
'{"state":"present"}'; exit 0
|
|
54079
|
+
}
|
|
54080
|
+
if ($kind -ne [Microsoft.Win32.RegistryValueKind]::ExpandString -and $kind -ne [Microsoft.Win32.RegistryValueKind]::String) {
|
|
54081
|
+
'{"state":"failed","reason":"your PATH setting has a type setup does not change"}'; exit 0
|
|
54082
|
+
}
|
|
54083
|
+
$old = [string]$user
|
|
54084
|
+
$new = if ($old -eq '') { $folder } elseif ($old.EndsWith(';')) { $old + $folder } else { $old + ';' + $folder }
|
|
54085
|
+
if ($new.Length -ge 32767) { '{"state":"failed","reason":"your PATH setting is full"}'; exit 0 }
|
|
54086
|
+
$key.SetValue('Path', $new, $kind)
|
|
54087
|
+
if ([string]$key.GetValue('Path', '', $raw) -ne $new) { '{"state":"failed","reason":"the new PATH did not read back"}'; exit 0 }
|
|
54088
|
+
$broadcast = $false
|
|
54089
|
+
try {
|
|
54090
|
+
Add-Type -Namespace ShinjukuPath -Name Native -MemberDefinition '[DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)] public static extern IntPtr SendMessageTimeout(IntPtr hWnd, uint Msg, UIntPtr wParam, string lParam, uint fuFlags, uint uTimeout, out UIntPtr lpdwResult);'
|
|
54091
|
+
$result = [UIntPtr]::Zero
|
|
54092
|
+
$broadcast = [ShinjukuPath.Native]::SendMessageTimeout([IntPtr]0xffff, 0x1A, [UIntPtr]::Zero, 'Environment', 2, 5000, [ref]$result) -ne [IntPtr]::Zero
|
|
54093
|
+
} catch { $broadcast = $false }
|
|
54094
|
+
'{"state":"added","kind":"' + $kind + '","broadcast":' + $(if ($broadcast) { 'true' } else { 'false' }) + '}'
|
|
54095
|
+
} catch {
|
|
54096
|
+
'{"state":"failed","reason":"Windows did not let setup change your PATH setting"}'
|
|
54097
|
+
}
|
|
54098
|
+
`;
|
|
54099
|
+
}
|
|
54100
|
+
});
|
|
54101
|
+
|
|
53955
54102
|
// wallet/src/setup/config.mjs
|
|
53956
54103
|
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
53957
54104
|
import { randomBytes as randomBytes7 } from "node:crypto";
|
|
53958
54105
|
import { homedir } from "node:os";
|
|
53959
|
-
import { dirname as dirname6, isAbsolute as isAbsolute2, join as
|
|
54106
|
+
import { dirname as dirname6, isAbsolute as isAbsolute2, join as join9, resolve as resolve6 } from "node:path";
|
|
53960
54107
|
function retiredPoolText(pool2, npmVersion) {
|
|
53961
54108
|
const next = RETIRED_POOLS[pool2];
|
|
53962
54109
|
if (!next) return void 0;
|
|
53963
54110
|
return `pool ${pool2} is retired: Shinjuku runs a newer pool now, and nothing serves the old pool. It held no user balance when it was retired. Your old wallet file stays where it is; run ${oneTimeCommandLine("setup", npmVersion)} to make a wallet for the new pool`;
|
|
53964
54111
|
}
|
|
53965
54112
|
function holdsWallet(dir) {
|
|
53966
|
-
if (existsSync(
|
|
54113
|
+
if (existsSync(join9(dir, CONFIG_FILE))) return true;
|
|
53967
54114
|
try {
|
|
53968
|
-
return readdirSync(dir, { withFileTypes: true }).some((entry) => entry.isDirectory() && existsSync(
|
|
54115
|
+
return readdirSync(dir, { withFileTypes: true }).some((entry) => entry.isDirectory() && existsSync(join9(dir, entry.name, "wallet.json")));
|
|
53969
54116
|
} catch {
|
|
53970
54117
|
return false;
|
|
53971
54118
|
}
|
|
53972
54119
|
}
|
|
53973
54120
|
function setupHome(env = process.env, home = homedir()) {
|
|
53974
54121
|
if (env.SHIELDED_WALLET_HOME) return resolve6(env.SHIELDED_WALLET_HOME);
|
|
53975
|
-
const current =
|
|
53976
|
-
const older =
|
|
54122
|
+
const current = join9(home, HOME_FOLDER);
|
|
54123
|
+
const older = join9(home, OLDER_HOME_FOLDER);
|
|
53977
54124
|
return !holdsWallet(current) && holdsWallet(older) ? older : current;
|
|
53978
54125
|
}
|
|
53979
54126
|
function checkConfig(value2) {
|
|
@@ -54067,7 +54214,7 @@ async function setAsideInvalidConfig(home, now = /* @__PURE__ */ new Date()) {
|
|
|
54067
54214
|
function setAsideNow(home, now) {
|
|
54068
54215
|
const path = configPath(home);
|
|
54069
54216
|
const text3 = readFileSync(path, "utf8");
|
|
54070
|
-
const keptAs =
|
|
54217
|
+
const keptAs = join9(home, `config.invalid-${now.toISOString().replace(/[:.]/g, "-")}.json`);
|
|
54071
54218
|
copyFileSync(path, keptAs, constants.COPYFILE_EXCL);
|
|
54072
54219
|
rmSync(path);
|
|
54073
54220
|
let loose;
|
|
@@ -54275,11 +54422,57 @@ function claudeCodeCommand(options = {}) {
|
|
|
54275
54422
|
const platform = options.platform ?? process.platform;
|
|
54276
54423
|
const gitBash = options.gitBash ?? inGitBash(options);
|
|
54277
54424
|
const words2 = claudeCodeArgs(options).map((word, index, all) => gitBash && platform === "win32" && word === "/c" && all[index - 1] === "cmd" ? "//c" : word);
|
|
54278
|
-
|
|
54425
|
+
const program = claudeProgramWord(programOf(options), platform, options.shell ?? (gitBash ? "bash" : "cmd"));
|
|
54426
|
+
return program === void 0 ? void 0 : [program, ...words2.map((word) => hostShellWord(word, platform))].join(" ");
|
|
54427
|
+
}
|
|
54428
|
+
function claudeCodeProgram({ env = process.env, platform = process.platform, userHome = homedir(), isProgram = programFileAt } = {}) {
|
|
54429
|
+
const windows = platform === "win32";
|
|
54430
|
+
const pathValue = String(env.PATH ?? env.Path ?? "");
|
|
54431
|
+
if (windows) {
|
|
54432
|
+
const endings = String(env.PATHEXT || ".COM;.EXE;.BAT;.CMD").split(";").map((each) => each.trim()).filter(Boolean);
|
|
54433
|
+
for (const folder of pathValue.split(";").map((each) => each.trim().replace(/^"(.*)"$/, "$1")).filter(Boolean)) {
|
|
54434
|
+
if (endings.some((ending) => isProgram(join9(folder, `claude${ending.toLowerCase()}`), platform))) return "claude";
|
|
54435
|
+
}
|
|
54436
|
+
} else {
|
|
54437
|
+
for (const folder of pathValue.split(":")) {
|
|
54438
|
+
if (isProgram(join9(folder === "" ? "." : folder, "claude"), platform)) return "claude";
|
|
54439
|
+
}
|
|
54440
|
+
}
|
|
54441
|
+
const npmFolder = commandFolder({ env, platform });
|
|
54442
|
+
const places = windows ? [join9(env.USERPROFILE || userHome, ".local", "bin", "claude.exe"), ...npmFolder ? [join9(npmFolder, "claude.cmd")] : []] : [join9(userHome, ".local", "bin", "claude"), ...npmFolder ? [join9(npmFolder, "claude")] : []];
|
|
54443
|
+
return places.find((file) => isProgram(file, platform));
|
|
54444
|
+
}
|
|
54445
|
+
function programFileAt(file, platform = process.platform) {
|
|
54446
|
+
try {
|
|
54447
|
+
if (!statSync(file).isFile()) return false;
|
|
54448
|
+
if (platform !== "win32") accessSync(file, constants.X_OK);
|
|
54449
|
+
return true;
|
|
54450
|
+
} catch {
|
|
54451
|
+
return false;
|
|
54452
|
+
}
|
|
54453
|
+
}
|
|
54454
|
+
function claudeProgramWord(program, platform, shell = "cmd") {
|
|
54455
|
+
if (!program || program === "claude") return "claude";
|
|
54456
|
+
if (platform !== "win32") return hostShellWord(program, platform);
|
|
54457
|
+
const slashed = program.replace(/\\/g, "/");
|
|
54458
|
+
if (/^[A-Za-z0-9_./:=@-]+$/.test(slashed)) return slashed;
|
|
54459
|
+
if (shell === "bash") return hostShellWord(slashed, "linux");
|
|
54460
|
+
if (shell === "powershell") return `& '${program.replace(/'/g, "''")}'`;
|
|
54461
|
+
return CMD_UNSAFE.test(program) ? void 0 : `"${program}"`;
|
|
54462
|
+
}
|
|
54463
|
+
function claudeProgramRunWhy(program, platform = process.platform) {
|
|
54464
|
+
if (platform !== "win32" || !program || program === "claude" || /\.exe$/i.test(program) || !CMD_UNSAFE.test(program)) return null;
|
|
54465
|
+
return `its folder path (${program}) holds a character that cmd reads as code, so setup cannot start it`;
|
|
54279
54466
|
}
|
|
54280
54467
|
function claudeCodeLines(options = {}) {
|
|
54281
54468
|
if ((options.platform ?? process.platform) !== "win32") return ["Claude Code (run once):", ` ${claudeCodeCommand(options)}`];
|
|
54282
|
-
const
|
|
54469
|
+
const split4 = claudeLineDiffers(options);
|
|
54470
|
+
const cmdLine = claudeCodeCommand({ ...options, gitBash: false, shell: "cmd" });
|
|
54471
|
+
const powershell = split4 ? [
|
|
54472
|
+
"Claude Code (run once; in PowerShell):",
|
|
54473
|
+
` ${claudeCodeCommand({ ...options, gitBash: false, shell: "powershell" })}`,
|
|
54474
|
+
...cmdLine ? ["Claude Code (run once; in cmd):", ` ${cmdLine}`] : ["Claude Code in cmd: its folder path holds %, which cmd reads as code; use the PowerShell or Git Bash line."]
|
|
54475
|
+
] : ["Claude Code (run once; in PowerShell or cmd):", ` ${cmdLine}`];
|
|
54283
54476
|
const gitBash = ["Claude Code (run once; in Git Bash):", ` ${claudeCodeCommand({ ...options, gitBash: true })}`];
|
|
54284
54477
|
return inGitBash(options) ? [...gitBash, ...powershell] : [...powershell, ...gitBash];
|
|
54285
54478
|
}
|
|
@@ -54298,37 +54491,37 @@ function hostShellWord(word, platform = process.platform) {
|
|
|
54298
54491
|
}
|
|
54299
54492
|
function hostConfigFile(target, { platform = process.platform, env = process.env, home = homedir() } = {}) {
|
|
54300
54493
|
const set = (name) => typeof env[name] === "string" && env[name].trim() ? env[name].trim() : void 0;
|
|
54301
|
-
if (target === "cursor") return
|
|
54302
|
-
if (target === "codex") return
|
|
54494
|
+
if (target === "cursor") return join9(home, ".cursor", "mcp.json");
|
|
54495
|
+
if (target === "codex") return join9(env.CODEX_HOME || join9(home, ".codex"), "config.toml");
|
|
54303
54496
|
if (target === "vscode") {
|
|
54304
|
-
const appData = platform === "win32" ? env.APPDATA ||
|
|
54305
|
-
return
|
|
54497
|
+
const appData = platform === "win32" ? env.APPDATA || join9(home, "AppData", "Roaming") : platform === "darwin" ? join9(home, "Library", "Application Support") : env.XDG_CONFIG_HOME || join9(home, ".config");
|
|
54498
|
+
return join9(appData, "Code", "User", "mcp.json");
|
|
54306
54499
|
}
|
|
54307
54500
|
if (target === "devin") {
|
|
54308
|
-
return
|
|
54501
|
+
return join9(platform === "win32" ? join9(home, "AppData", "Roaming", "devin") : join9(env.XDG_CONFIG_HOME || join9(home, ".config"), "devin"), "mcp_config.json");
|
|
54309
54502
|
}
|
|
54310
54503
|
if (target === "cline") {
|
|
54311
|
-
return set("CLINE_MCP_SETTINGS_PATH") ??
|
|
54504
|
+
return set("CLINE_MCP_SETTINGS_PATH") ?? join9(set("CLINE_DATA_DIR") ?? join9(set("CLINE_DIR") ?? join9(home, ".cline"), "data"), "settings", "cline_mcp_settings.json");
|
|
54312
54505
|
}
|
|
54313
|
-
if (target === "continue") return
|
|
54314
|
-
if (target === "gemini") return
|
|
54315
|
-
if (target === "antigravity") return
|
|
54506
|
+
if (target === "continue") return join9(set("CONTINUE_GLOBAL_DIR") ? resolve6(set("CONTINUE_GLOBAL_DIR")) : join9(home, ".continue"), "mcpServers", `${MCP_SERVER_NAME}.yaml`);
|
|
54507
|
+
if (target === "gemini") return join9(set("GEMINI_CLI_HOME") ?? home, ".gemini", "settings.json");
|
|
54508
|
+
if (target === "antigravity") return join9(home, ".gemini", "config", "mcp_config.json");
|
|
54316
54509
|
if (target === "claude-desktop") {
|
|
54317
|
-
if (platform === "win32") return packagedClaudeDesktopFile(env, home) ??
|
|
54318
|
-
if (platform === "darwin") return
|
|
54319
|
-
return
|
|
54510
|
+
if (platform === "win32") return packagedClaudeDesktopFile(env, home) ?? join9(env.APPDATA || join9(home, "AppData", "Roaming"), "Claude", "claude_desktop_config.json");
|
|
54511
|
+
if (platform === "darwin") return join9(home, "Library", "Application Support", "Claude", "claude_desktop_config.json");
|
|
54512
|
+
return join9(env.XDG_CONFIG_HOME || join9(home, ".config"), "Claude", "claude_desktop_config.json");
|
|
54320
54513
|
}
|
|
54321
54514
|
return void 0;
|
|
54322
54515
|
}
|
|
54323
54516
|
function packagedClaudeDesktopFile(env, home) {
|
|
54324
|
-
const packages =
|
|
54517
|
+
const packages = join9(env.LOCALAPPDATA || join9(home, "AppData", "Local"), "Packages");
|
|
54325
54518
|
let names;
|
|
54326
54519
|
try {
|
|
54327
54520
|
names = readdirSync(packages);
|
|
54328
54521
|
} catch {
|
|
54329
54522
|
return void 0;
|
|
54330
54523
|
}
|
|
54331
|
-
const files = names.filter((each) => /^Claude_[a-z0-9]+$/i.test(each)).map((name) =>
|
|
54524
|
+
const files = names.filter((each) => /^Claude_[a-z0-9]+$/i.test(each)).map((name) => join9(packages, name, "LocalCache", "Roaming", "Claude", "claude_desktop_config.json")).filter((file) => existsSync(file));
|
|
54332
54525
|
if (files.length > 1) {
|
|
54333
54526
|
throw Object.assign(
|
|
54334
54527
|
new Error(`setup_host_config_ambiguous: this computer has ${files.length} Claude Desktop settings files (${files.join("; ")}), so the wallet did not pick one`),
|
|
@@ -54678,12 +54871,12 @@ function isSameClaudeCodeEntry(existing, options = {}) {
|
|
|
54678
54871
|
return entry !== void 0 && sameJson(entry, mcpServerEntry(options));
|
|
54679
54872
|
}
|
|
54680
54873
|
function restrictToOwnerWindows(file, { run: run2 = execFileSync2 } = {}) {
|
|
54681
|
-
const system32 =
|
|
54874
|
+
const system32 = join9(process.env.SystemRoot || "C:/Windows", "System32");
|
|
54682
54875
|
try {
|
|
54683
|
-
const line = String(run2(
|
|
54876
|
+
const line = String(run2(join9(system32, "whoami.exe"), ["/user", "/fo", "csv", "/nh"], { encoding: "utf8", windowsHide: true }));
|
|
54684
54877
|
const sid = line.match(/"(S-1-[0-9-]+)"/)?.[1];
|
|
54685
54878
|
if (!sid) throw new Error("no sid");
|
|
54686
|
-
run2(
|
|
54879
|
+
run2(join9(system32, "icacls.exe"), [file, "/inheritance:r", "/grant:r", `*${sid}:F`], { stdio: "ignore", windowsHide: true });
|
|
54687
54880
|
} catch {
|
|
54688
54881
|
throw new Error("setup_host_config_acl_failed: setup could not limit the file to only you on this computer (icacls), so it did not write it; add the printed entry by hand");
|
|
54689
54882
|
}
|
|
@@ -54956,7 +55149,7 @@ function changeFileOnce(file, change, { now, platform, restrict, codec = JSON_CO
|
|
|
54956
55149
|
}
|
|
54957
55150
|
return { changed: true, ...backup ? { backup } : {} };
|
|
54958
55151
|
}
|
|
54959
|
-
var import_web396, CONFIG_SCHEMA, CONFIG_FILE, NPM_PACKAGE_NAMES, COMMAND_PACKAGE, NPX_PACKAGE, NPX_INSTALL_FLAGS, MCP_SERVER_NAME, OLD_MCP_SERVER_NAMES, P03_BINDING, PRODUCTION, RETIRED_POOLS, NO_LIMIT_ATOMIC, DEFAULT_CAPS, OLD_DEFAULT_SETUP_CAPS, OLD_DEFAULT_WALLET_BUDGETS, capText, POSITIVE_ATOMIC, HOME_FOLDER, OLDER_HOME_FOLDER, defaultHomeWords, configPath, homeWalletPath, invalid, isPubkey, MAX_OWN_ADDRESSES, isOwnAddressText, salvagePath, clearConfigSalvage, HOST_TARGETS, HOST_NAMES, hostServersKey, hostEntry, CODEX_STARTUP_TIMEOUT_SEC, CODEX_TOOL_TIMEOUT_SEC, PINNED_PACKAGE, LAUNCHER_PACKAGE, NPM_VERSION, knownNpmVersion, RECOVERY_WORDS, NPX_WALLET_LINE, RELEASES_URL, npmStartEnvironment, NPM_START_KEYS, defaultWalletHome, WINDOWS_SHELL_CODE, CONTINUE_HEADER, tomlString, tomlKey, codexEntryOf, isPlainObject, sameJson, claudeCodeEntry, READ_ONLY_TOOL_NAMES, claudeCodeAllowRules, claudeCodeSettingsFile, UNREADABLE_JSON, JSON_CODEC, indentAt, TEXT_CODEC, RACED;
|
|
55152
|
+
var import_web396, CONFIG_SCHEMA, CONFIG_FILE, NPM_PACKAGE_NAMES, COMMAND_PACKAGE, NPX_PACKAGE, NPX_INSTALL_FLAGS, MCP_SERVER_NAME, OLD_MCP_SERVER_NAMES, P03_BINDING, PRODUCTION, RETIRED_POOLS, NO_LIMIT_ATOMIC, DEFAULT_CAPS, OLD_DEFAULT_SETUP_CAPS, OLD_DEFAULT_WALLET_BUDGETS, capText, POSITIVE_ATOMIC, HOME_FOLDER, OLDER_HOME_FOLDER, defaultHomeWords, configPath, homeWalletPath, invalid, isPubkey, MAX_OWN_ADDRESSES, isOwnAddressText, salvagePath, clearConfigSalvage, HOST_TARGETS, HOST_NAMES, hostServersKey, hostEntry, CODEX_STARTUP_TIMEOUT_SEC, CODEX_TOOL_TIMEOUT_SEC, PINNED_PACKAGE, LAUNCHER_PACKAGE, NPM_VERSION, knownNpmVersion, RECOVERY_WORDS, NPX_WALLET_LINE, RELEASES_URL, npmStartEnvironment, NPM_START_KEYS, defaultWalletHome, CMD_UNSAFE, programOf, claudeLineDiffers, WINDOWS_SHELL_CODE, CONTINUE_HEADER, tomlString, tomlKey, codexEntryOf, isPlainObject, sameJson, claudeCodeEntry, READ_ONLY_TOOL_NAMES, claudeCodeAllowRules, claudeCodeSettingsFile, UNREADABLE_JSON, JSON_CODEC, indentAt, TEXT_CODEC, RACED;
|
|
54960
55153
|
var init_config = __esm({
|
|
54961
55154
|
"wallet/src/setup/config.mjs"() {
|
|
54962
55155
|
"use strict";
|
|
@@ -54964,6 +55157,7 @@ var init_config = __esm({
|
|
|
54964
55157
|
import_web396 = __toESM(require_index_cjs(), 1);
|
|
54965
55158
|
init_rpcDefault();
|
|
54966
55159
|
init_processLock();
|
|
55160
|
+
init_userPath();
|
|
54967
55161
|
CONFIG_SCHEMA = "shinjuku-shielded/config/v1";
|
|
54968
55162
|
CONFIG_FILE = "config.json";
|
|
54969
55163
|
NPM_PACKAGE_NAMES = Object.freeze(["shinjuku-shield", "shinjuku-shielded"]);
|
|
@@ -55001,9 +55195,9 @@ var init_config = __esm({
|
|
|
55001
55195
|
POSITIVE_ATOMIC = /^[1-9][0-9]{0,30}$/;
|
|
55002
55196
|
HOME_FOLDER = ".shinjuku-shield";
|
|
55003
55197
|
OLDER_HOME_FOLDER = ".carbon-shielded-wallet";
|
|
55004
|
-
defaultHomeWords = (home = homedir()) => `~/${setupHome({}, home) ===
|
|
55005
|
-
configPath = (home) =>
|
|
55006
|
-
homeWalletPath = (home, pool2) =>
|
|
55198
|
+
defaultHomeWords = (home = homedir()) => `~/${setupHome({}, home) === join9(home, HOME_FOLDER) ? HOME_FOLDER : OLDER_HOME_FOLDER}`;
|
|
55199
|
+
configPath = (home) => join9(home, CONFIG_FILE);
|
|
55200
|
+
homeWalletPath = (home, pool2) => join9(home, pool2, "wallet.json");
|
|
55007
55201
|
invalid = (why) => new Error(`setup_config_invalid: config.json ${why}; rerun shinjuku setup (it keeps the wallet) or fix the file`);
|
|
55008
55202
|
isPubkey = (value2) => {
|
|
55009
55203
|
try {
|
|
@@ -55014,7 +55208,7 @@ var init_config = __esm({
|
|
|
55014
55208
|
};
|
|
55015
55209
|
MAX_OWN_ADDRESSES = 8;
|
|
55016
55210
|
isOwnAddressText = (value2) => isPubkey(value2);
|
|
55017
|
-
salvagePath = (home) =>
|
|
55211
|
+
salvagePath = (home) => join9(home, "config.salvage.json");
|
|
55018
55212
|
clearConfigSalvage = (home) => rmSync(salvagePath(home), { force: true });
|
|
55019
55213
|
HOST_TARGETS = Object.freeze(["claude-code", "claude-desktop", "cursor", "codex", "vscode", "devin", "cline", "continue", "gemini", "antigravity"]);
|
|
55020
55214
|
HOST_NAMES = Object.freeze({
|
|
@@ -55043,6 +55237,9 @@ var init_config = __esm({
|
|
|
55043
55237
|
npmStartEnvironment = (tor) => tor ? { npm_config_offline: "true" } : { npm_config_prefer_offline: "true" };
|
|
55044
55238
|
NPM_START_KEYS = ["npm_config_offline", "npm_config_prefer_offline"];
|
|
55045
55239
|
defaultWalletHome = (home = homedir()) => setupHome({}, home);
|
|
55240
|
+
CMD_UNSAFE = /[%"\r\n]/;
|
|
55241
|
+
programOf = (options) => "claudeProgram" in options ? options.claudeProgram : claudeCodeProgram(options);
|
|
55242
|
+
claudeLineDiffers = (options) => claudeProgramWord(programOf(options), "win32", "cmd") !== claudeProgramWord(programOf(options), "win32", "powershell");
|
|
55046
55243
|
WINDOWS_SHELL_CODE = /[%$`"\r\n]/;
|
|
55047
55244
|
CONTINUE_HEADER = Object.freeze(["name: Shinjuku Shield", "version: 0.0.1", "schema: v1", "mcpServers:"]);
|
|
55048
55245
|
tomlString = (value2) => `"${String(value2).replace(/[\\"]/g, (c) => `\\${c}`).replace(/[\u0000-\u001f\u007f]/g, (c) => `\\u${c.charCodeAt(0).toString(16).padStart(4, "0")}`)}"`;
|
|
@@ -55067,7 +55264,7 @@ var init_config = __esm({
|
|
|
55067
55264
|
"inference_models"
|
|
55068
55265
|
]);
|
|
55069
55266
|
claudeCodeAllowRules = () => READ_ONLY_TOOL_NAMES.map((name) => `mcp__${MCP_SERVER_NAME}__${name}`);
|
|
55070
|
-
claudeCodeSettingsFile = ({ env = process.env, home = homedir() } = {}) =>
|
|
55267
|
+
claudeCodeSettingsFile = ({ env = process.env, home = homedir() } = {}) => join9(env.CLAUDE_CONFIG_DIR || join9(home, ".claude"), "settings.json");
|
|
55071
55268
|
UNREADABLE_JSON = "setup_host_config_unreadable: the host's config file is not a JSON object, so setup left it alone; add the printed entry by hand";
|
|
55072
55269
|
JSON_CODEC = Object.freeze({
|
|
55073
55270
|
empty: () => ({}),
|
|
@@ -55105,7 +55302,7 @@ var init_config = __esm({
|
|
|
55105
55302
|
|
|
55106
55303
|
// wallet/src/setup/channel.mjs
|
|
55107
55304
|
import { createPublicKey as createPublicKey2, randomBytes as randomBytes8, verify } from "node:crypto";
|
|
55108
|
-
import { join as
|
|
55305
|
+
import { join as join10 } from "node:path";
|
|
55109
55306
|
function canonicalJson(value2) {
|
|
55110
55307
|
if (value2 === null || typeof value2 !== "object") {
|
|
55111
55308
|
if (typeof value2 === "number" && !Number.isFinite(value2)) throw fail7("wallet_channel_invalid", "the channel body holds a number JSON cannot carry");
|
|
@@ -55190,7 +55387,7 @@ function verifyChannelDocument(document2, { publicKeyHex = CHANNEL_PUBLIC_KEY_HE
|
|
|
55190
55387
|
return checkBody(document2.body);
|
|
55191
55388
|
}
|
|
55192
55389
|
function readSeq(home) {
|
|
55193
|
-
const path =
|
|
55390
|
+
const path = join10(home, CHANNEL_SEQ_FILE);
|
|
55194
55391
|
if (!existsSync(path)) return -1;
|
|
55195
55392
|
let value2;
|
|
55196
55393
|
try {
|
|
@@ -55218,9 +55415,9 @@ function acceptSeq(home, body, documentBytes) {
|
|
|
55218
55415
|
throw fail7("wallet_channel_rollback", `Shinjuku serves channel ${body.seq}, older than channel ${seen} this wallet already saw; nothing was installed and the old setup files stay`);
|
|
55219
55416
|
}
|
|
55220
55417
|
mkdirSync(home, { recursive: true, mode: 448 });
|
|
55221
|
-
if (body.seq > seen) writeAtomic(
|
|
55418
|
+
if (body.seq > seen) writeAtomic(join10(home, CHANNEL_SEQ_FILE), `${JSON.stringify({ seq: body.seq })}
|
|
55222
55419
|
`);
|
|
55223
|
-
if (documentBytes) writeAtomic(
|
|
55420
|
+
if (documentBytes) writeAtomic(join10(home, CHANNEL_FILE), documentBytes);
|
|
55224
55421
|
}
|
|
55225
55422
|
function onChannelRegistered(listener) {
|
|
55226
55423
|
registrationListeners.add(listener);
|
|
@@ -55295,7 +55492,7 @@ function applyStoredChannel({ home, publicKeyHex = CHANNEL_PUBLIC_KEY_HEX }) {
|
|
|
55295
55492
|
} catch {
|
|
55296
55493
|
return void 0;
|
|
55297
55494
|
}
|
|
55298
|
-
const path =
|
|
55495
|
+
const path = join10(home, CHANNEL_FILE);
|
|
55299
55496
|
if (!existsSync(path)) return void 0;
|
|
55300
55497
|
let document2;
|
|
55301
55498
|
try {
|
|
@@ -61675,16 +61872,16 @@ var init_incremental = __esm({
|
|
|
61675
61872
|
// wallet/src/history/walletHistory.mjs
|
|
61676
61873
|
import { AsyncLocalStorage as AsyncLocalStorage3 } from "node:async_hooks";
|
|
61677
61874
|
import { createHmac as createHmac5 } from "node:crypto";
|
|
61678
|
-
import { dirname as dirname8, join as
|
|
61875
|
+
import { dirname as dirname8, join as join11, resolve as resolve7 } from "node:path";
|
|
61679
61876
|
function walletHistoryCache(store) {
|
|
61680
|
-
return createHistoryCacheStore({ path:
|
|
61877
|
+
return createHistoryCacheStore({ path: join11(dirname8(store.path), "history-cache.json"), hmacKey: historyCacheKey(store) });
|
|
61681
61878
|
}
|
|
61682
61879
|
function walletSuccessorHistoryCache(store, pool2) {
|
|
61683
61880
|
if (!/^[1-9A-HJ-NP-Za-km-z]{32,44}$/.test(String(pool2))) throw new Error("wallet_succession_chain_invalid");
|
|
61684
|
-
return createHistoryCacheStore({ path:
|
|
61881
|
+
return createHistoryCacheStore({ path: join11(dirname8(store.path), `history-cache-successor-${pool2}.json`), hmacKey: historyCacheKey(store) });
|
|
61685
61882
|
}
|
|
61686
61883
|
function walletCompactHistoryCache(store) {
|
|
61687
|
-
return createCompactHistoryCacheStore({ path:
|
|
61884
|
+
return createCompactHistoryCacheStore({ path: join11(dirname8(store.path), "history-compact-cache.json"), hmacKey: historyCacheKey(store) });
|
|
61688
61885
|
}
|
|
61689
61886
|
async function loadWalletP03History(args) {
|
|
61690
61887
|
const runKey = lastRunReportKey(args.store, args.programId, args.pool, args.deploymentIdentity, args.cache);
|
|
@@ -63230,7 +63427,7 @@ var init_production_proof_bundle = __esm({
|
|
|
63230
63427
|
// wallet/src/prove/recoveredPayment.mjs
|
|
63231
63428
|
import { spawn as spawn2 } from "node:child_process";
|
|
63232
63429
|
import { createHash as createHash15 } from "node:crypto";
|
|
63233
|
-
import { dirname as dirname10, isAbsolute as isAbsolute4, join as
|
|
63430
|
+
import { dirname as dirname10, isAbsolute as isAbsolute4, join as join12, relative as relative4, resolve as resolve10 } from "node:path";
|
|
63234
63431
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
63235
63432
|
function fail9(reason) {
|
|
63236
63433
|
throw new Error(`p03_recovered_payment_${reason}`);
|
|
@@ -63617,7 +63814,7 @@ async function proveRecoveredP03Payment({ request, tools, onMemoBundle }) {
|
|
|
63617
63814
|
const bundle = loadBundle(tools);
|
|
63618
63815
|
markPhase("bundle");
|
|
63619
63816
|
const started = await takeEarlyTools(tools);
|
|
63620
|
-
const scratch = started?.scratch ?? mkdtempSync(
|
|
63817
|
+
const scratch = started?.scratch ?? mkdtempSync(join12(tmpdir2(), "sx402-wallet-payment-"));
|
|
63621
63818
|
try {
|
|
63622
63819
|
const { vectors, primaryProofs } = scratchDirectories(scratch);
|
|
63623
63820
|
if (!started) {
|
|
@@ -63673,7 +63870,7 @@ async function proveRecoveredP03Payment({ request, tools, onMemoBundle }) {
|
|
|
63673
63870
|
} catch {
|
|
63674
63871
|
}
|
|
63675
63872
|
markPhase("payment-prover", Number.isSafeInteger(ownMs) && ownMs >= 0 ? `proof_ms${ownMs}` : void 0);
|
|
63676
|
-
const primary = JSON.parse(readFileSync(
|
|
63873
|
+
const primary = JSON.parse(readFileSync(join12(primaryProofs, "shielded-exact-v2.json"), "utf8"));
|
|
63677
63874
|
if (JSON.stringify(primary.publicInputBytesHex) !== JSON.stringify(output2.primaryWitness.publicInputBytesHex)) {
|
|
63678
63875
|
fail9("proof_public_inputs_mismatch");
|
|
63679
63876
|
}
|
|
@@ -63709,7 +63906,7 @@ function startRecoveredPaymentTools(tools, { maxAgeMs = EARLY_TOOLS_MAX_AGE_MS }
|
|
|
63709
63906
|
}
|
|
63710
63907
|
async function launchEarlyTools(tools) {
|
|
63711
63908
|
const bundle = loadBundle(tools);
|
|
63712
|
-
const scratch = mkdtempSync(
|
|
63909
|
+
const scratch = mkdtempSync(join12(tmpdir2(), "sx402-wallet-payment-"));
|
|
63713
63910
|
const runs = [];
|
|
63714
63911
|
const stop3 = async () => {
|
|
63715
63912
|
for (const run2 of runs) run2.send("");
|
|
@@ -63764,10 +63961,10 @@ async function proveP03Vector({ tools, relation, vector }) {
|
|
|
63764
63961
|
const [toolName, outputName] = RELATION_PROVERS[relation] ?? fail9("relation_invalid");
|
|
63765
63962
|
const tool = tools[toolName] ?? fail9(`${toolName}_missing`);
|
|
63766
63963
|
const bundle = loadBundle(tools);
|
|
63767
|
-
const scratch = mkdtempSync(
|
|
63964
|
+
const scratch = mkdtempSync(join12(tmpdir2(), "sx402-wallet-vector-"));
|
|
63768
63965
|
try {
|
|
63769
|
-
const vectorPath =
|
|
63770
|
-
const proofs =
|
|
63966
|
+
const vectorPath = join12(scratch, "vector.json");
|
|
63967
|
+
const proofs = join12(scratch, "proof");
|
|
63771
63968
|
mkdirSync(proofs, { mode: 448 });
|
|
63772
63969
|
writeFileSync(vectorPath, jsonBytes(vector), { mode: 384 });
|
|
63773
63970
|
try {
|
|
@@ -63780,7 +63977,7 @@ async function proveP03Vector({ tools, relation, vector }) {
|
|
|
63780
63977
|
} catch (error) {
|
|
63781
63978
|
throw new Error(`p03_recovered_payment_${relation.replaceAll("-", "_")}_prover_failed`, { cause: error });
|
|
63782
63979
|
}
|
|
63783
|
-
const proof = JSON.parse(readFileSync(
|
|
63980
|
+
const proof = JSON.parse(readFileSync(join12(proofs, outputName), "utf8"));
|
|
63784
63981
|
return Object.freeze({ proofBytesHex: proof.proofBytesHex, publicInputBytesHex: proof.publicInputBytesHex });
|
|
63785
63982
|
} finally {
|
|
63786
63983
|
removeScratch(scratch);
|
|
@@ -63809,9 +64006,9 @@ var init_recoveredPayment = __esm({
|
|
|
63809
64006
|
${stamp}`;
|
|
63810
64007
|
bundleStamps = (files) => files.map((file) => fileStamp(file)).join("\n");
|
|
63811
64008
|
OPTIONAL_TOOL_KEYS = /* @__PURE__ */ new Set(["depositProver", "solanaCli", "moveWitness", "moveProver"]);
|
|
63812
|
-
scratchDirectories = (scratch) => ({ vectors:
|
|
64009
|
+
scratchDirectories = (scratch) => ({ vectors: join12(scratch, "vectors"), primaryProofs: join12(scratch, "payment-proof") });
|
|
63813
64010
|
paymentProverEnvironment = (bundle, vectors, primaryProofs) => ({
|
|
63814
|
-
SHIELDED_X402_VECTOR_PATH:
|
|
64011
|
+
SHIELDED_X402_VECTOR_PATH: join12(vectors, "shielded-exact-v2.json"),
|
|
63815
64012
|
SHIELDED_X402_PRODUCTION_PROOF_DIR: primaryProofs,
|
|
63816
64013
|
SHIELDED_X402_PARAMETER_MANIFEST_SHA256: bundle.manifestSha256,
|
|
63817
64014
|
SHIELDED_X402_PARAMETER_PATH: bundle.relations["shielded-exact-v2"].parameterPath
|
|
@@ -65965,10 +66162,10 @@ var init_deposit = __esm({
|
|
|
65965
66162
|
|
|
65966
66163
|
// wallet/src/store/sealedCache.mjs
|
|
65967
66164
|
import { createCipheriv as createCipheriv2, createDecipheriv as createDecipheriv2, createHmac as createHmac7, randomBytes as randomBytes11 } from "node:crypto";
|
|
65968
|
-
import { dirname as dirname12, join as
|
|
66165
|
+
import { dirname as dirname12, join as join13 } from "node:path";
|
|
65969
66166
|
function sealedCacheFile(store, { file, schema, keyLabel }) {
|
|
65970
66167
|
if (typeof store?.path !== "string" || !/^[0-9a-f]{64}$/i.test(store?.state?.seedHex ?? "")) return void 0;
|
|
65971
|
-
const path =
|
|
66168
|
+
const path = join13(dirname12(store.path), file);
|
|
65972
66169
|
const key = createHmac7("sha256", Buffer.from(store.state.seedHex, "hex")).update(keyLabel).digest();
|
|
65973
66170
|
const aad = Buffer.from(schema, "utf8");
|
|
65974
66171
|
return Object.freeze({
|
|
@@ -66590,14 +66787,14 @@ var init_successorHistories = __esm({
|
|
|
66590
66787
|
|
|
66591
66788
|
// wallet/src/recovery/recover.mjs
|
|
66592
66789
|
import { createHash as createHash16 } from "node:crypto";
|
|
66593
|
-
import { join as
|
|
66790
|
+
import { join as join14, resolve as resolve11 } from "node:path";
|
|
66594
66791
|
import { performance as performance4 } from "node:perf_hooks";
|
|
66595
66792
|
import { fileURLToPath as fileURLToPath5 } from "node:url";
|
|
66596
66793
|
function pinnedGenerator2(profileVector) {
|
|
66597
66794
|
if (profileVector?.payerKeys?.generator) return profileVector.payerKeys.generator;
|
|
66598
66795
|
if (!committedGenerator) {
|
|
66599
66796
|
const committed2 = JSON.parse(readFileSync(
|
|
66600
|
-
|
|
66797
|
+
join14(MODEL_DIR, "vectors", "rust-vectors.json"),
|
|
66601
66798
|
"utf8"
|
|
66602
66799
|
));
|
|
66603
66800
|
committedGenerator = Object.freeze(committed2.payerKeys.generator);
|
|
@@ -75641,7 +75838,7 @@ var init_production_proof_bundle2 = __esm({
|
|
|
75641
75838
|
// spikes/shielded-x402-wallet/lib/p03-recovered-exit.mjs
|
|
75642
75839
|
import { spawn as spawn3 } from "node:child_process";
|
|
75643
75840
|
import { createHash as createHash18 } from "node:crypto";
|
|
75644
|
-
import { dirname as dirname14, isAbsolute as isAbsolute6, join as
|
|
75841
|
+
import { dirname as dirname14, isAbsolute as isAbsolute6, join as join15, relative as relative6, resolve as resolve14 } from "node:path";
|
|
75645
75842
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
75646
75843
|
function fail15(reason) {
|
|
75647
75844
|
throw new Error(`p03_recovered_exit_${reason}`);
|
|
@@ -75929,11 +76126,11 @@ function proveRecoveredP03Exit({ request, tools }) {
|
|
|
75929
76126
|
return proveLoadedExit({ request, tools, kind, primaryProver, bundle });
|
|
75930
76127
|
}
|
|
75931
76128
|
async function proveLoadedExit({ request, tools, kind, primaryProver, bundle }) {
|
|
75932
|
-
const scratch = mkdtempSync(
|
|
76129
|
+
const scratch = mkdtempSync(join15(tmpdir3(), kind.scratchPrefix));
|
|
75933
76130
|
try {
|
|
75934
|
-
const vectors =
|
|
75935
|
-
const primaryProofs =
|
|
75936
|
-
const appendProofs =
|
|
76131
|
+
const vectors = join15(scratch, "vectors");
|
|
76132
|
+
const primaryProofs = join15(scratch, "primary-proof");
|
|
76133
|
+
const appendProofs = join15(scratch, "append-proof");
|
|
75937
76134
|
mkdirSync(vectors, { recursive: true, mode: 448 });
|
|
75938
76135
|
mkdirSync(primaryProofs, { recursive: true, mode: 448 });
|
|
75939
76136
|
mkdirSync(appendProofs, { recursive: true, mode: 448 });
|
|
@@ -75951,10 +76148,10 @@ async function proveLoadedExit({ request, tools, kind, primaryProver, bundle })
|
|
|
75951
76148
|
if (output2?.schema !== "carbon-shielded-x402/p03-recovered-exit-witness/v1" || output2.relation !== request.exitKind || output2.ownerRole !== kind.ownerRole) {
|
|
75952
76149
|
fail15("witness_output_invalid");
|
|
75953
76150
|
}
|
|
75954
|
-
const primaryVector =
|
|
76151
|
+
const primaryVector = join15(vectors, kind.vectorName);
|
|
75955
76152
|
const appendVector = oneItemAppendVector(
|
|
75956
|
-
|
|
75957
|
-
|
|
76153
|
+
join15(vectors, "tree-append-v1.json"),
|
|
76154
|
+
join15(vectors, "tree-append-sequence.json")
|
|
75958
76155
|
);
|
|
75959
76156
|
try {
|
|
75960
76157
|
await runTool2(primaryProver, [kind.command], {
|
|
@@ -75976,8 +76173,8 @@ async function proveLoadedExit({ request, tools, kind, primaryProver, bundle })
|
|
|
75976
76173
|
} catch (error) {
|
|
75977
76174
|
throw new Error("p03_recovered_exit_append_prover_phase_failed", { cause: error });
|
|
75978
76175
|
}
|
|
75979
|
-
const primary = JSON.parse(readFileSync(
|
|
75980
|
-
const append = JSON.parse(readFileSync(
|
|
76176
|
+
const primary = JSON.parse(readFileSync(join15(primaryProofs, kind.proofName), "utf8"));
|
|
76177
|
+
const append = JSON.parse(readFileSync(join15(appendProofs, "tree-append-v1-deposit.json"), "utf8"));
|
|
75981
76178
|
if (JSON.stringify(primary.publicInputBytesHex) !== JSON.stringify(output2.primaryWitness.publicInputBytesHex) || JSON.stringify(append.publicInputBytesHex) !== JSON.stringify(output2.treeAppendWitness.publicInputBytesHex)) {
|
|
75982
76179
|
fail15("proof_public_inputs_mismatch");
|
|
75983
76180
|
}
|
|
@@ -76038,13 +76235,13 @@ var init_p03_recovered_exit = __esm({
|
|
|
76038
76235
|
|
|
76039
76236
|
// spikes/shielded-x402-wallet/bin/shielded-wallet.mjs
|
|
76040
76237
|
import { createHash as createHash19 } from "node:crypto";
|
|
76041
|
-
import { join as
|
|
76238
|
+
import { join as join16, resolve as resolve15 } from "node:path";
|
|
76042
76239
|
import { fileURLToPath as fileURLToPath7 } from "node:url";
|
|
76043
76240
|
function walletHome() {
|
|
76044
76241
|
return setupHome(process.env);
|
|
76045
76242
|
}
|
|
76046
76243
|
function walletPath(pool2) {
|
|
76047
|
-
return
|
|
76244
|
+
return join16(walletHome(), pool2, "wallet.json");
|
|
76048
76245
|
}
|
|
76049
76246
|
function initialWalletState({ pool: pool2, network, asset, decimals, binding, config, keys: keys3, memoStart }) {
|
|
76050
76247
|
const seedHex = keys3?.seedHex ?? Buffer.from(generateSeed()).toString("hex");
|
|
@@ -76102,16 +76299,16 @@ function readCallerJson(path, code2) {
|
|
|
76102
76299
|
}
|
|
76103
76300
|
function loadProfileDirectory(profileDir) {
|
|
76104
76301
|
const directory = resolve15(profileDir);
|
|
76105
|
-
const profile = readCallerJson(
|
|
76106
|
-
const vector = readCallerJson(
|
|
76302
|
+
const profile = readCallerJson(join16(directory, "profile.json"), "profile_json_invalid");
|
|
76303
|
+
const vector = readCallerJson(join16(directory, "rust-vectors.json"), "profile_vectors_json_invalid");
|
|
76107
76304
|
const production = profile.schema === "carbon-shielded-exact/svm-mainnet-bounded-alpha-profile/v4";
|
|
76108
|
-
const artifactDir =
|
|
76305
|
+
const artifactDir = join16(directory, production ? "proofs" : "artifacts");
|
|
76109
76306
|
return { directory, profile, vector, production, artifactDir };
|
|
76110
76307
|
}
|
|
76111
76308
|
function pinnedGenerator3(profileVector) {
|
|
76112
76309
|
if (profileVector?.payerKeys?.generator) return profileVector.payerKeys.generator;
|
|
76113
76310
|
const committed2 = JSON.parse(readFileSync(
|
|
76114
|
-
|
|
76311
|
+
join16(MODEL_DIR2, "vectors", "rust-vectors.json"),
|
|
76115
76312
|
"utf8"
|
|
76116
76313
|
));
|
|
76117
76314
|
return committed2.payerKeys.generator;
|
|
@@ -76271,7 +76468,7 @@ function proveFromProfile({ binding, profileDir }) {
|
|
|
76271
76468
|
const proved = provePayment({
|
|
76272
76469
|
binding,
|
|
76273
76470
|
modelDir: MODEL_DIR2,
|
|
76274
|
-
vectorPath:
|
|
76471
|
+
vectorPath: join16(resolve15(profileDir), "rust-vectors.json"),
|
|
76275
76472
|
artifactDir,
|
|
76276
76473
|
production: production ? {
|
|
76277
76474
|
parameterPathByRelation: profile.parameterBundle?.parameterPathByRelation,
|
|
@@ -77569,7 +77766,7 @@ async function main(argv2 = process.argv.slice(2)) {
|
|
|
77569
77766
|
case "backup-verify": {
|
|
77570
77767
|
const pool2 = flag(args, "--pool") ?? requiredPoolFromHome();
|
|
77571
77768
|
const backupDir = flag(args, "--backup-dir");
|
|
77572
|
-
const path = backupDir ?
|
|
77769
|
+
const path = backupDir ? join16(backupDir, "wallet.json") : walletPath(pool2);
|
|
77573
77770
|
const store = openWalletStore(path, passphrase());
|
|
77574
77771
|
if (store.state.pool !== pool2) throw new Error("backup-verify pool does not match wallet");
|
|
77575
77772
|
const bundle = backupDir ? verifyWalletRecoveryBundle(backupDir, passphrase()) : void 0;
|
|
@@ -77735,7 +77932,7 @@ async function runValueMove(command, args) {
|
|
|
77735
77932
|
const vault = vaultAddress(programId, pool2, mint);
|
|
77736
77933
|
const poolState2 = await readPoolState(connection, pool2);
|
|
77737
77934
|
if (!poolState2) throw new Error("pool account not found");
|
|
77738
|
-
const readProof = (name) => JSON.parse(readFileSync(
|
|
77935
|
+
const readProof = (name) => JSON.parse(readFileSync(join16(artifactDir, name), "utf8"));
|
|
77739
77936
|
if (command === "deposit") {
|
|
77740
77937
|
const proofName = production ? "deposit-v1.json" : "UNSAFE_TEST_ONLY-deposit-v1-proof.json";
|
|
77741
77938
|
const appendName2 = production ? "tree-append-v1-deposit.json" : "UNSAFE_TEST_ONLY-tree-append-v1-deposit-proof.json";
|
|
@@ -78123,153 +78320,6 @@ var init_secretFile = __esm({
|
|
|
78123
78320
|
}
|
|
78124
78321
|
});
|
|
78125
78322
|
|
|
78126
|
-
// wallet/src/setup/userPath.mjs
|
|
78127
|
-
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
78128
|
-
import { basename as basename3, join as join16 } from "node:path";
|
|
78129
|
-
function commandFolder({ env = process.env, platform = process.platform } = {}) {
|
|
78130
|
-
const prefix = env.npm_config_global_prefix || env.npm_config_prefix;
|
|
78131
|
-
if (platform === "win32") return prefix || (env.APPDATA ? join16(env.APPDATA, "npm") : void 0);
|
|
78132
|
-
return prefix ? `${String(prefix).replace(/\/+$/, "")}/bin` : void 0;
|
|
78133
|
-
}
|
|
78134
|
-
function commandFileIn(folder, platform = process.platform) {
|
|
78135
|
-
if (!folder) return void 0;
|
|
78136
|
-
const file = join16(folder, platform === "win32" ? `${COMMAND_PACKAGE}.cmd` : COMMAND_PACKAGE);
|
|
78137
|
-
try {
|
|
78138
|
-
if (!statSync(file).isFile()) return void 0;
|
|
78139
|
-
if (platform !== "win32") accessSync(file, constants.X_OK);
|
|
78140
|
-
return file;
|
|
78141
|
-
} catch {
|
|
78142
|
-
return void 0;
|
|
78143
|
-
}
|
|
78144
|
-
}
|
|
78145
|
-
function shellPathEntries({ env = process.env, platform = process.platform } = {}) {
|
|
78146
|
-
const pathValue = env.PATH ?? env.Path ?? env.path ?? "";
|
|
78147
|
-
const entries = String(pathValue).split(platform === "win32" ? ";" : ":");
|
|
78148
|
-
let last = -1;
|
|
78149
|
-
entries.forEach((each, index) => {
|
|
78150
|
-
if (/[\\/]node-gyp-bin[\\/]*$/i.test(each.trim())) last = index;
|
|
78151
|
-
});
|
|
78152
|
-
return entries.slice(last + 1);
|
|
78153
|
-
}
|
|
78154
|
-
function folderOnPath(folder, { env = process.env, platform = process.platform } = {}) {
|
|
78155
|
-
const key = folderKey(folder, platform);
|
|
78156
|
-
return shellPathEntries({ env, platform }).some((each) => each.trim() && folderKey(each, platform) === key);
|
|
78157
|
-
}
|
|
78158
|
-
function addFolderToUserPath(folder, { run: run2 = spawnSync2, env = process.env } = {}) {
|
|
78159
|
-
let result;
|
|
78160
|
-
try {
|
|
78161
|
-
result = run2(
|
|
78162
|
-
"powershell.exe",
|
|
78163
|
-
[
|
|
78164
|
-
"-NoProfile",
|
|
78165
|
-
"-NonInteractive",
|
|
78166
|
-
"-ExecutionPolicy",
|
|
78167
|
-
"Bypass",
|
|
78168
|
-
"-EncodedCommand",
|
|
78169
|
-
Buffer.from(ADD_SCRIPT, "utf16le").toString("base64")
|
|
78170
|
-
],
|
|
78171
|
-
{ windowsHide: true, encoding: "utf8", timeout: 6e4, env: { ...env, SHINJUKU_PATH_FOLDER: folder } }
|
|
78172
|
-
);
|
|
78173
|
-
} catch {
|
|
78174
|
-
return { state: "failed", reason: "Windows PowerShell did not start" };
|
|
78175
|
-
}
|
|
78176
|
-
const line = String(result?.stdout ?? "").trim().split(/\r?\n/).reverse().find((each) => each.startsWith("{"));
|
|
78177
|
-
try {
|
|
78178
|
-
const answer = JSON.parse(line ?? "");
|
|
78179
|
-
if (["present", "added", "failed"].includes(answer?.state)) return answer;
|
|
78180
|
-
} catch {
|
|
78181
|
-
}
|
|
78182
|
-
return { state: "failed", reason: "Windows PowerShell gave no answer" };
|
|
78183
|
-
}
|
|
78184
|
-
function shellProfileLine(folder, { env = process.env, platform = process.platform } = {}) {
|
|
78185
|
-
const shell = basename3(String(env.SHELL ?? ""));
|
|
78186
|
-
if (shell === "fish") return { file: "~/.config/fish/config.fish", line: `fish_add_path '${String(folder).replace(/[\\']/g, "\\$&")}'` };
|
|
78187
|
-
const file = shell === "zsh" ? "~/.zshrc" : shell === "bash" ? platform === "darwin" ? "~/.bash_profile" : "~/.bashrc" : "~/.profile";
|
|
78188
|
-
return { file, line: `export PATH='${String(folder).replace(/'/g, "'\\''")}':"$PATH"` };
|
|
78189
|
-
}
|
|
78190
|
-
function commandPathStep({ env = process.env, platform = process.platform, run: run2 = spawnSync2 } = {}) {
|
|
78191
|
-
const folder = commandFolder({ env, platform });
|
|
78192
|
-
if (!commandFileIn(folder, platform)) return { state: "no-command", folder };
|
|
78193
|
-
if (platform !== "win32") {
|
|
78194
|
-
return folderOnPath(folder, { env, platform }) ? { state: "on-path", folder } : { state: "profile", folder, ...shellProfileLine(folder, { env, platform }) };
|
|
78195
|
-
}
|
|
78196
|
-
return { folder, ...addFolderToUserPath(folder, { run: run2, env }), thisWindow: folderOnPath(folder, { env, platform }) };
|
|
78197
|
-
}
|
|
78198
|
-
function pathStepSays(step) {
|
|
78199
|
-
return ["added", "failed", "profile"].includes(step?.state) || step?.state === "present" && step.thisWindow === false;
|
|
78200
|
-
}
|
|
78201
|
-
function commandPathLines(step, hereLine) {
|
|
78202
|
-
const here3 = ["In this window, type the longer command, for example:", ` ${hereLine}`];
|
|
78203
|
-
if (step?.state === "added") {
|
|
78204
|
-
return [step.broadcast === false ? "Added Shinjuku to your PATH. Sign out of Windows and in again, then type shinjuku in a new window." : "Added Shinjuku to your PATH. Open a new window to type shinjuku.", ...here3];
|
|
78205
|
-
}
|
|
78206
|
-
if (step?.state === "present") return ["Shinjuku is on your PATH. Open a new window to type shinjuku.", ...here3];
|
|
78207
|
-
if (step?.state === "failed") {
|
|
78208
|
-
return [
|
|
78209
|
-
`Setup could not add Shinjuku to your PATH (${step.reason}). To add it yourself: open Start, type environment variables, open "Edit environment variables for your account", pick Path, choose Edit, then New, and paste this folder:`,
|
|
78210
|
-
` ${step.folder}`,
|
|
78211
|
-
"Then open a new window to type shinjuku.",
|
|
78212
|
-
...here3
|
|
78213
|
-
];
|
|
78214
|
-
}
|
|
78215
|
-
if (step?.state === "profile") {
|
|
78216
|
-
return [
|
|
78217
|
-
`Your terminal does not look in the folder where npm put the shinjuku command. Add this line to the end of ${step.file}, then open a new terminal to type shinjuku:`,
|
|
78218
|
-
` ${step.line}`,
|
|
78219
|
-
...here3
|
|
78220
|
-
];
|
|
78221
|
-
}
|
|
78222
|
-
return [];
|
|
78223
|
-
}
|
|
78224
|
-
var folderKey, ADD_SCRIPT;
|
|
78225
|
-
var init_userPath = __esm({
|
|
78226
|
-
"wallet/src/setup/userPath.mjs"() {
|
|
78227
|
-
"use strict";
|
|
78228
|
-
init_fs();
|
|
78229
|
-
init_config();
|
|
78230
|
-
folderKey = (folder, platform) => {
|
|
78231
|
-
const key = String(folder).trim().replace(/^"(.*)"$/, "$1").replace(/[\\/]+$/, "");
|
|
78232
|
-
return platform === "win32" || platform === "darwin" ? key.toLowerCase() : key;
|
|
78233
|
-
};
|
|
78234
|
-
ADD_SCRIPT = String.raw`
|
|
78235
|
-
$ErrorActionPreference = 'Stop'
|
|
78236
|
-
$ProgressPreference = 'SilentlyContinue'
|
|
78237
|
-
$folder = $env:SHINJUKU_PATH_FOLDER
|
|
78238
|
-
function Key([string]$p) { ([Environment]::ExpandEnvironmentVariables($p.Trim().Trim('"'))).TrimEnd('\', '/').ToLowerInvariant() }
|
|
78239
|
-
try {
|
|
78240
|
-
$raw = [Microsoft.Win32.RegistryValueOptions]::DoNotExpandEnvironmentNames
|
|
78241
|
-
$want = Key $folder
|
|
78242
|
-
$machineKey = [Microsoft.Win32.Registry]::LocalMachine.OpenSubKey('SYSTEM\CurrentControlSet\Control\Session Manager\Environment')
|
|
78243
|
-
$machine = if ($machineKey) { [string]$machineKey.GetValue('Path', '', $raw) } else { '' }
|
|
78244
|
-
$key = [Microsoft.Win32.Registry]::CurrentUser.CreateSubKey('Environment')
|
|
78245
|
-
$user = $key.GetValue('Path', $null, $raw)
|
|
78246
|
-
$kind = if ($null -ne $user) { $key.GetValueKind('Path') } else { [Microsoft.Win32.RegistryValueKind]::ExpandString }
|
|
78247
|
-
$entries = @(([string]$user).Split(';')) + @($machine.Split(';'))
|
|
78248
|
-
if (@($entries | Where-Object { $_.Trim() -and (Key $_) -eq $want }).Count -gt 0) {
|
|
78249
|
-
'{"state":"present"}'; exit 0
|
|
78250
|
-
}
|
|
78251
|
-
if ($kind -ne [Microsoft.Win32.RegistryValueKind]::ExpandString -and $kind -ne [Microsoft.Win32.RegistryValueKind]::String) {
|
|
78252
|
-
'{"state":"failed","reason":"your PATH setting has a type setup does not change"}'; exit 0
|
|
78253
|
-
}
|
|
78254
|
-
$old = [string]$user
|
|
78255
|
-
$new = if ($old -eq '') { $folder } elseif ($old.EndsWith(';')) { $old + $folder } else { $old + ';' + $folder }
|
|
78256
|
-
if ($new.Length -ge 32767) { '{"state":"failed","reason":"your PATH setting is full"}'; exit 0 }
|
|
78257
|
-
$key.SetValue('Path', $new, $kind)
|
|
78258
|
-
if ([string]$key.GetValue('Path', '', $raw) -ne $new) { '{"state":"failed","reason":"the new PATH did not read back"}'; exit 0 }
|
|
78259
|
-
$broadcast = $false
|
|
78260
|
-
try {
|
|
78261
|
-
Add-Type -Namespace ShinjukuPath -Name Native -MemberDefinition '[DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)] public static extern IntPtr SendMessageTimeout(IntPtr hWnd, uint Msg, UIntPtr wParam, string lParam, uint fuFlags, uint uTimeout, out UIntPtr lpdwResult);'
|
|
78262
|
-
$result = [UIntPtr]::Zero
|
|
78263
|
-
$broadcast = [ShinjukuPath.Native]::SendMessageTimeout([IntPtr]0xffff, 0x1A, [UIntPtr]::Zero, 'Environment', 2, 5000, [ref]$result) -ne [IntPtr]::Zero
|
|
78264
|
-
} catch { $broadcast = $false }
|
|
78265
|
-
'{"state":"added","kind":"' + $kind + '","broadcast":' + $(if ($broadcast) { 'true' } else { 'false' }) + '}'
|
|
78266
|
-
} catch {
|
|
78267
|
-
'{"state":"failed","reason":"Windows did not let setup change your PATH setting"}'
|
|
78268
|
-
}
|
|
78269
|
-
`;
|
|
78270
|
-
}
|
|
78271
|
-
});
|
|
78272
|
-
|
|
78273
78323
|
// wallet/src/cli/commandName.mjs
|
|
78274
78324
|
import { spawnSync as spawnSync3 } from "node:child_process";
|
|
78275
78325
|
import { basename as basename4, dirname as dirname15, join as join17 } from "node:path";
|
|
@@ -160082,6 +160132,21 @@ function claudeCodeEntryOf(deps) {
|
|
|
160082
160132
|
return void 0;
|
|
160083
160133
|
}
|
|
160084
160134
|
}
|
|
160135
|
+
function runClaude(args, program = "claude", stdio = "inherit") {
|
|
160136
|
+
const options = { stdio, windowsHide: true, timeout: 12e4 };
|
|
160137
|
+
const programWord = program === "claude" ? program : `"${program}"`;
|
|
160138
|
+
const result = process.platform === "win32" && !/\.exe$/i.test(program) ? spawnSync10([programWord, ...args.map((word) => hostShellWord(word, "win32"))].join(" "), { ...options, shell: true }) : spawnSync10(program, args, options);
|
|
160139
|
+
return result.status ?? 1;
|
|
160140
|
+
}
|
|
160141
|
+
function claudeRemoveLines(program, platform) {
|
|
160142
|
+
const tail = `mcp remove --scope user ${MCP_SERVER_NAME}`;
|
|
160143
|
+
const shells = platform === "win32" ? ["powershell", "cmd", "bash"] : ["bash"];
|
|
160144
|
+
const words2 = shells.map((shell) => claudeProgramWord(program, platform, shell));
|
|
160145
|
+
if (new Set(words2).size === 1) return ` ${words2[0]} ${tail}`;
|
|
160146
|
+
const names = { powershell: "PowerShell", cmd: "cmd", bash: "Git Bash" };
|
|
160147
|
+
return shells.map((shell, index) => words2[index] === void 0 ? void 0 : ` In ${names[shell]}:
|
|
160148
|
+
${words2[index]} ${tail}`).filter((line) => line !== void 0).join("\n");
|
|
160149
|
+
}
|
|
160085
160150
|
var RESTART_APP = (app) => `If ${app} is open now, quit it and start it again.`;
|
|
160086
160151
|
function hostAddedNext(target, app, platform) {
|
|
160087
160152
|
const ask = 'then ask in plain words, for example "what is my Shinjuku balance".';
|
|
@@ -160187,7 +160252,23 @@ async function addToHosts(targets, home, deps, { force = false, npmVersion, ask,
|
|
|
160187
160252
|
`);
|
|
160188
160253
|
continue;
|
|
160189
160254
|
}
|
|
160190
|
-
const
|
|
160255
|
+
const claudeProgram = claudeCodeProgram({ env: deps.env ?? process.env, platform: options.platform, userHome: deps.homedir() });
|
|
160256
|
+
const claudeOptions = { ...options, userHome: deps.homedir() };
|
|
160257
|
+
if (claudeProgram === void 0) {
|
|
160258
|
+
io.out(`Not added to Claude Code: its command, claude, is not on this computer's PATH and not in the folders where Claude Code's installers put it (${options.platform === "win32" ? "%USERPROFILE%\\.local\\bin, or npm's folder" : "~/.local/bin"}). If Claude Code is not installed, install it (https://code.claude.com/docs/en/setup), then do this step again. If it is in another folder, run this line in a window where claude works:
|
|
160259
|
+
${claudeCodeCommand({ ...claudeOptions, claudeProgram: "claude" })}
|
|
160260
|
+
`);
|
|
160261
|
+
continue;
|
|
160262
|
+
}
|
|
160263
|
+
const runWhy = claudeProgramRunWhy(claudeProgram, options.platform);
|
|
160264
|
+
if (runWhy) {
|
|
160265
|
+
io.out(`Not added to Claude Code: ${runWhy}. Run this yourself:
|
|
160266
|
+
${claudeCodeLines({ ...claudeOptions, claudeProgram }).map((line) => ` ${line}`).join("\n")}
|
|
160267
|
+
`);
|
|
160268
|
+
continue;
|
|
160269
|
+
}
|
|
160270
|
+
const quiet = (args) => (deps.runClaudeCliQuiet ?? deps.runClaudeCli)(args, claudeProgram);
|
|
160271
|
+
const runClaudeCli = (args) => deps.runClaudeCli(args, claudeProgram);
|
|
160191
160272
|
for (const old of OLD_MCP_SERVER_NAMES) {
|
|
160192
160273
|
if (quiet(["mcp", "remove", "--scope", "user", old]) === 0) io.out(`Replaced the old ${old} entry in Claude Code.
|
|
160193
160274
|
`);
|
|
@@ -160210,9 +160291,9 @@ async function addToHosts(targets, home, deps, { force = false, npmVersion, ask,
|
|
|
160210
160291
|
continue;
|
|
160211
160292
|
}
|
|
160212
160293
|
const replacedOther = replace === true && quiet(["mcp", "remove", "--scope", "user", MCP_SERVER_NAME]) === 0;
|
|
160213
|
-
let status =
|
|
160294
|
+
let status = runClaudeCli(claudeCodeArgs(options));
|
|
160214
160295
|
const removed = olderOwn || replacedOther || status !== 0 && force && quiet(["mcp", "remove", "--scope", "user", MCP_SERVER_NAME]) === 0;
|
|
160215
|
-
if (removed && status !== 0) status =
|
|
160296
|
+
if (removed && status !== 0) status = runClaudeCli(claudeCodeArgs(options));
|
|
160216
160297
|
if (status === 0) done.add(target);
|
|
160217
160298
|
const check = status === 0 ? await hostStartCheck("Claude Code", options, deps, { terminal: true, noTor }) : void 0;
|
|
160218
160299
|
if (check && !check.ok) io.out(`${hostCheckWords("Claude Code", check)}
|
|
@@ -160220,10 +160301,10 @@ async function addToHosts(targets, home, deps, { force = false, npmVersion, ask,
|
|
|
160220
160301
|
const homeNow = replacedOther ? ` Claude Code now uses the wallet in ${home}; the wallet in ${otherHome} is unchanged.` : "";
|
|
160221
160302
|
io.out(status === 0 ? `${removed ? "Replaced the wallet in" : "Added the wallet to"} Claude Code, for all your folders.${homeNow} ${allowWalletChecks(deps).say} ${RESTART_APP("Claude Code")}
|
|
160222
160303
|
` : `Claude Code did not take the server; its message is above. Run this yourself:
|
|
160223
|
-
${
|
|
160304
|
+
${claudeCodeLines({ ...claudeOptions, claudeProgram }).map((line) => ` ${line}`).join("\n")}
|
|
160224
160305
|
` + (removed ? `Setup removed the old ${MCP_SERVER_NAME} entry first, so Claude Code has none until that line runs.
|
|
160225
160306
|
` : `If it says the server already exists, remove that entry with this command, then run the line above:
|
|
160226
|
-
|
|
160307
|
+
${claudeRemoveLines(claudeProgram, options.platform)}
|
|
160227
160308
|
`));
|
|
160228
160309
|
continue;
|
|
160229
160310
|
}
|
|
@@ -165431,16 +165512,8 @@ function defaultDependencies() {
|
|
|
165431
165512
|
});
|
|
165432
165513
|
}),
|
|
165433
165514
|
/** claude with no output on the terminal (setup's probe of an old entry, and its remove); the exit status. */
|
|
165434
|
-
runClaudeCliQuiet: (args) =>
|
|
165435
|
-
|
|
165436
|
-
const result = windows ? spawnSync10(["claude", ...args].map((word) => hostShellWord(word, "win32")).join(" "), { stdio: "ignore", shell: true, windowsHide: true, timeout: 12e4 }) : spawnSync10("claude", args, { stdio: "ignore", windowsHide: true, timeout: 12e4 });
|
|
165437
|
-
return result.status ?? 1;
|
|
165438
|
-
},
|
|
165439
|
-
runClaudeCli: (args) => {
|
|
165440
|
-
const windows = process.platform === "win32";
|
|
165441
|
-
const result = windows ? spawnSync10(["claude", ...args].map((word) => hostShellWord(word, "win32")).join(" "), { stdio: "inherit", shell: true, windowsHide: true, timeout: 12e4 }) : spawnSync10("claude", args, { stdio: "inherit", windowsHide: true, timeout: 12e4 });
|
|
165442
|
-
return result.status ?? 1;
|
|
165443
|
-
},
|
|
165515
|
+
runClaudeCliQuiet: (args, program) => runClaude(args, program, "ignore"),
|
|
165516
|
+
runClaudeCli: (args, program) => runClaude(args, program, "inherit"),
|
|
165444
165517
|
/**
|
|
165445
165518
|
* The --tor entry of this CLI: re-execute `args` behind Tor (proxy.mjs proves Tor first). `startedFile`
|
|
165446
165519
|
* (torRunOf) reaches the Tor run in its environment, which proxy.mjs copies from this process at the spawn.
|