shinjuku-shielded 0.3.174 → 0.3.175
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 +63 -20
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.175. 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.175 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.175 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.175", "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.175", "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": "dd3bab15896a11e725fd452abbfd4fbad9b412640201141c884a77bd6c81d5dd",
|
|
5
|
+
"bytes": 9395751,
|
|
6
|
+
"sourceCommit": "9dc2ed8abb49b3cce01ddd09f43128cc0aa5c885",
|
|
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-05T23:21:41.970Z"
|
|
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.175",
|
|
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": "dd3bab15",
|
|
7
|
+
"shinjukuSha256": "dd3bab15896a11e725fd452abbfd4fbad9b412640201141c884a77bd6c81d5dd",
|
|
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
|
@@ -54474,7 +54474,7 @@ function hostStartFolder(target, entry) {
|
|
|
54474
54474
|
}
|
|
54475
54475
|
function noStartFolderWords(target, entry) {
|
|
54476
54476
|
if (hasPrefix(entry) || hostStartFolder(target, entry) !== void 0) return "";
|
|
54477
|
-
return ` Your wallet folder path has a character that Windows reads as code (% & | < > ^ ! or
|
|
54477
|
+
return ` Your wallet folder path has a character that Windows reads as code (% & | < > ^ ! " $ or \`), so ${HOST_NAMES[target]} starts the wallet in a folder of its own: a settings file there (.npmrc) can stop the wallet. If the wallet does not start there, set up the wallet again in a folder without these characters.`;
|
|
54478
54478
|
}
|
|
54479
54479
|
function cwdFolder(cwd) {
|
|
54480
54480
|
if (typeof cwd !== "string" || !cwd) return void 0;
|
|
@@ -54492,12 +54492,12 @@ function installPackageWord(npmVersion) {
|
|
|
54492
54492
|
const version3 = knownNpmVersion(npmVersion);
|
|
54493
54493
|
return version3 ? `${COMMAND_PACKAGE}@${version3}` : COMMAND_PACKAGE;
|
|
54494
54494
|
}
|
|
54495
|
-
function oneTimeCommandLine(words2, npmVersion) {
|
|
54496
|
-
return [npxCommandPrefix(npmVersion, { recovery: RECOVERY_WORDS.test(String(words2 ?? "")) }), words2].join(" ");
|
|
54495
|
+
function oneTimeCommandLine(words2, npmVersion, { npmArgs = [] } = {}) {
|
|
54496
|
+
return [npxCommandPrefix(npmVersion, { recovery: RECOVERY_WORDS.test(String(words2 ?? "")), npmArgs }), words2].join(" ");
|
|
54497
54497
|
}
|
|
54498
|
-
function npxCommandPrefix(npmVersion, { recovery = false } = {}) {
|
|
54498
|
+
function npxCommandPrefix(npmVersion, { recovery = false, npmArgs = [] } = {}) {
|
|
54499
54499
|
const cache = knownNpmVersion(npmVersion) && !recovery ? npxCacheFlag() : void 0;
|
|
54500
|
-
return ["npx", ...cache ? [cache] : [], "-y", ...NPX_INSTALL_FLAGS, npxPackageWord(npmVersion)].join(" ");
|
|
54500
|
+
return ["npx", ...cache ? [cache] : [], "-y", ...NPX_INSTALL_FLAGS, ...npmArgs, npxPackageWord(npmVersion)].join(" ");
|
|
54501
54501
|
}
|
|
54502
54502
|
function npxLineFlags(text3, ownVersion) {
|
|
54503
54503
|
const own = knownNpmVersion(ownVersion);
|
|
@@ -54539,7 +54539,7 @@ function mcpServerEntry({ home, platform = process.platform, npmVersion, path, t
|
|
|
54539
54539
|
}
|
|
54540
54540
|
function npmPrefixArgs(home, platform = process.platform) {
|
|
54541
54541
|
const folder = resolve6(home);
|
|
54542
|
-
return platform === "win32" &&
|
|
54542
|
+
return platform === "win32" && WIN_ARG_CODE.test(folder) ? [] : [`--prefix=${folder}`];
|
|
54543
54543
|
}
|
|
54544
54544
|
function homeTorOn(home) {
|
|
54545
54545
|
try {
|
|
@@ -55812,7 +55812,7 @@ function changeFileOnce(file, change, { now, platform, restrict, codec = JSON_CO
|
|
|
55812
55812
|
}
|
|
55813
55813
|
return { changed: true, ...backup ? { backup } : {} };
|
|
55814
55814
|
}
|
|
55815
|
-
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, CWD_HOSTS, hasPrefix, CODEX_STARTUP_TIMEOUT_SEC, CODEX_TOOL_TIMEOUT_SEC, PINNED_PACKAGE, LAUNCHER_PACKAGE, NPM_VERSION, knownNpmVersion, RECOVERY_WORDS, NPX_WALLET_LINE, RELEASES_URL, npmStartEnvironment,
|
|
55815
|
+
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, CWD_HOSTS, hasPrefix, CODEX_STARTUP_TIMEOUT_SEC, CODEX_TOOL_TIMEOUT_SEC, PINNED_PACKAGE, LAUNCHER_PACKAGE, NPM_VERSION, knownNpmVersion, RECOVERY_WORDS, NPX_WALLET_LINE, RELEASES_URL, npmStartEnvironment, WIN_ARG_CODE, NPM_START_KEYS, defaultWalletHome, CMD_UNSAFE, programOf, claudeLineDiffers, WINDOWS_SHELL_CODE, CLAUDE_DESKTOP_FILE, claudeDataDirsCache, CONTINUE_HEADER, tomlString, tomlKey, codexEntryOf, HERMES_TRUST, HERMES_TOOL_TIMEOUT_SEC, hermesCwd, HERMES_OWN_KEYS, HERMES_RESERVED_PROFILES, yamlString, hermesEntryOf, isPlainObject, sameJson, claudeCodeEntry, READ_ONLY_TOOL_NAMES, claudeCodeAllowRules, claudeCodeSettingsFile, UNREADABLE_JSON, JSON_CODEC, indentAt, TEXT_CODEC, RACED;
|
|
55816
55816
|
var init_config = __esm({
|
|
55817
55817
|
"wallet/src/setup/config.mjs"() {
|
|
55818
55818
|
"use strict";
|
|
@@ -55901,7 +55901,7 @@ var init_config = __esm({
|
|
|
55901
55901
|
NPX_WALLET_LINE = /npx (?:--(?:prefer-)?offline )?-y ((?:--no-audit --no-fund )?(?:shinjuku-shield|shinjuku)@(\d+\.\d+\.\d+))((?: (?:setup|restore))(?=\s|$|[^\w-]))?/g;
|
|
55902
55902
|
RELEASES_URL = "https://github.com/ShinjukuStaition/shinjuku-shield#releases";
|
|
55903
55903
|
npmStartEnvironment = (tor) => tor ? { npm_config_offline: "true" } : { npm_config_prefer_offline: "true" };
|
|
55904
|
-
|
|
55904
|
+
WIN_ARG_CODE = /[%&|<>^!"$`\r\n]/;
|
|
55905
55905
|
NPM_START_KEYS = ["npm_config_offline", "npm_config_prefer_offline"];
|
|
55906
55906
|
defaultWalletHome = (home = homedir()) => setupHome({}, home);
|
|
55907
55907
|
CMD_UNSAFE = /[%"\r\n]/;
|
|
@@ -135122,7 +135122,8 @@ ${canonical5}`;
|
|
|
135122
135122
|
return said;
|
|
135123
135123
|
}
|
|
135124
135124
|
if (typeof parsed2.next !== "string") return said;
|
|
135125
|
-
|
|
135125
|
+
const note = typeof nextNote === "function" ? nextNote(parsed2) : nextNote;
|
|
135126
|
+
parsed2.next = `${parsed2.next.replace(/[.\s]+$/, "")}. ${note}`;
|
|
135126
135127
|
const out = JSON.stringify(parsed2, null, /^\s*\{\s*\n/.test(text3) ? 2 : void 0);
|
|
135127
135128
|
return { ...said, text: out, ...blocks ? { content: [{ ...blocks[0], text: out }, ...blocks.slice(1)] } : {} };
|
|
135128
135129
|
}
|
|
@@ -138013,7 +138014,7 @@ ${canonical5}`;
|
|
|
138013
138014
|
const sendStoppedFailure = (job) => ({
|
|
138014
138015
|
code: SEND_STOPPED,
|
|
138015
138016
|
detail: `the app stopped the call before the send of ${usdcText3(job.amountAtomic)} USDC was signed, so the wallet stopped it; nothing was sent`,
|
|
138016
|
-
next: "Nothing was sent. Tell the user the send was stopped and nothing left the private balance. Send it only if the user asks again: then call wallet_unshield with a NEW request_id (it asks the user again)",
|
|
138017
|
+
next: "Nothing was sent. Tell the user the send was stopped and nothing left the private balance. Send it only if the user asks again: then call wallet_unshield with a NEW request_id (it asks the user again, except for an address the user saved, which sends at once)",
|
|
138017
138018
|
say: `Nothing was sent: the send of ${usdcText3(job.amountAtomic)} USDC was stopped before it was signed.`
|
|
138018
138019
|
});
|
|
138019
138020
|
function jobFailure(kind, job, error, linkHeld = /* @__PURE__ */ new Map()) {
|
|
@@ -138797,16 +138798,30 @@ ${canonical5}`;
|
|
|
138797
138798
|
return { ok: false, why: error?.timedOut === true ? `no answer in ${Math.round(elicitTimeoutMs / 1e3)} s` : "this app did not answer the confirmation" };
|
|
138798
138799
|
}
|
|
138799
138800
|
}
|
|
138800
|
-
function intentDoneAtMs(kind) {
|
|
138801
|
+
function intentDoneAtMs(kind, stopped = {}) {
|
|
138802
|
+
const released = () => {
|
|
138803
|
+
stopped.seen = true;
|
|
138804
|
+
return stopped.release === true ? 0 : void 0;
|
|
138805
|
+
};
|
|
138801
138806
|
return (requestId, store) => {
|
|
138802
138807
|
const job = jobs.get(`${kind}:${toRecordId(requestId)}`);
|
|
138803
138808
|
if (job?.state === "done") return job.doneAtMs;
|
|
138809
|
+
if (kind === "unshield" && job?.state === "failed" && job.error?.code === SEND_STOPPED) return released();
|
|
138804
138810
|
if (job?.state === "failed") return /NEW request_id|Do not retry this request/.test(String(job.error?.next ?? "")) ? 0 : void 0;
|
|
138805
138811
|
if (job) return void 0;
|
|
138806
138812
|
const names = kind === "unshield" ? [`self-pay-${moneyId(requestId)}`, privateSendPlanName(moneyId(requestId))] : [KINDS[kind].walName(requestId)];
|
|
138807
138813
|
for (const name of names) {
|
|
138808
138814
|
const record = store.readWal(name);
|
|
138809
138815
|
if (!record) continue;
|
|
138816
|
+
if (kind === "unshield" && name === names[0] && record.schema === SELF_PAY_WAL_SCHEMA && record.state === "started" && record.refusedCode === SEND_STOPPED) {
|
|
138817
|
+
let signed = true;
|
|
138818
|
+
try {
|
|
138819
|
+
signed = selfPayMayHaveSigned(store, moneyId(requestId));
|
|
138820
|
+
} catch {
|
|
138821
|
+
signed = true;
|
|
138822
|
+
}
|
|
138823
|
+
return signed ? void 0 : released();
|
|
138824
|
+
}
|
|
138810
138825
|
const finished = kind !== "unshield" ? ["published", "foreign_funded", "reclaimed"].includes(record.state) : record.schema === PRIVATE_SEND_WAL_SCHEMA ? record.state === "done" || record.state === "cancelled" && privateSendStatus(store, record).done : ["exited", "released", "abandoned"].includes(record.state);
|
|
138811
138826
|
if (!finished) return void 0;
|
|
138812
138827
|
const at = Date.parse(String(record.doneAt ?? "")) || sentAtMs(record);
|
|
@@ -138851,13 +138866,30 @@ ${canonical5}`;
|
|
|
138851
138866
|
}
|
|
138852
138867
|
return void 0;
|
|
138853
138868
|
}
|
|
138869
|
+
const CLAIM_LEASE_WAIT_MS = 8e3;
|
|
138870
|
+
async function claimUnderLease(task) {
|
|
138871
|
+
const until = Date.now() + CLAIM_LEASE_WAIT_MS;
|
|
138872
|
+
for (; ; ) {
|
|
138873
|
+
try {
|
|
138874
|
+
return await underLease(task);
|
|
138875
|
+
} catch (error) {
|
|
138876
|
+
if (!/wallet_process_locked|wallet_locked/.test(String(error?.message ?? error)) || Date.now() >= until) throw error;
|
|
138877
|
+
await new Promise((resolve43) => {
|
|
138878
|
+
const timer = setTimeout(resolve43, 250);
|
|
138879
|
+
timer.unref?.();
|
|
138880
|
+
});
|
|
138881
|
+
}
|
|
138882
|
+
}
|
|
138883
|
+
}
|
|
138854
138884
|
async function beginWithoutId(kind, args, options) {
|
|
138855
138885
|
const spec = KINDS[kind];
|
|
138856
138886
|
const probe = argumentsOf(kind, { ...args, request_id: "intent-probe" }, { probe: true });
|
|
138857
138887
|
if (probe.refusal) return refuse12(...probe.refusal);
|
|
138858
138888
|
let claimed;
|
|
138889
|
+
const stopped = {};
|
|
138859
138890
|
try {
|
|
138860
|
-
|
|
138891
|
+
const found = intents.find(kind, probe, INTENT_WINDOW_MS, intentDoneAtMs(kind, stopped));
|
|
138892
|
+
if (found && !stopped.seen) claimed = { ...found, created: false };
|
|
138861
138893
|
} catch (error) {
|
|
138862
138894
|
return refuse12(
|
|
138863
138895
|
"mcp_wallet_unreadable",
|
|
@@ -138865,13 +138897,21 @@ ${canonical5}`;
|
|
|
138865
138897
|
`call ${spec.tool} again, or pass your own request_id`
|
|
138866
138898
|
);
|
|
138867
138899
|
}
|
|
138900
|
+
if (!claimed) {
|
|
138901
|
+
try {
|
|
138902
|
+
claimed = await claimUnderLease(() => intents.claim(kind, probe, INTENT_WINDOW_MS, intentDoneAtMs(kind, { release: true })));
|
|
138903
|
+
} catch (error) {
|
|
138904
|
+
return /^(?:wallet_locked|wallet_process_locked)$/.test(errorCode2(error, "wallet_locked")) ? refuse12(
|
|
138905
|
+
"wallet_locked",
|
|
138906
|
+
"another program is using this wallet right now, so this call did not start anything; another app may be running the same request",
|
|
138907
|
+
`This call did not start a ${spec.noun}. Do not tell the user whether money moved: first call ${spec.tool === "wallet_unshield" ? "wallet_cancel with no request_id, or wallet_receipts" : "wallet_receipts"}, or call ${spec.tool} again with the same arguments in about a minute (it reads the same request and never moves money twice). If it repeats, tell the user another program (for example a Shinjuku terminal window) is using the wallet`,
|
|
138908
|
+
{ done: false, say: "The wallet is busy with another program right now, so this request did not start here. I will check and try again.", ...lockedFields() }
|
|
138909
|
+
) : refuse12("mcp_wallet_unreadable", describeError(error, { fallback: "wallet_store_unreadable" }), `call ${spec.tool} again, or pass your own request_id`);
|
|
138910
|
+
}
|
|
138911
|
+
}
|
|
138868
138912
|
if (claimed.created) log(`MCP_INTENT_NEW kind=${kind} requestId=${claimed.requestId}`);
|
|
138869
138913
|
const answer = await begin(kind, { ...args, request_id: claimed.requestId }, options);
|
|
138870
|
-
return withAutoId(
|
|
138871
|
-
answer,
|
|
138872
|
-
spec.tool,
|
|
138873
|
-
"The same call without request_id within 10 minutes after it ends reads this same request; if the user wants to do it again later, ask after 10 minutes or give a new request_id."
|
|
138874
|
-
);
|
|
138914
|
+
return withAutoId(answer, spec.tool, (parsed2) => kind === "unshield" && parsed2.error === SEND_STOPPED ? "The same call without request_id reads this stopped send again; to send it, the user must ask again and you pass a NEW request_id." : "The same call without request_id within 10 minutes after it ends reads this same request; if the user wants to do it again later, ask after 10 minutes or give a new request_id.");
|
|
138875
138915
|
}
|
|
138876
138916
|
function stageChanged(job) {
|
|
138877
138917
|
if (!job.changed) {
|
|
@@ -140556,7 +140596,7 @@ ${canonical5}`;
|
|
|
140556
140596
|
name: "wallet_unshield",
|
|
140557
140597
|
// UX130-13: a host that defers tools may show only the title: it says where a send goes by default.
|
|
140558
140598
|
title: "Send USDC privately",
|
|
140559
|
-
description: `Use this when the user says "send 2 USDC to <address>" or "withdraw to my wallet" (for "my wallet" leave \`to\` out: it uses the address saved at setup, or says how to set one; never ask the user first): it sends amount (USDC, like "2"; or amount_atomic) from the PRIVATE balance as plain USDC to \`to\`, a public Solana address. BEFORE you call it to send all of the balance when wallet_balance showed balanceParts above 1, write to the user that the wallet first gets the balance ready to send (do not tell the user how the wallet stores the balance; some apps show nothing until this call ends). Privately: the chain shows the pool paying the address, not which wallet paid. The wallet's own key (ownAddress in wallet_balance) is this wallet's public address: it holds the public USDC, wallet_shield deposits from it, and wallet_transfer_token sells from it. So it is refused as \`to\`: an exit there would show on chain that the private balance belongs to this wallet. This holds whether or not that key ever deposited: wallet_add_funds deposits come from one-time addresses, not from this key, so never tell the user the deposits came from it. Shinjuku pays every network fee; no SOL is needed. The user's saved own addresses (setup or this app's wallet entry) send at once. Any other address is sent only after the user confirms it in
|
|
140599
|
+
description: `Use this when the user says "send 2 USDC to <address>" or "withdraw to my wallet" (for "my wallet" leave \`to\` out: it uses the address saved at setup, or says how to set one; never ask the user first): it sends amount (USDC, like "2"; or amount_atomic) from the PRIVATE balance as plain USDC to \`to\`, a public Solana address. BEFORE you call it to send all of the balance when wallet_balance showed balanceParts above 1, write to the user that the wallet first gets the balance ready to send (do not tell the user how the wallet stores the balance; some apps show nothing until this call ends). Privately: the chain shows the pool paying the address, not which wallet paid. The wallet's own key (ownAddress in wallet_balance) is this wallet's public address: it holds the public USDC, wallet_shield deposits from it, and wallet_transfer_token sells from it. So it is refused as \`to\`: an exit there would show on chain that the private balance belongs to this wallet. This holds whether or not that key ever deposited: wallet_add_funds deposits come from one-time addresses, not from this key, so never tell the user the deposits came from it. Shinjuku pays every network fee; no SOL is needed. The user's saved own addresses (setup or this app's wallet entry) send at once. Any other address is sent only after the user confirms it in a dialog of this app; a client that cannot ask is refused (mcp_unshield_to_not_allowed) and a decline sends nothing (mcp_unshield_declined). \`to\` must already be able to receive USDC: an address that cannot is refused before any dialog (mcp_unshield_to_invalid). It runs in steps and may wait for the pool's next anchor: the call answers within about 20 s with stage (confirming, queued, refreshing, self-pay = preparing, exit = sending, done; joining = the wallet first gets the balance ready to send, then sends; each call goes on with it (joinSteps: its steps, one after another; doneInMinutesLow to doneInMinutesHigh: the time to say), ok: true); call wallet_unshield again with the SAME request_id, amount, and to for the status (each call answers within about 20 s, at once when the send ends; a dialog may take longer). When the wallet must first get the balance ready to send, the FIRST call answers at once with stage joining and joinTellFirst: true; write its say to the user, then call again with the same request_id at once. One exception: for a send whose balance must first be made ready, when this app sends a progress token with the call, that next call gets the balance ready and then sends, with a progress line every ${JOIN_STEP_MS / 1e3} s ("getting your balance ready to send"; some apps show none of them, so the line is said before the call, as above). It answers when the send is done, or after about ${joinAnswerSeconds(JOIN_CALL_MAX_MS)} s with how far it got (joinsDone; sendState sending: the USDC is leaving, never say nothing moved); then call again with the same request_id. Without a progress token it answers within about 20 s with stage joining: call again until it sends. The same request_id never sends twice, also after a restart. request_id is optional: without it the answer names the id it made, and the same call again within 10 minutes after it ends reads that same send. An optional limit the user sets (the unshield limit) may bound each call and what this wallet sends in any 24 hours, from every app that runs it (mcp_unshield_cap_exceeded: tell the user). Other refusals: mcp_argument_invalid, mcp_request_id_reused, wallet_locked, mcp_tool_disabled, mcp_unshield_failed, and the unshield's own p03_* codes. A call the app stopped or calls rejected or interrupted, or one that failed, may still send: call wallet_cancel (no request_id) before you tell the user anything about that send; never say nothing was sent without it. A send is one payment to \`to\`. ${HOST_BLOCKED_LINE}`,
|
|
140560
140600
|
inputSchema: {
|
|
140561
140601
|
type: "object",
|
|
140562
140602
|
properties: {
|
|
@@ -145702,7 +145742,7 @@ var init_stdioServer = __esm({
|
|
|
145702
145742
|
SUPPORTED_PROTOCOL_VERSIONS = Object.freeze(["2025-06-18", "2025-03-26", "2024-11-05"]);
|
|
145703
145743
|
MAX_LINE_BYTES = 4 * 1024 * 1024;
|
|
145704
145744
|
POSITIVE_ATOMIC7 = /^[1-9][0-9]{0,30}$/;
|
|
145705
|
-
INSTRUCTIONS_BASE = `A self-custody Shinjuku Shield wallet on this machine; no tool takes or returns its keys or passphrase. Each answer's say is one plain sentence for the user; other fields hold numbers. Never tell the user a tool, field, code or protocol name (x402, MCP) unless told to. Map a plain request to one tool: "what is my balance" -> wallet_balance (safe at any time); "add money" / "deposit" / "move USDC in from Phantom or an exchange" -> wallet_add_funds (a one-time address; the next wallet_balance after the USDC arrives makes it private, up to 5 USDC); "shield the USDC on this wallet's own address" -> wallet_shield; "stop" / "cancel" -> wallet_cancel (the request_id of what to stop); "pay this URL" -> pay_for_service (no preview needed); "what does this URL cost" -> check_price (only when asked); "find a paid API for X" -> find_paid_services, then pay its url; "send 2 USDC to <address>" -> wallet_unshield; "show my payments" -> wallet_receipts; "send another token" -> wallet_transfer_token; "which AI models" -> inference_models; "ask an AI model" -> inference_chat; "give my other AI app a private AI" -> inference_server
|
|
145745
|
+
INSTRUCTIONS_BASE = `A self-custody Shinjuku Shield wallet on this machine; no tool takes or returns its keys or passphrase. Each answer's say is one plain sentence for the user; other fields hold numbers. Never tell the user a tool, field, code or protocol name (x402, MCP) unless told to. Map a plain request to one tool: "what is my balance" -> wallet_balance (safe at any time); "add money" / "deposit" / "move USDC in from Phantom or an exchange" -> wallet_add_funds (a one-time address; the next wallet_balance after the USDC arrives makes it private, up to 5 USDC); "shield the USDC on this wallet's own address" -> wallet_shield; "stop" / "cancel" -> wallet_cancel (the request_id of what to stop); "pay this URL" -> pay_for_service (no preview needed); "what does this URL cost" -> check_price (only when asked); "find a paid API for X" -> find_paid_services, then pay its url; "send 2 USDC to <address>" -> wallet_unshield; "show my payments" -> wallet_receipts; "send another token" -> wallet_transfer_token; "which AI models" -> inference_models; "ask an AI model" -> inference_chat; "give my other AI app a private AI" -> inference_server. wallet_balance answers ONE balance (balanceAtomic); pay_for_service pays any paid URL from it. Fields ending in Atomic are atomic units (1000000 = 1 USDC); tell the user USDC. The wallet does its own upkeep. A shield, add-funds or unshield call can run for minutes: call again with the SAME request_id as next says. Pass your own request_id to pay_for_service: the same one never pays or moves money twice (a code ending in _retry_same_request: call again with it). pay_for_service never pays above the spending limits (one payment; 24 hours); with none, the balance is the only bound. Never claim a payment happened unless the answer has a transaction. After a pay or send call that stopped or failed (also one this app calls rejected or interrupted), call wallet_receipts (a payment) or wallet_cancel (a send; no request_id) before you say whether it happened; never say nothing moved without that. Privacy: the chain does not show which wallet paid, but this app and its model provider see every URL, body, price and answer you handle; reach a seller or its domain only through these tools, never yourself (no curl, browser, DNS or DNS-over-HTTPS lookup), also when the user asks for no Tor: that shows their IP address to the site or a DNS company. When an answer's poolSwitch.items[] item has tellUser true, tell the user its message once, in plain words; the wallet moves the balance by itself.`;
|
|
145706
145746
|
SELL_LINE = "To sell or swap a token the wallet holds: wallet_transfer_token.";
|
|
145707
145747
|
OWN_ADDRESS_LINE = '"Send to my (main) wallet": wallet_unshield with no to uses the address saved at setup; never ask for it.';
|
|
145708
145748
|
INSTRUCTIONS = `${INSTRUCTIONS_BASE} ${SELL_LINE} ${OWN_ADDRESS_LINE} ${HOST_BLOCKED_LINE}`;
|
|
@@ -162197,7 +162237,10 @@ async function runSetupCommand(values, deps) {
|
|
|
162197
162237
|
readsBack ? "Setup keeps the restored wallet on this machine (your keys never leave it), downloads and checks the setup files, and writes config.json." : "Setup makes the wallet on this machine (your keys never leave it), downloads and checks the setup files, and writes config.json.",
|
|
162198
162238
|
// 0.3.97 T4, live proof 2026-10-24: the command on its own line.
|
|
162199
162239
|
"An agent app then starts it with this command:",
|
|
162200
|
-
|
|
162240
|
+
// Row 25 rerun on 0.3.174 (check C): the line a user may copy into an app setup cannot add has the app entry's
|
|
162241
|
+
// --prefix (npm reads no .npmrc of the folder the app starts in); a Windows home with a cmd sign, $ or ` gets none, as
|
|
162242
|
+
// the entry. Quoted for the user's shell (hostShellWord: single quotes on POSIX; Codex round 1 on 1b3aaa99 item 2).
|
|
162243
|
+
` ${oneTimeCommandLine("mcp", npmVersion, { npmArgs: npmPrefixArgs(home, deps.platform ?? process.platform).map((word2) => hostShellWord(word2, deps.platform ?? process.platform)) })}`,
|
|
162201
162244
|
""
|
|
162202
162245
|
],
|
|
162203
162246
|
// The status line too, when a terminal setup started this run and printed it (AB234's live run 2026-11-04 showed
|