shinjuku-shield 0.3.91 → 0.3.92
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 +16 -13
package/README.md
CHANGED
|
@@ -6,13 +6,13 @@ answers privately, in a terminal chat or for your agent app. Its `mcp`
|
|
|
6
6
|
command runs a local MCP server (stdio) for your agent. Your keys never
|
|
7
7
|
leave your machine.
|
|
8
8
|
|
|
9
|
-
This is version 0.3.
|
|
9
|
+
This is version 0.3.92. The npm packages `shinjuku-shield` and
|
|
10
10
|
`shinjuku-shielded` hold the same files; `shinjuku` is the short command.
|
|
11
11
|
|
|
12
12
|
## Set up
|
|
13
13
|
|
|
14
14
|
```sh
|
|
15
|
-
npx -y --no-audit --no-fund shinjuku-shield@0.3.
|
|
15
|
+
npx -y --no-audit --no-fund shinjuku-shield@0.3.92 setup
|
|
16
16
|
```
|
|
17
17
|
|
|
18
18
|
Setup makes the wallet on this machine, a private passphrase file, and the
|
|
@@ -24,7 +24,7 @@ server to that host's config.
|
|
|
24
24
|
## The `shinjuku` command
|
|
25
25
|
|
|
26
26
|
```sh
|
|
27
|
-
npm install -g shinjuku@0.3.
|
|
27
|
+
npm install -g shinjuku@0.3.92
|
|
28
28
|
shinjuku help
|
|
29
29
|
```
|
|
30
30
|
|
|
@@ -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-shielded -- npx -y --no-audit --no-fund shinjuku-shield@0.3.
|
|
39
|
+
claude mcp add --scope user shinjuku-shielded -- npx -y --no-audit --no-fund shinjuku-shield@0.3.92 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-shielded": { "command": "npx", "args": ["-y", "--no-audit", "--no-fund", "shinjuku-shield@0.3.
|
|
45
|
+
{ "mcpServers": { "shinjuku-shielded": { "command": "npx", "args": ["-y", "--no-audit", "--no-fund", "shinjuku-shield@0.3.92", "mcp"] } } }
|
|
46
46
|
```
|
|
47
47
|
|
|
48
48
|
On native Windows, if the host cannot find `npx`, use `"command": "cmd"` and
|
package/manifest.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema": "carbon-shielded-wallet/bundle-manifest/v1",
|
|
3
3
|
"file": "shinjuku-wallet.mjs",
|
|
4
|
-
"sha256": "
|
|
5
|
-
"bytes":
|
|
6
|
-
"sourceCommit": "
|
|
4
|
+
"sha256": "afa037c8868c722838c0642335b1767af4bcc0040878ae441e83cb94dd9aeea2",
|
|
5
|
+
"bytes": 12692822,
|
|
6
|
+
"sourceCommit": "3b6e926704a348088fa33d114ed7913e2d610033",
|
|
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",
|
|
@@ -1297,5 +1297,5 @@
|
|
|
1297
1297
|
"version": "1.8.0"
|
|
1298
1298
|
}
|
|
1299
1299
|
],
|
|
1300
|
-
"publishedAt": "2026-10-
|
|
1300
|
+
"publishedAt": "2026-10-24T02:20:31.413Z"
|
|
1301
1301
|
}
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "shinjuku-shield",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.92",
|
|
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": "afa037c8",
|
|
7
|
+
"shinjukuSha256": "afa037c8868c722838c0642335b1767af4bcc0040878ae441e83cb94dd9aeea2",
|
|
8
8
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
9
9
|
"author": "Shinjuku Shielded",
|
|
10
10
|
"homepage": "https://github.com/ShinjukuStaition/shinjuku-mcp#readme",
|
package/shinjuku-wallet.mjs
CHANGED
|
@@ -127591,7 +127591,7 @@ ${canonical5}`;
|
|
|
127591
127591
|
const balance = {
|
|
127592
127592
|
name: "wallet_balance",
|
|
127593
127593
|
title: "Balance",
|
|
127594
|
-
description: `Use this when the user asks "what is my balance" or "how much USDC do I have": it answers ONE balance (balanceAtomic, what x402_pay can spend) and the public (unshielded) USDC. Pays nothing and signs nothing. When the user asks to see the wallet ("show my wallet"), print \`card\` as it is
|
|
127594
|
+
description: `Use this when the user asks "what is my balance" or "how much USDC do I have": it answers ONE balance (balanceAtomic, what x402_pay can spend) and the public (unshielded) USDC. Pays nothing and signs nothing. When the user asks to see the wallet ("show my wallet"), print \`card\` as it is (at most 8 lines: balances, Tor, the last 3 payments, example requests). balanceParts (only above 1): a send of all of it first gets the balance ready to send (next says the minutes; never say parts or join to the user). balanceAtomic is one number; breakdown names its parts (breakdown.shieldedAtomic is what wallet_unshield can send; privateSendPendingAtomic is the part of a running private send (wallet_unshield with parts or max_delay_minutes) not sent yet, already taken off shieldedAtomic; refundsInFlightAtomic is a Shinjuku refund on its way back; setAsideAtomic (only when not 0) is value an older version of this wallet set aside to pay sellers; during a pool move, pools lists each pool's part and movingAtomic is value on its way from the old pool to the new one; the move field shows the move, poolSwitches each switch). UNSHIELDED (unshieldedAtomic) is the plain public USDC on the wallet's own Solana key (ownAddress), the USDC wallet_shield makes private; unshieldedSolLamports is that key's SOL, information only: wallet_shield needs none (the facilitator's relayer pays every fee and rent). When the local balance is stale (a new deposit, a received payment), it reads the chain by itself first; when that takes longer than about 20 s it answers the last balance with refreshing: true and finishes in the background (call wallet_balance again in 30 s). A balance with refreshing: true and refreshReason is exact (payment_settling: a payment settles and the number counts it; account_join: the wallet gets its own balance ready to send and the number counts all of it; pool_move: value from the old pool arrives and the number counts it; refund_check: a refund counted from an old read, which the wallet checks now (never tell the user it is still on its way); first_check: a new wallet's first history check, the number is its own landed deposits). status reading (balanceAtomic null): the first balance read of a wallet that may hold money is not done; call wallet_balance again in 30 s. If the public read fails, unshieldedAtomic is null with unshieldedReason; the rest still answers. ownKeyTokens (only when there are any): the other tokens on ownAddress (not its USDC), each { mint, amountAtomic, decimals, amount }, at most 10 (ownKeyTokensMore counts the rest); a token is its mint, never a name or symbol; wallet_transfer_token with that mint as token_mint sells one and sends the USDC privately. earlierDeposits (only when there are any): USDC found at a one-time deposit address of an earlier pool, each with a notice line to tell the user; the wallet moves it into the current pool by itself. addFunds (only when there are any): each wallet_add_funds address still open, with its state and the USDC known to wait there (heldAtomic; null with heldNote when the address was not checked yet). startsAtNextRequest true (old name): its deposit is not sent yet; once the wallet has seen USDC there, it sends it by itself in about startsInMinutes + 1 minutes, in every host, with no ask. landingAtomic (only when not 0): USDC you added whose deposit landed on chain and that balanceAtomic does not count yet; this call finishes it and waits about 20 s for it, past that it is being counted: call wallet_balance again as next says (at once in the same turn when this call waited its 20 s, else in 30 s). session: the spending limits (null or "none": no limit), what is left, and how to change them (session.summary, only when a limit is set). With no limit set, say nothing about limits or the session counters (limit bookkeeping; they may count earlier conversations). To add money, use wallet_add_funds. Amounts are atomic units (USDC: 1000000 = 1 USDC); say and usdc give them in USDC.`,
|
|
127595
127595
|
inputSchema: { type: "object", properties: {
|
|
127596
127596
|
verbose: { type: "boolean", description: "Optional. true adds `internal`: the engineering numbers (funded accounts, notes, payments without waiting, a 0 set-aside value). Default false." }
|
|
127597
127597
|
}, additionalProperties: false },
|
|
@@ -129812,7 +129812,7 @@ ${canonical5}`;
|
|
|
129812
129812
|
decimals = Number(session.openStore().state.decimals);
|
|
129813
129813
|
} catch {
|
|
129814
129814
|
}
|
|
129815
|
-
const amount =
|
|
129815
|
+
const amount = usdcText2(job.amountAtomic, decimals);
|
|
129816
129816
|
const askedAt = Date.now();
|
|
129817
129817
|
try {
|
|
129818
129818
|
const how = isSplitSend(job) ? job.parts === 1 ? ` after a random wait of up to ${job.maxDelayMinutes} min` : ` as ${job.parts} separate exits of unequal size, each after a random wait of up to ${job.maxDelayMinutes} min` : "";
|
|
@@ -130105,13 +130105,13 @@ ${canonical5}`;
|
|
|
130105
130105
|
}
|
|
130106
130106
|
if (checkInput) {
|
|
130107
130107
|
try {
|
|
130108
|
-
await recipientCheck(checkInput);
|
|
130108
|
+
await withTimeout(recipientCheck(checkInput), RECIPIENT_CHECK_TIMEOUT_MS);
|
|
130109
130109
|
} catch (error) {
|
|
130110
130110
|
if (errorCode2(error, "") === "mcp_unshield_to_invalid") {
|
|
130111
130111
|
log(`MCP_UNSHIELD_TO_REFUSED requestId=${request.requestId}`);
|
|
130112
130112
|
return refuse12("mcp_unshield_to_invalid", /has no USDC token account/.test(String(error?.message)) ? UNSHIELD_TO_NO_USDC_DETAIL : String(error.message).replace(/^mcp_unshield_to_invalid:\s*/, ""), UNSHIELD_TO_INVALID_NEXT, { requestId: request.requestId, to: request.to });
|
|
130113
130113
|
}
|
|
130114
|
-
log(`MCP_UNSHIELD_TO_CHECK_SKIPPED requestId=${request.requestId} ${errorCode2(error, "unknown")}`);
|
|
130114
|
+
log(`MCP_UNSHIELD_TO_CHECK_SKIPPED requestId=${request.requestId} ${error?.timedOut === true ? "timeout" : errorCode2(error, "unknown")}`);
|
|
130115
130115
|
}
|
|
130116
130116
|
}
|
|
130117
130117
|
}
|
|
@@ -131189,7 +131189,7 @@ ${canonical5}`;
|
|
|
131189
131189
|
const unshield = {
|
|
131190
131190
|
name: "wallet_unshield",
|
|
131191
131191
|
title: "Send USDC privately from the shielded balance",
|
|
131192
|
-
description: `Use this when the user says "send 2 USDC to <address>" or "withdraw to my wallet" (leave \`to\` out for the owner's own wallet when one is set): it sends amount (USDC, like "2"; or amount_atomic) from the SHIELDED balance as plain USDC to \`to\`, a public Solana address (the USDC goes to its USDC token account). BEFORE you call it to send all of the balance when wallet_balance showed balanceParts above 1, write to the user that it takes about joinMinutes minutes (the wallet first gets the balance ready to send; never say parts or join to the user; 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. The facilitator pays every network fee; no SOL is needed. The owner's --unshield-to addresses send at once. Any other address is sent only after the user confirms it in the MCP client (a confirmation dialog); a client that cannot ask is refused (mcp_unshield_to_not_allowed) and a decline sends nothing (mcp_unshield_declined). \`to\` must already hold USDC (have a USDC token account): an address without one is refused before any dialog (mcp_unshield_to_invalid). It takes minutes (one wait of up to 5 minutes is normal): 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; the answer says how many more asks and when (joinAsks, joinMinutes), 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 confirmation dialog the user answers may take longer). When the balance is in several parts, 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 single send (no parts, no delay) whose balance is in several parts, when this MCP app sends a progress token with the call, that next call joins the parts and then sends, taking up to ${JOIN_CALL_MAX_MS / 6e4} minutes, with a progress line every ${JOIN_STEP_MS / 1e3} s ("getting your balance ready to send (about M min)"; some apps show none of them, so the time is said before the call, as above). Without a progress token it answers within about 20 s with stage joining and when to ask again. 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. When it lands, the wallet writes an encrypted backup (backupPath). x402_pay calls wait while it runs. An optional owner cap (--max-unshield) may bound each call and what this wallet sends in any 24 hours, from every MCP process (mcp_unshield_cap_exceeded: tell the owner). Other refusals: mcp_argument_invalid, mcp_request_id_reused, mcp_unshield_to_invalid, wallet_locked, mcp_tool_disabled, mcp_unshield_failed, and the unshield's own p03_* codes. PRIVATE SEND (optional): when the user says "send it in parts", "spread it out", or "do not send it all at once", pass parts (2-8) WITH max_delay_minutes (1-60;
|
|
131192
|
+
description: `Use this when the user says "send 2 USDC to <address>" or "withdraw to my wallet" (leave \`to\` out for the owner's own wallet when one is set): it sends amount (USDC, like "2"; or amount_atomic) from the SHIELDED balance as plain USDC to \`to\`, a public Solana address (the USDC goes to its USDC token account). BEFORE you call it to send all of the balance when wallet_balance showed balanceParts above 1, write to the user that it takes about joinMinutes minutes (the wallet first gets the balance ready to send; never say parts or join to the user; 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. The facilitator pays every network fee; no SOL is needed. The owner's --unshield-to addresses send at once. Any other address is sent only after the user confirms it in the MCP client (a confirmation dialog); a client that cannot ask is refused (mcp_unshield_to_not_allowed) and a decline sends nothing (mcp_unshield_declined). \`to\` must already hold USDC (have a USDC token account): an address without one is refused before any dialog (mcp_unshield_to_invalid). It takes minutes (one wait of up to 5 minutes is normal): 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; the answer says how many more asks and when (joinAsks, joinMinutes), 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 confirmation dialog the user answers may take longer). When the balance is in several parts, 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 single send (no parts, no delay) whose balance is in several parts, when this MCP app sends a progress token with the call, that next call joins the parts and then sends, taking up to ${JOIN_CALL_MAX_MS / 6e4} minutes, with a progress line every ${JOIN_STEP_MS / 1e3} s ("getting your balance ready to send (about M min)"; some apps show none of them, so the time is said before the call, as above). Without a progress token it answers within about 20 s with stage joining and when to ask again. 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. When it lands, the wallet writes an encrypted backup (backupPath). x402_pay calls wait while it runs. An optional owner cap (--max-unshield) may bound each call and what this wallet sends in any 24 hours, from every MCP process (mcp_unshield_cap_exceeded: tell the owner). Other refusals: mcp_argument_invalid, mcp_request_id_reused, mcp_unshield_to_invalid, wallet_locked, mcp_tool_disabled, mcp_unshield_failed, and the unshield's own p03_* codes. PRIVATE SEND (optional): when the user says "send it in parts", "spread it out", or "do not send it all at once", pass parts (2-8) WITH max_delay_minutes (1-60); the parts argument says how it works, and its privacy limit, which you tell the user.`,
|
|
131193
131193
|
inputSchema: {
|
|
131194
131194
|
type: "object",
|
|
131195
131195
|
properties: {
|
|
@@ -131197,7 +131197,7 @@ ${canonical5}`;
|
|
|
131197
131197
|
amount_atomic: { type: "string", pattern: "^[1-9][0-9]*$", description: "USDC to send, in atomic units (1000000 = 1 USDC)." },
|
|
131198
131198
|
to: { type: "string", description: "The receiving Solana address (base58), exactly as the user gave it. Leave it out to send to the owner's own wallet when the owner set exactly one (wallet_balance session.unshield.to); with none or several set, pass it." },
|
|
131199
131199
|
request_id: { type: "string", pattern: "^[A-Za-z0-9._:-]{1,128}$", description: "Optional. Your stable name for this send, like send-1; pass it again to read the status." },
|
|
131200
|
-
parts: { type: "integer", minimum: 1, maximum: 8, description: "Optional, default 1: send the amount as this many separate exits of unequal size (a private send). Each part carries at least 10000 atomic (0.01 USDC). Above 1 it needs max_delay_minutes 1-60." },
|
|
131200
|
+
parts: { type: "integer", minimum: 1, maximum: 8, description: "Optional, default 1: send the amount as this many separate exits of unequal size (a private send). Each part carries at least 10000 atomic (0.01 USDC). Above 1 it needs max_delay_minutes 1-60 (parts with no wait are refused: they would leave together). Each part is sent after a random wait of up to max_delay_minutes (part 1 too), so the chain shows no single exit of this amount at this time; max_delay_minutes alone delays one exit. " + SEND_RUNS_ON + ` Late parts never go together. While parts are unsent, x402_pay may spend only the rest of the balance. The plan is saved in the wallet before part 1, so the same request_id (with the same parts and max_delay_minutes) continues after a restart and never sends a part twice; the answer's privateSend lists each part (state, amount, when it may go, transactions), sentAtomic, and remainingAtomic. The user confirms the whole send once. Each part is a full unshield, so it takes as long as one, and the facilitator pays the network fee of each. Privacy limit (tell the user): every part goes to the SAME \`to\`, so anyone who adds up that address's incoming transfers sees the total; the parts hide the time and the single amount of the exit, not the sum the address received. wallet_cancel with the same request_id stops the parts not sent yet (their value stays in the shielded balance); while a part is being sent, that call waits for the part to finish, up to about ${CALL_BUDGET_MS / 1e3} s.` },
|
|
131201
131201
|
max_delay_minutes: { type: "integer", minimum: 0, maximum: 60, description: "Optional, default 0: each part, part 1 included, is sent after a random wait of up to this many minutes (a private send)." }
|
|
131202
131202
|
},
|
|
131203
131203
|
additionalProperties: false
|
|
@@ -132164,7 +132164,7 @@ ${canonical5}`;
|
|
|
132164
132164
|
async function confirmTransfer(request, quote, decimals) {
|
|
132165
132165
|
const usdcOut = usdcText2(BigInt(quote.outAtomic));
|
|
132166
132166
|
const usdcMin = usdcText2(BigInt(quote.minOutAtomic));
|
|
132167
|
-
const amount =
|
|
132167
|
+
const amount = usdcText2(request.amountAtomic, decimals);
|
|
132168
132168
|
const message = `Sell ${amount} of token ${request.tokenMint} for about ${usdcOut} USDC (at least ${usdcMin}; price impact ${(Number(quote.priceImpactPct) * 100).toFixed(2)} %), shield it, and send it to ${request.to} as ${request.parts} parts, each after a random wait of up to ${request.maxDelayMinutes} min? The address receives USDC, not the token.`;
|
|
132169
132169
|
const askedAt = Date.now();
|
|
132170
132170
|
try {
|
|
@@ -133648,7 +133648,7 @@ function createSetupTools({
|
|
|
133648
133648
|
};
|
|
133649
133649
|
return { tools: [setupTool, statusTool, ...MCP_TOOL_NAMES.map((name) => name === "x402_discover" ? discoverTool(discoverCacheDir) : notSetUp(name))], doneTool };
|
|
133650
133650
|
}
|
|
133651
|
-
var import_web3133, shownCaps, RELEASE_RETRY_MS, STAGE_WORDS, stageWords, INTERNAL_BALANCE_DETAIL, shownBreakdown, sessionLeftShown, TOKEN_UNIT_TOOLS, RESOURCE_PAYMENT_WAL_PREFIX2, POOL_LAYOUT_CODE, POOL_LAYOUT_UPDATE, USEPOD_VIA_INFERENCE_CHAT, SEND_RUNS_ON, DEPOSIT_RUNS_ON, CLI_FUNDS_PLAN_PREFIX, CLI_FUNDS_SCHEMA, SELF_PAY_ORIGIN3, REQUEST_ID4, POSITIVE_ATOMIC6, PRIVATE_HOST3, FORBIDDEN_HEADERS3, MAX_BODY_BYTES2, PREVIEW_TIMEOUT_MS, PREVIEW_SELLER_READ_MS, CALL_BUDGET_MS, budgetLeft, MONEY_FIRST_ANSWER_MS, BALANCE_AFTER_LANDING_MS, JOIN_CALL_MAX_MS, JOIN_NUDGE_QUIET_MS, JOIN_STEP_MS, sleep2, PROGRESS_EVERY_MS2, READ_BUDGET_MS, UNPAID_TOR_TRY_MS, UNPAID_CLEAR_MS, READ_BUDGET_TOOLS, FLOAT_BUSY_CODES, RETRY_MARGIN_MS, ASK_PAY_CODES, runningNpmVersion, terminalCommand, capPlaceWords, capRaiseText, cheaperSellerText, limitNext, SAFE_TEXT, MCP_TOOL_ALIASES, POOL_SWITCH_WHY, POOL_SWITCH_NEXT, SWITCH_STATES, quietSwitch, switchKey, ATOMIC_TEXT, FLOAT_ID, ANSWERED_EXIT_RETRY_MS, ANSWERED_EXIT_UNCONFIRMED_MS, ANSWERED_EXIT_RETRY_WINDOW_MS, ANSWERED_EXIT_CLOSED, switchAmount, switchEta, switchRows, OWNER_CAP_CODES, JOIN_END_MCP, JOIN_END_TERMINAL_LIBRARY, JOIN_RETRY_BACKOFF_MS, WALLET_CAP_FIX, MCP_CAP_FIX, capFix, ownerOnlyNext, mcpNext, CONFIDENTIAL_RETIRED, json3, answerResult, discoverTool, refuse12, publicOffer, FLOAT_PAID_CODES, FLOAT_PRIVATE_LEG, floatStillSettling, MONEY_ID2, toRecordId, linkKindOf, moneyId, REFUSED_CODES, refusedCodeOf, PLAIN_REASONS, plainReason, KEPT_SEND_TRIES, shownId, isSplitSend, sendPartId, PROMISED_NEXT, PUBLIC_READ_TIMEOUT_MS, withTimeout, ownKey, readFailure, OWN_KEY_TOKENS_MAX, OWN_TOKENS_GRACE_MS, tokenAmountText, elsewhereId, AGENT_ID_SCHEMA, agentIdName, minutesText2, ageWords2, DEPOSIT_SENT_STATES, depositLanded, usdcText2, walkWalletHistory, REFRESH_LEASE_WALK_MS, HOME_MARKS_SETTLED_MS2, AUTO_BACKUPS_KEPT, AUTO_BACKUP_NAME, AUTO_BACKUP_VERIFIED, FRONTED_SETTLE_MARGIN_SLOTS, BALANCE_REFRESH_WAIT_MS, BALANCE_REFRESH_GRACE_MS, BALANCE_REFRESH_LONG_MS, INBOUND_REFRESH_AGE_MS, CAP_BALANCE_WAIT_MS, CAP_BALANCE_RETRY_MS, REFRESH_RETRY_MS, FINALITY_POLL_MS, FINALITY_WAIT_MS, FINALITY_REFRESH_LIMIT_MS, POOL_WATCH_MS, POOL_WATCH_POLL_MS, EARLY_BALANCE_DELAY_MS, FINALITY_SETTLE_WINDOW_SLOTS, PUBLIC_READ_ANSWER_MS, SWITCH_WAIT_MS, UNSHIELD_TO_NO_USDC_DETAIL, UNSHIELD_TO_INVALID_NEXT, INFERENCE_MIN_MAX_TOKENS, ELICIT_TIMEOUT_MS, ELICIT_UNSHOWN_MS, elicitUnshown, POLL_SECONDS3, TRANSFER_CHANGE_READ_MS, TEMP_CLEAN_DELAY_MS, KEPT_ON_DISK, MAX_SHIELDED_BALANCE_ATOMIC, receiveGenerator, MCP_TOOL_NAMES, MCP_HIDDEN_TOOL_NAMES, setupTerminalNext, SETUP_POLL_NEXT, PRIVATE_INFERENCE_WHY, PRIVATE_INFERENCE_NEXT;
|
|
133651
|
+
var import_web3133, shownCaps, RELEASE_RETRY_MS, STAGE_WORDS, stageWords, INTERNAL_BALANCE_DETAIL, shownBreakdown, sessionLeftShown, TOKEN_UNIT_TOOLS, RESOURCE_PAYMENT_WAL_PREFIX2, POOL_LAYOUT_CODE, POOL_LAYOUT_UPDATE, USEPOD_VIA_INFERENCE_CHAT, SEND_RUNS_ON, DEPOSIT_RUNS_ON, CLI_FUNDS_PLAN_PREFIX, CLI_FUNDS_SCHEMA, SELF_PAY_ORIGIN3, REQUEST_ID4, POSITIVE_ATOMIC6, PRIVATE_HOST3, FORBIDDEN_HEADERS3, MAX_BODY_BYTES2, PREVIEW_TIMEOUT_MS, PREVIEW_SELLER_READ_MS, CALL_BUDGET_MS, budgetLeft, MONEY_FIRST_ANSWER_MS, BALANCE_AFTER_LANDING_MS, JOIN_CALL_MAX_MS, JOIN_NUDGE_QUIET_MS, JOIN_STEP_MS, sleep2, PROGRESS_EVERY_MS2, READ_BUDGET_MS, UNPAID_TOR_TRY_MS, UNPAID_CLEAR_MS, READ_BUDGET_TOOLS, FLOAT_BUSY_CODES, RETRY_MARGIN_MS, ASK_PAY_CODES, runningNpmVersion, terminalCommand, capPlaceWords, capRaiseText, cheaperSellerText, limitNext, SAFE_TEXT, MCP_TOOL_ALIASES, POOL_SWITCH_WHY, POOL_SWITCH_NEXT, SWITCH_STATES, quietSwitch, switchKey, ATOMIC_TEXT, FLOAT_ID, ANSWERED_EXIT_RETRY_MS, ANSWERED_EXIT_UNCONFIRMED_MS, ANSWERED_EXIT_RETRY_WINDOW_MS, ANSWERED_EXIT_CLOSED, switchAmount, switchEta, switchRows, OWNER_CAP_CODES, JOIN_END_MCP, JOIN_END_TERMINAL_LIBRARY, JOIN_RETRY_BACKOFF_MS, WALLET_CAP_FIX, MCP_CAP_FIX, capFix, ownerOnlyNext, mcpNext, CONFIDENTIAL_RETIRED, json3, answerResult, discoverTool, refuse12, publicOffer, FLOAT_PAID_CODES, FLOAT_PRIVATE_LEG, floatStillSettling, MONEY_ID2, toRecordId, linkKindOf, moneyId, REFUSED_CODES, refusedCodeOf, PLAIN_REASONS, plainReason, KEPT_SEND_TRIES, shownId, isSplitSend, sendPartId, PROMISED_NEXT, PUBLIC_READ_TIMEOUT_MS, RECIPIENT_CHECK_TIMEOUT_MS, withTimeout, ownKey, readFailure, OWN_KEY_TOKENS_MAX, OWN_TOKENS_GRACE_MS, tokenAmountText, elsewhereId, AGENT_ID_SCHEMA, agentIdName, minutesText2, ageWords2, DEPOSIT_SENT_STATES, depositLanded, usdcText2, walkWalletHistory, REFRESH_LEASE_WALK_MS, HOME_MARKS_SETTLED_MS2, AUTO_BACKUPS_KEPT, AUTO_BACKUP_NAME, AUTO_BACKUP_VERIFIED, FRONTED_SETTLE_MARGIN_SLOTS, BALANCE_REFRESH_WAIT_MS, BALANCE_REFRESH_GRACE_MS, BALANCE_REFRESH_LONG_MS, INBOUND_REFRESH_AGE_MS, CAP_BALANCE_WAIT_MS, CAP_BALANCE_RETRY_MS, REFRESH_RETRY_MS, FINALITY_POLL_MS, FINALITY_WAIT_MS, FINALITY_REFRESH_LIMIT_MS, POOL_WATCH_MS, POOL_WATCH_POLL_MS, EARLY_BALANCE_DELAY_MS, FINALITY_SETTLE_WINDOW_SLOTS, PUBLIC_READ_ANSWER_MS, SWITCH_WAIT_MS, UNSHIELD_TO_NO_USDC_DETAIL, UNSHIELD_TO_INVALID_NEXT, INFERENCE_MIN_MAX_TOKENS, ELICIT_TIMEOUT_MS, ELICIT_UNSHOWN_MS, elicitUnshown, POLL_SECONDS3, TRANSFER_CHANGE_READ_MS, TEMP_CLEAN_DELAY_MS, KEPT_ON_DISK, MAX_SHIELDED_BALANCE_ATOMIC, receiveGenerator, MCP_TOOL_NAMES, MCP_HIDDEN_TOOL_NAMES, setupTerminalNext, SETUP_POLL_NEXT, PRIVATE_INFERENCE_WHY, PRIVATE_INFERENCE_NEXT;
|
|
133652
133652
|
var init_tools = __esm({
|
|
133653
133653
|
"wallet/src/mcp/tools.mjs"() {
|
|
133654
133654
|
"use strict";
|
|
@@ -133976,6 +133976,7 @@ var init_tools = __esm({
|
|
|
133976
133976
|
sendPartId = (requestId) => (index) => `mp${index}-${toRecordId(requestId)}`;
|
|
133977
133977
|
PROMISED_NEXT = "Nothing was sent. Part of the shielded balance is promised to the unsent parts of a private send. Wait until that send is done (wallet_unshield with its request_id shows its parts), or stop its unsent parts with wallet_cancel and its request_id, then call wallet_unshield again with the same arguments; or send at most freeAtomic now with a NEW request_id";
|
|
133978
133978
|
PUBLIC_READ_TIMEOUT_MS = 3e4;
|
|
133979
|
+
RECIPIENT_CHECK_TIMEOUT_MS = 8e3;
|
|
133979
133980
|
withTimeout = (promise, ms) => Promise.race([
|
|
133980
133981
|
promise,
|
|
133981
133982
|
new Promise((_, reject) => {
|
|
@@ -135192,7 +135193,7 @@ var init_stdioServer = __esm({
|
|
|
135192
135193
|
SUPPORTED_PROTOCOL_VERSIONS = Object.freeze(["2025-06-18", "2025-03-26", "2024-11-05"]);
|
|
135193
135194
|
MAX_LINE_BYTES = 4 * 1024 * 1024;
|
|
135194
135195
|
POSITIVE_ATOMIC7 = /^[1-9][0-9]{0,30}$/;
|
|
135195
|
-
INSTRUCTIONS = `A self-custody Shinjuku Shield wallet on this machine; the keys and the passphrase stay in this process and no tool takes or returns them. Every tool answer starts with say: one plain sentence to tell the user; the other fields hold the exact numbers. Map the user's plain request to one tool: "what is my balance" -> wallet_balance; "add money" / "deposit" / "fund the wallet" / "move USDC in from Phantom, an exchange, or another wallet" -> wallet_add_funds (it answers a one-time
|
|
135196
|
+
INSTRUCTIONS = `A self-custody Shinjuku Shield wallet on this machine; the keys and the passphrase stay in this process and no tool takes or returns them. Every tool answer starts with say: one plain sentence to tell the user; the other fields hold the exact numbers. Map the user's plain request to one tool: "what is my balance" -> wallet_balance; "add money" / "deposit" / "fund the wallet" / "move USDC in from Phantom, an exchange, or another wallet" -> wallet_add_funds (it answers a one-time address; the money becomes private a few minutes after it arrives, at the next wallet call); "shield the USDC on this wallet's own address" -> wallet_shield (only public USDC already there); "stop" / "cancel" -> wallet_cancel with the request_id of what to stop; "pay this URL" -> x402_pay (call it directly, no preview is needed); "what does this URL cost" -> x402_preview (only when the user asks for the price); "find a paid API for X" -> x402_discover, then x402_pay on the url it found; "send 2 USDC to <address>" -> wallet_unshield. wallet_balance answers ONE balance (balanceAtomic), and x402_pay pays any x402 seller from it (through Shinjuku for a seller that cannot take a private payment: max_payment must cover the total amountAtomic, fee included; a refund comes back by itself within about 7 minutes). Fields ending in Atomic are atomic units (USDC: 1000000 = 1 USDC); tell the user amounts in USDC. The wallet does its upkeep by itself (chain reads, encrypted backups); the user never runs a CLI command for it. wallet_shield, wallet_add_funds, and wallet_unshield can run for minutes: call again with the SAME request_id as next says. Pass your own request_id to x402_pay: the same request_id never pays or moves money twice (on a code that ends in _retry_same_request, call again with it). wallet_unshield never sends to the wallet's own deposit address; a send to an address the owner did not approve ahead asks the user to confirm it in this client first. When the owner set limits, x402_pay never pays above them (one payment, and any 24 hours for this wallet across all MCP processes); with none, the balance is the only bound. Never claim a payment happened unless the answer has a transaction. Privacy: the chain does not show which wallet paid, but this MCP host and its model provider see every URL, body, price, and paid answer the agent handles. When an item of an answer's poolSwitch.items[] has tellUser true, tell the user its message once, in plain words; the wallet moves the balance by itself.`;
|
|
135196
135197
|
MCP_LOG_LEVELS = Object.freeze(["debug", "info", "notice", "warning", "error", "critical", "alert", "emergency"]);
|
|
135197
135198
|
POOL_SWITCH_LOG_LEVEL = "info";
|
|
135198
135199
|
validId = (id) => id === null || typeof id === "string" || typeof id === "number" && Number.isFinite(id);
|
|
@@ -135220,7 +135221,7 @@ var init_stdioServer = __esm({
|
|
|
135220
135221
|
MCP_CLOSE_UNREADABLE_BOUND_MS = 6e4;
|
|
135221
135222
|
MCP_CLOSE_POLL_MS = 500;
|
|
135222
135223
|
closeHistoryBusy = (server) => () => compactHistoryReadsRunning() > 0 || memoReadsAheadRunning() > 0 || server.refreshOpen?.() === true;
|
|
135223
|
-
SETUP_INSTRUCTIONS = `
|
|
135224
|
+
SETUP_INSTRUCTIONS = `This Shinjuku Shield wallet server is NOT SET UP on this machine yet: every money tool answers wallet_not_set_up. When the user wants to pay, check a balance, or add money, call shinjuku_setup: it asks the user to confirm in this client, creates the wallet here, and downloads the proof tools (minutes: call it again as its next says). At stage done the wallet tools are live in this same server. After setup: ${INSTRUCTIONS}`;
|
|
135224
135225
|
}
|
|
135225
135226
|
});
|
|
135226
135227
|
|
|
@@ -159643,7 +159644,8 @@ var PublicFundsFailure = class extends Error {
|
|
|
159643
159644
|
};
|
|
159644
159645
|
var failure = (code2, text3) => new PublicFundsFailure(`p03_funds_${code2}: ${text3}`);
|
|
159645
159646
|
var iso2 = (ms) => new Date(ms).toISOString();
|
|
159646
|
-
var
|
|
159647
|
+
var plainUsdc = (text3) => text3.includes(".") ? text3.replace(/0+$/, "").replace(/\.$/, "") : text3;
|
|
159648
|
+
var usdc5 = (atomic4, decimals = 6) => plainUsdc(formatAtomic(BigInt(atomic4), decimals));
|
|
159647
159649
|
var usdcFlag = usdcFlagText;
|
|
159648
159650
|
var planName = (fundsId) => `${FUNDS_PLAN_PREFIX2}${fundsId}`;
|
|
159649
159651
|
var lockPath = (walletFile) => `${walletFile}.add-funds.lock`;
|
|
@@ -159862,7 +159864,7 @@ function fundsView(store, plan, { now = Date.now(), running } = {}) {
|
|
|
159862
159864
|
function fundsSummary(view2) {
|
|
159863
159865
|
const privacy = `. Privacy: ${view2.privacy}`;
|
|
159864
159866
|
const status = view2.status.endsWith(privacy) ? view2.status.slice(0, -privacy.length) : view2.status;
|
|
159865
|
-
const total = view2.balance?.total ? ` (your balance now: ${view2.balance.total} USDC)` : "";
|
|
159867
|
+
const total = view2.balance?.total ? ` (your balance now: ${plainUsdc(String(view2.balance.total))} USDC)` : "";
|
|
159866
159868
|
return [
|
|
159867
159869
|
view2.ready ? `add-funds ${view2.fundsId} is ready: ${view2.amount} was added to your shielded balance${total}.` : `add-funds ${view2.fundsId} is not ready yet: ${status}.`,
|
|
159868
159870
|
`Next: ${view2.next}.`
|
|
@@ -159894,6 +159896,7 @@ function fundsStatusSummary(view2) {
|
|
|
159894
159896
|
}
|
|
159895
159897
|
var HELD = /^(shinjuku(?:-wallet)?\b.*\bfailed: |shinjuku(?:-wallet)?\b.*: waiting for funds, nothing failed \(|hint: |Help: |next: |Examples?:|Every flag: | shinjuku(?:-wallet)? )/;
|
|
159896
159898
|
var STEP_TOR_LINE = /^(?:tor|proxy): /;
|
|
159899
|
+
var DENOMINATION_WARNING = /^warning: no pool denomination is configured\b/;
|
|
159897
159900
|
async function runStep(ctx, argv2) {
|
|
159898
159901
|
if (ctx.signal.aborted) return { exit: 1, held: [], codes: [], details: {}, aborted: true };
|
|
159899
159902
|
const file = join37(ctx.tempDir, `step-${randomBytes28(8).toString("hex")}.json`);
|
|
@@ -159919,7 +159922,7 @@ async function runStep(ctx, argv2) {
|
|
|
159919
159922
|
`);
|
|
159920
159923
|
return;
|
|
159921
159924
|
}
|
|
159922
|
-
if (ctx.quiet && isProgressLine(text3)) return;
|
|
159925
|
+
if (ctx.quiet && (isProgressLine(text3) || DENOMINATION_WARNING.test(text3))) return;
|
|
159923
159926
|
if (!text3.trim() || ctx.shown.has(text3)) return;
|
|
159924
159927
|
ctx.shown.add(text3);
|
|
159925
159928
|
ctx.io.err(` ${text3}
|