shinjuku-shield 0.3.100 → 0.3.102
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 +180 -50
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.102. 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 --no-audit --no-fund shinjuku-shield@0.3.
|
|
15
|
+
npx -y --no-audit --no-fund shinjuku-shield@0.3.102 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 --no-audit --no-fund shinjuku@0.3.
|
|
27
|
+
npm install -g --no-audit --no-fund shinjuku@0.3.102
|
|
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 -- 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.102 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.102", "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": "3a9841626e4a97d756f610278b4e03f2571b556a7b06207c418a850b2b5200bf",
|
|
5
|
+
"bytes": 12797194,
|
|
6
|
+
"sourceCommit": "ca9b414196f12b2512f5457cb0160b58c8a36b25",
|
|
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-24T14:57:43.313Z"
|
|
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.102",
|
|
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": "3a984162",
|
|
7
|
+
"shinjukuSha256": "3a9841626e4a97d756f610278b4e03f2571b556a7b06207c418a850b2b5200bf",
|
|
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
|
@@ -107677,8 +107677,8 @@ var init_models = __esm({
|
|
|
107677
107677
|
"wallet/src/inference/models.mjs"() {
|
|
107678
107678
|
"use strict";
|
|
107679
107679
|
DEFAULT_MODEL = "qwen3-8-flash";
|
|
107680
|
-
DEFAULT_MODEL_PAID_WORDS = "0.
|
|
107681
|
-
DEFAULT_MAX_TOKENS =
|
|
107680
|
+
DEFAULT_MODEL_PAID_WORDS = "0.00312 USDC";
|
|
107681
|
+
DEFAULT_MAX_TOKENS = 4096;
|
|
107682
107682
|
SHORT_DEFAULT_MAX_TOKENS = 512;
|
|
107683
107683
|
FLOOR_ATOMIC = 10000n;
|
|
107684
107684
|
MIN_MAX_TOKENS = 256;
|
|
@@ -120441,7 +120441,7 @@ function paidMessage(error, code2, paid, requestId, key) {
|
|
|
120441
120441
|
const floatId = error?.floatId ?? error?.cause?.floatId;
|
|
120442
120442
|
const sellerSaid = error?.sellerReason ?? error?.cause?.sellerReason;
|
|
120443
120443
|
const reason = code2 === "p03_float_seller_kept_payment" ? `The AI provider received the payment but did not serve the request${typeof sellerSaid === "string" ? ` (${JSON.stringify(sellerSaid)})` : ""}; no refund comes. ` : typeof sellerSaid === "string" ? `The AI provider refused the payment: ${JSON.stringify(sellerSaid)}. ` : "";
|
|
120444
|
-
return `this call was paid ${usdcWords(paid)} and returned no answer${floatId ? ` (
|
|
120444
|
+
return `this call was paid ${usdcWords(paid)} and returned no answer${floatId ? ` (Shinjuku payment ${floatId})` : ""}. Do not resend it without the same Idempotency-Key: a new request pays again. ${reason}Request id ${requestId}` + (key ? `; a resend with header Idempotency-Key: ${key} returns this same result and pays nothing more. ` : ". ") + (refund && ambiguous ? "An earlier send of it may have reached the seller; if it did not, Shinjuku refunds the amount in about 7 minutes. Check shinjuku balance" : refund ? "Shinjuku refunds the amount to the wallet by itself in about 7 minutes; shinjuku balance shows it back" : "Check the wallet with shinjuku balance");
|
|
120445
120445
|
}
|
|
120446
120446
|
function unknownMessage(code2, counted, requestId, key) {
|
|
120447
120447
|
return `request ${requestId} may already have paid (${code2 ?? "the payment failed with no code"}), and its outcome is not known yet. This server counted ${usdcWords(counted)} (its limit per request) of its limit per run for it. ` + (key ? `Do not send it as a new request: resend the same body with header Idempotency-Key: ${key} to finish that same payment; it never pays twice` : "This request had no Idempotency-Key, so infer serve cannot resume that payment, and a resend pays again. Check the wallet with shinjuku balance before you send it again, and send an Idempotency-Key header with each request so a resend finishes the same payment");
|
|
@@ -132914,7 +132914,7 @@ ${canonical5}`;
|
|
|
132914
132914
|
const inferenceModule = async () => ops.inference ?? await Promise.resolve().then(() => (init_inference(), inference_exports));
|
|
132915
132915
|
const proxied = () => typeof ops.proxied === "function" ? ops.proxied() : proxyProvenAt() !== void 0;
|
|
132916
132916
|
const usd = (atomic4) => `$${formatAtomic(atomic4, 6)}`;
|
|
132917
|
-
const INFERENCE_COST_WORDS = "A qwen3-8-flash answer (the default,
|
|
132917
|
+
const INFERENCE_COST_WORDS = "A qwen3-8-flash answer (the default, 4096 tokens) paid 0.00312 USDC live: the AI provider's price plus the Shinjuku fee (0.001 USDC). The call's cap (max_payment, else the per-payment limit) must still cover the call's ceiling: max_tokens at the model's output price plus the prompt, and at least 0.01 USDC";
|
|
132918
132918
|
const paysUpToAtomic = (inference, asked) => {
|
|
132919
132919
|
try {
|
|
132920
132920
|
const extra = inference.listModels().find((model) => model.id === asked.model).priceOutPerMAtomic * 100n;
|
|
@@ -133013,7 +133013,7 @@ ${canonical5}`;
|
|
|
133013
133013
|
const inferenceChat2 = {
|
|
133014
133014
|
name: "inference_chat",
|
|
133015
133015
|
title: "Ask an AI model, paid privately",
|
|
133016
|
-
description: `Use this when the user wants an AI model's answer paid from the PRIVATE balance: it calls the AI provider's x402 chat endpoint (the AI provider picks the model's provider) and pays it privately (the chain does not show which wallet paid); use this tool, not x402_pay, for AI answers. Only prompt (or messages) is needed: model defaults to qwen3-8-flash and max_tokens to
|
|
133016
|
+
description: `Use this when the user wants an AI model's answer paid from the PRIVATE balance: it calls the AI provider's x402 chat endpoint (the AI provider picks the model's provider) and pays it privately (the chain does not show which wallet paid); use this tool, not x402_pay, for AI answers. Only prompt (or messages) is needed: model defaults to qwen3-8-flash and max_tokens to 4096 (512 for claude-opus-5). Called with neither prompt nor messages, it lists the models and their prices and pays nothing (for example qwen3-8-flash, deepseek-v4-1-flash, claude-opus-5). COST: a qwen3-8-flash answer at 4096 tokens paid 0.00312 USDC live (the AI provider's price plus the Shinjuku fee 0.001 USDC). The call's cap (max_payment, in USDC like "0.05", or max_payment_atomic; else the per-payment limit) must still cover the call's ceiling: max_tokens of output plus the prompt at the model's prices, and at least 0.01 USDC (the AI provider's floor for its standard offer). The total paid is never above the cap, and the cap is only a limit: a larger cap never pays more. What max_tokens does not use is NOT refunded when the answer is shorter. max_tokens must be at least ${INFERENCE_MIN_MAX_TOKENS} (a reasoning model spends its first tokens thinking). Example: { "prompt": "Name three prime numbers" }. PRIVACY: the AI provider and the company that runs the model see the prompt and the answer; never put keys, passphrases, or secrets in it. It runs only when this wallet runs over Tor or its own proxy (else inference_tor_required, nothing paid), so they never see this machine's IP. The same caps as x402_pay apply (max_payment can only lower the per-payment limit). When the call can cost more than that limit and the MCP client can ask the user, the wallet asks the user once to allow this one call; else the answer says the cost and the limit. On an error code that ends in _retry_same_request, call inference_chat again with the SAME request_id and arguments: it never pays twice. No streaming.`,
|
|
133017
133017
|
inputSchema: {
|
|
133018
133018
|
type: "object",
|
|
133019
133019
|
properties: {
|
|
@@ -133025,7 +133025,7 @@ ${canonical5}`;
|
|
|
133025
133025
|
additionalProperties: false
|
|
133026
133026
|
}, description: "The conversation, oldest first. Or pass prompt instead." },
|
|
133027
133027
|
prompt: { type: "string", description: "One user message (instead of messages)." },
|
|
133028
|
-
max_tokens: { type: "integer", minimum: 1, description: `Optional, default
|
|
133028
|
+
max_tokens: { type: "integer", minimum: 1, description: `Optional, default 4096 (512 for claude-opus-5), at least ${INFERENCE_MIN_MAX_TOKENS}. The most output tokens; the call pays for all of them up front. A reasoning model spends its first tokens thinking, so fewer can end with no answer.` },
|
|
133029
133029
|
temperature: { type: "number", minimum: 0, maximum: 2, description: "Sampling temperature; leave it out for the model's default." },
|
|
133030
133030
|
max_payment: { type: "string", description: 'Optional: the most this call may pay, in USDC, like "0.05"; at most the spending limit.' },
|
|
133031
133031
|
max_payment_atomic: { type: "string", pattern: "^[1-9][0-9]*$", description: "The most this call may pay, in atomic units; at most the spending limit." },
|
|
@@ -133048,7 +133048,7 @@ ${canonical5}`;
|
|
|
133048
133048
|
...body,
|
|
133049
133049
|
paid: false,
|
|
133050
133050
|
detail: "no prompt or messages were given, so nothing was sent or paid; these are the models and prices",
|
|
133051
|
-
next: body.ready ? "call inference_chat with prompt (model defaults to qwen3-8-flash, max_tokens to
|
|
133051
|
+
next: body.ready ? "call inference_chat with prompt (model defaults to qwen3-8-flash, max_tokens to 4096)" : body.next
|
|
133052
133052
|
});
|
|
133053
133053
|
}
|
|
133054
133054
|
const model = rawArgs.model ?? DEFAULT_MODEL;
|
|
@@ -133062,7 +133062,7 @@ ${canonical5}`;
|
|
|
133062
133062
|
return refuse12(
|
|
133063
133063
|
"inference_max_tokens_too_low",
|
|
133064
133064
|
`max_tokens ${args.max_tokens} is below ${INFERENCE_MIN_MAX_TOKENS}: a reasoning model (qwen3-8-flash) spends its first tokens thinking, and with max_tokens 32 or 80 it was paid and gave no answer; nothing was paid`,
|
|
133065
|
-
`call inference_chat again with max_tokens ${INFERENCE_MIN_MAX_TOKENS} or more (512 answers a short question), or leave max_tokens out; a larger max_tokens costs little more: a qwen3-8-flash answer at
|
|
133065
|
+
`call inference_chat again with max_tokens ${INFERENCE_MIN_MAX_TOKENS} or more (512 answers a short question), or leave max_tokens out; a larger max_tokens costs little more: a qwen3-8-flash answer at 4096 tokens paid 0.00312 USDC`,
|
|
133066
133066
|
{ paid: false, maxTokens: args.max_tokens, minMaxTokens: INFERENCE_MIN_MAX_TOKENS }
|
|
133067
133067
|
);
|
|
133068
133068
|
}
|
|
@@ -136082,7 +136082,11 @@ function savedBalance(store) {
|
|
|
136082
136082
|
const report = computeBalance({ store, snapshotRead: readBalanceSnapshot(store), source: "local" });
|
|
136083
136083
|
const value = report.split?.shieldedAtomic;
|
|
136084
136084
|
if (typeof value === "string" && /^[0-9]{1,31}$/.test(value)) {
|
|
136085
|
-
return {
|
|
136085
|
+
return {
|
|
136086
|
+
atomic: BigInt(value),
|
|
136087
|
+
current: (report.status === "current" || report.status === "empty") && !report.detail?.pendingDeposits?.length,
|
|
136088
|
+
atMs: Date.parse(report.detail?.lastRefresh?.at ?? "")
|
|
136089
|
+
};
|
|
136086
136090
|
}
|
|
136087
136091
|
} catch {
|
|
136088
136092
|
}
|
|
@@ -136236,11 +136240,13 @@ async function runChat({ io, values, deps = {} }) {
|
|
|
136236
136240
|
const readBalance = () => {
|
|
136237
136241
|
let saved;
|
|
136238
136242
|
try {
|
|
136239
|
-
saved = savedBalance(session.openStore());
|
|
136243
|
+
saved = (deps.savedBalance ?? savedBalance)(session.openStore());
|
|
136240
136244
|
} catch {
|
|
136241
136245
|
saved = void 0;
|
|
136242
136246
|
}
|
|
136243
|
-
if (saved
|
|
136247
|
+
if (saved && (saved.current || lastKnown && saved.atMs > lastKnown.atMs)) {
|
|
136248
|
+
lastKnown = { atomic: saved.atomic, spentThen: state.spent, atMs: saved.atMs };
|
|
136249
|
+
}
|
|
136244
136250
|
return saved;
|
|
136245
136251
|
};
|
|
136246
136252
|
const entryOf = (id) => models.find((entry) => entry.id === id);
|
|
@@ -136457,6 +136463,11 @@ async function runChat({ io, values, deps = {} }) {
|
|
|
136457
136463
|
say6(`No AI provider serves ${turn.model} at this price right now. ${paidWords} Try another model (/model ${models.find((entry) => entry.id !== turn.model)?.id ?? DEFAULT_MODEL2}), or ${again} later.`);
|
|
136458
136464
|
} else if (NO_ANSWER_CODES.test(code2 ?? "")) {
|
|
136459
136465
|
say6(`The AI provider did not send a chat answer. ${paidWords} Wait a moment and ${again}, or try another model (/model).`);
|
|
136466
|
+
} else if (FLOAT_WAIT_WORDS[code2]) {
|
|
136467
|
+
state.pending = turn;
|
|
136468
|
+
const named = error?.retryAfterSeconds ?? error?.cause?.retryAfterSeconds;
|
|
136469
|
+
const seconds2 = Number.isFinite(named) && named > 0 ? Math.ceil(named) : FLOAT_WAIT_WORDS[code2].seconds;
|
|
136470
|
+
say6(`Nothing was paid: ${FLOAT_WAIT_WORDS[code2].what}. Ask again in about ${seconds2 >= 60 ? `${Math.round(seconds2 / 60)} minute${seconds2 >= 120 ? "s" : ""}` : `${seconds2} seconds`} (or /retry).`);
|
|
136460
136471
|
} else if (WAIT_CODES.test(code2 ?? "")) {
|
|
136461
136472
|
say6(`The payment did not finish yet (the wallet or the network is busy). ${paidWords} Wait a moment, then ${again}.`);
|
|
136462
136473
|
} else {
|
|
@@ -136481,8 +136492,13 @@ async function runChat({ io, values, deps = {} }) {
|
|
|
136481
136492
|
say6(`Your private balance is ${usdcWords(saved.atomic)}.`);
|
|
136482
136493
|
} else if (lastKnown) {
|
|
136483
136494
|
const since = state.spent - lastKnown.spentThen;
|
|
136484
|
-
|
|
136485
|
-
|
|
136495
|
+
if (since === 0n) {
|
|
136496
|
+
say6(`Your private balance is about ${usdcWords(lastKnown.atomic)} at its last read. ${again}`);
|
|
136497
|
+
} else if (since > lastKnown.atomic) {
|
|
136498
|
+
say6(`This chat paid ${usdcWords(since)} since the last read of your private balance (${usdcWords(lastKnown.atomic)}), so a deposit came in since then. ${commandLine("balance")} in another terminal reads the balance again.`);
|
|
136499
|
+
} else {
|
|
136500
|
+
say6(`Your private balance is about ${usdcWords(lastKnown.atomic - since)}: ${usdcWords(lastKnown.atomic)} at its last read, less the ${usdcWords(since)} this chat paid since then. ${again}`);
|
|
136501
|
+
}
|
|
136486
136502
|
} else if (saved) {
|
|
136487
136503
|
say6(`Your private balance was ${usdcWords(saved.atomic)} at its last read; this chat paid ${usdcWords(state.spent)} since it started. ${again}`);
|
|
136488
136504
|
} else {
|
|
@@ -136537,7 +136553,7 @@ async function runChat({ io, values, deps = {} }) {
|
|
|
136537
136553
|
await session.close();
|
|
136538
136554
|
}
|
|
136539
136555
|
}
|
|
136540
|
-
var DEFAULT_MODEL2, CHAT_DEFAULT_MODEL, CHAT_MAX_TOKENS, CHAT_SHORT_TOKENS, DEFAULT_ANSWER_CAP_ATOMIC, DEFAULT_CHAT_CAP_ATOMIC, CHEAPEST_MODEL, STILL_WAITING_MS, providerKept, higherCap, POSITIVE_ATOMIC9, SHINJUKU_FEE_ATOMIC, SHORT_QUESTION_TOKENS, PASTE_JOIN_MS, INSUFFICIENT2, CAP_CODES, WAIT_CODES, NO_ANSWER_CODES, NOTHING_PAID, CAP_FROM, PROGRESS_LINE, SHOWN_PROGRESS, SELF_PAY_LINE, isProgressLine, fail46, nothingPaid;
|
|
136556
|
+
var DEFAULT_MODEL2, CHAT_DEFAULT_MODEL, CHAT_MAX_TOKENS, CHAT_SHORT_TOKENS, DEFAULT_ANSWER_CAP_ATOMIC, DEFAULT_CHAT_CAP_ATOMIC, CHEAPEST_MODEL, STILL_WAITING_MS, providerKept, higherCap, POSITIVE_ATOMIC9, SHINJUKU_FEE_ATOMIC, SHORT_QUESTION_TOKENS, PASTE_JOIN_MS, INSUFFICIENT2, CAP_CODES, WAIT_CODES, NO_ANSWER_CODES, FLOAT_WAIT_WORDS, NOTHING_PAID, CAP_FROM, PROGRESS_LINE, SHOWN_PROGRESS, SELF_PAY_LINE, isProgressLine, fail46, nothingPaid;
|
|
136541
136557
|
var init_chat = __esm({
|
|
136542
136558
|
"wallet/src/inference/chat.mjs"() {
|
|
136543
136559
|
"use strict";
|
|
@@ -136554,7 +136570,7 @@ var init_chat = __esm({
|
|
|
136554
136570
|
init_models();
|
|
136555
136571
|
DEFAULT_MODEL2 = DEFAULT_MODEL;
|
|
136556
136572
|
CHAT_DEFAULT_MODEL = DEFAULT_MODEL;
|
|
136557
|
-
CHAT_MAX_TOKENS =
|
|
136573
|
+
CHAT_MAX_TOKENS = DEFAULT_MAX_TOKENS;
|
|
136558
136574
|
CHAT_SHORT_TOKENS = 512;
|
|
136559
136575
|
DEFAULT_ANSWER_CAP_ATOMIC = 50000n;
|
|
136560
136576
|
DEFAULT_CHAT_CAP_ATOMIC = 1000000n;
|
|
@@ -136570,6 +136586,11 @@ var init_chat = __esm({
|
|
|
136570
136586
|
CAP_CODES = /^(spend_payment_cap_exceeded|mcp_session_cap_exceeded|mcp_cap_argument_above_launch_cap|p03_float_over_maximum)$/;
|
|
136571
136587
|
WAIT_CODES = /_retry_same_request$|_retry_same_payment$|_retry_later$|^wallet_locked$|another_request_unresolved$/;
|
|
136572
136588
|
NO_ANSWER_CODES = /^inference_(upstream_failed|response_invalid)$/;
|
|
136589
|
+
FLOAT_WAIT_WORDS = Object.freeze({
|
|
136590
|
+
p03_float_not_ready_retry_later: { what: "Shinjuku's payment service is not ready right now", seconds: 60 },
|
|
136591
|
+
p03_float_busy_retry_later: { what: "Shinjuku's payment service is busy right now", seconds: 30 },
|
|
136592
|
+
p03_float_payment_in_flight_retry_later: { what: "an earlier quote for this answer is still open at Shinjuku", seconds: 60 }
|
|
136593
|
+
});
|
|
136573
136594
|
NOTHING_PAID = /\bnothing was (?:sent or )?paid\b|\bnothing was paid or signed\b/i;
|
|
136574
136595
|
CAP_FROM = { line: "from this command line", setup: "set in setup", default: "the default" };
|
|
136575
136596
|
PROGRESS_LINE = /^(?:tor|rpc|history|memo service): |^reading \d+ memos? from the memo service|^reading your private balance again\b|^getting your balance ready: moving \S+ USDC of one deposit\b/;
|
|
@@ -160889,12 +160910,13 @@ function fundsView(store, plan, { now = Date.now(), running } = {}) {
|
|
|
160889
160910
|
view2.status += `. Privacy: ${view2.privacy}`;
|
|
160890
160911
|
return view2;
|
|
160891
160912
|
}
|
|
160892
|
-
function fundsSummary(view2) {
|
|
160913
|
+
function fundsSummary(view2, { named = false } = {}) {
|
|
160893
160914
|
const privacy = `. Privacy: ${view2.privacy}`;
|
|
160894
160915
|
const status = view2.status.endsWith(privacy) ? view2.status.slice(0, -privacy.length) : view2.status;
|
|
160895
160916
|
const total = view2.balance?.total ? ` (your balance now: ${plainUsdc(String(view2.balance.total))} USDC)` : "";
|
|
160917
|
+
const run5 = named ? `add-funds ${view2.fundsId}` : "add-funds";
|
|
160896
160918
|
return [
|
|
160897
|
-
view2.ready ?
|
|
160919
|
+
view2.ready ? `${run5} is ready: ${view2.amount} was added to your private balance${total}.` : `${run5} is not ready yet: ${status}.`,
|
|
160898
160920
|
// 0.3.97 T6: a next step that ends with a command line gets no "." after it. A block of lines starts on its own line.
|
|
160899
160921
|
// S3 (mcp56, published 0.3.99): inside setup, setup's own Next line follows, so this one is not printed.
|
|
160900
160922
|
...view2.next === SETUP_LINES_BELOW ? [] : [`Next:${view2.next.startsWith("\n") ? "" : " "}${sentence(view2.next)}`]
|
|
@@ -160910,7 +160932,7 @@ function printEnd(deps, view2, terminal) {
|
|
|
160910
160932
|
`);
|
|
160911
160933
|
}
|
|
160912
160934
|
function fundsStatusSummary(view2) {
|
|
160913
|
-
const [first, ...next] = fundsSummary(view2).split("\n");
|
|
160935
|
+
const [first, ...next] = fundsSummary(view2, { named: true }).split("\n");
|
|
160914
160936
|
const said = view2.stages?.find((entry) => entry.said?.length)?.said ?? [];
|
|
160915
160937
|
const rests = view2.leftoverAtOneTimeAddresses ?? (view2.leftoverAtOneTimeAddress ? [view2.leftoverAtOneTimeAddress] : []);
|
|
160916
160938
|
return [
|
|
@@ -161703,9 +161725,16 @@ async function addFunds(values, deps) {
|
|
|
161703
161725
|
plan.status = { ...plan.status ?? { stage: currentStage(store, plan) }, ended: iso2(deps.now()) };
|
|
161704
161726
|
save2();
|
|
161705
161727
|
const view2 = fundsView(store, plan, { now: deps.now(), running: false });
|
|
161706
|
-
|
|
161728
|
+
if (ctx.quiet) {
|
|
161729
|
+
const waits = view2.stages.find((entry) => entry.stage === view2.stage)?.waitsFor;
|
|
161730
|
+
io.err(`add-funds stopped: nothing is lost.${waits ? ` It was waiting for ${waits}.` : ""} To continue, run:
|
|
161731
|
+
${commandLine("add-funds")}
|
|
161707
161732
|
`);
|
|
161708
|
-
|
|
161733
|
+
} else {
|
|
161734
|
+
io.err(`add-funds ${plan.fundsId} stopped at ${view2.stage}: nothing is lost. Run the same command again to continue.
|
|
161735
|
+
`);
|
|
161736
|
+
printEnd(deps, view2, ctx.terminal);
|
|
161737
|
+
}
|
|
161709
161738
|
} finally {
|
|
161710
161739
|
process.off("SIGINT", onSignal);
|
|
161711
161740
|
process.off("SIGTERM", onSignal);
|
|
@@ -162164,6 +162193,18 @@ var UsageError = class extends Error {
|
|
|
162164
162193
|
};
|
|
162165
162194
|
var PublicFailure = class extends Error {
|
|
162166
162195
|
};
|
|
162196
|
+
var AnswerDeclined = class extends PublicFailure {
|
|
162197
|
+
constructor(code2, plain) {
|
|
162198
|
+
super(`${code2}: ${plain}`);
|
|
162199
|
+
this.plain = plain;
|
|
162200
|
+
}
|
|
162201
|
+
};
|
|
162202
|
+
var QuestionCancelled = class extends PublicFailure {
|
|
162203
|
+
// Every terminal question comes before a payment or a send, so this is true at each one.
|
|
162204
|
+
constructor(interrupted) {
|
|
162205
|
+
super(`stopped: ${interrupted ? "you pressed Ctrl-C at a question" : "the input ended before an answer to the question"}, so the command stopped there; nothing was sent or paid. Run the same command again when you are ready.`);
|
|
162206
|
+
}
|
|
162207
|
+
};
|
|
162167
162208
|
var NOT_SET_UP_CODE = "wallet_not_set_up";
|
|
162168
162209
|
var flag2 = (name, value, about, options = {}) => ({ name, value, about, ...options });
|
|
162169
162210
|
var bool2 = (name, about, options = {}) => ({ name, boolean: true, about, ...options });
|
|
@@ -162524,7 +162565,7 @@ ${CURL_USEPOD_NEXT}`, { cause: error });
|
|
|
162524
162565
|
if (response) return curlOutput(response, values, deps, probeId);
|
|
162525
162566
|
const answer = String(await deps.ask(`Pay ${usdcText3(priceAtomic)} USDC for ${values.get("--url")}? [y/N] `)).trim();
|
|
162526
162567
|
if (!/^y(es)?$/i.test(answer)) {
|
|
162527
|
-
throw new
|
|
162568
|
+
throw new AnswerDeclined("curl_payment_declined", "you did not answer y, so nothing was paid. To pay, run the same command again and answer y");
|
|
162528
162569
|
}
|
|
162529
162570
|
values.set("--max-payment", priceAtomic);
|
|
162530
162571
|
return runCurlPaid(values, deps, { requestId });
|
|
@@ -162603,6 +162644,20 @@ var INFER_COST_LINE = "the AI provider charges its quoted cap for --max-tokens a
|
|
|
162603
162644
|
var INFER_STDIN_MAX_BYTES = 1024 * 1024;
|
|
162604
162645
|
var INFER_STDIN_EXAMPLE = `echo "Summarize x402 in one line" | ${CLI_WORD} infer - --model qwen3-8-flash`;
|
|
162605
162646
|
var CURL_USEPOD_NEXT = `use \`${CLI_WORD} infer\` for the AI provider: it sends the prompt only through --tor or --proxy`;
|
|
162647
|
+
function unshieldArgs(command2, args) {
|
|
162648
|
+
if (args.includes("--amount")) return args;
|
|
162649
|
+
const known = new Map(command2.flags.map((entry) => [entry.name, entry]));
|
|
162650
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
162651
|
+
const token = args[index];
|
|
162652
|
+
if (token.startsWith("--")) {
|
|
162653
|
+
if (known.has(token) && !known.get(token).boolean) index += 1;
|
|
162654
|
+
continue;
|
|
162655
|
+
}
|
|
162656
|
+
if (!/^(all|[0-9]+(\.[0-9]+)?)$/i.test(token)) return args;
|
|
162657
|
+
return ["--amount", /^all$/i.test(token) ? "all" : token, ...args.slice(0, index), ...args.slice(index + 1)];
|
|
162658
|
+
}
|
|
162659
|
+
return args;
|
|
162660
|
+
}
|
|
162606
162661
|
function inferArgs(command2, args) {
|
|
162607
162662
|
const known = new Map(command2.flags.map((entry) => [entry.name, entry]));
|
|
162608
162663
|
const out = [];
|
|
@@ -163649,10 +163704,10 @@ function agentAppLines({ home, deps, npmVersion, skip = /* @__PURE__ */ new Set(
|
|
|
163649
163704
|
}
|
|
163650
163705
|
return lines.join("\n");
|
|
163651
163706
|
}
|
|
163652
|
-
function setupNextText({ home, deps, npmVersion, config, fundAsked, rerun,
|
|
163707
|
+
function setupNextText({ home, deps, npmVersion, config, fundAsked, rerun, targets = [], added = /* @__PURE__ */ new Set() }) {
|
|
163653
163708
|
const parts = [];
|
|
163654
163709
|
if (!fundAsked && !rerun) parts.push(fundingStepText());
|
|
163655
|
-
|
|
163710
|
+
parts.push(privateInferencePath(config));
|
|
163656
163711
|
if (targets.some((target) => !added.has(target))) {
|
|
163657
163712
|
const byHand = hostConfigText({ home, env: deps.env, platform: deps.platform ?? process.platform, npmVersion, skip: added });
|
|
163658
163713
|
if (byHand) parts.push(`Or add it by hand:
|
|
@@ -163660,8 +163715,7 @@ ${byHand}
|
|
|
163660
163715
|
`);
|
|
163661
163716
|
} else if (rerun && !targets.length) {
|
|
163662
163717
|
parts.push([
|
|
163663
|
-
"
|
|
163664
|
-
"To add the wallet to another agent app, run one of these:",
|
|
163718
|
+
"To add the wallet to an agent app, run one of these:",
|
|
163665
163719
|
...HOST_TARGETS.map((target) => ` ${cli2()} setup --add-to ${target}`),
|
|
163666
163720
|
""
|
|
163667
163721
|
].join("\n"));
|
|
@@ -163701,10 +163755,21 @@ function recordOwnAddress(home, address5, deps) {
|
|
|
163701
163755
|
return [` note your own address was not saved: ${why}`];
|
|
163702
163756
|
}
|
|
163703
163757
|
}
|
|
163704
|
-
async function offerFundNow(deps, { tor }) {
|
|
163758
|
+
async function offerFundNow(deps, { tor, created }) {
|
|
163759
|
+
const io = deps.io;
|
|
163760
|
+
try {
|
|
163761
|
+
await askFundNow(deps, { tor, created });
|
|
163762
|
+
} catch (error) {
|
|
163763
|
+
if (!(error instanceof QuestionCancelled)) throw error;
|
|
163764
|
+
io.out(`Setup is done; no money was added. To add money later, ask your agent to add funds, or run:
|
|
163765
|
+
${FUND_COMMAND}
|
|
163766
|
+
`);
|
|
163767
|
+
}
|
|
163768
|
+
}
|
|
163769
|
+
async function askFundNow(deps, { tor, created }) {
|
|
163705
163770
|
const io = deps.io;
|
|
163706
163771
|
for (let attempt = 0; attempt < 3; attempt += 1) {
|
|
163707
|
-
const answer = String(await deps.ask(attempt === 0 ? "The wallet starts empty. Add money now? Amount in USDC, from 0.01 (press Enter to skip): " : "Add money now? Amount in USDC, from 0.01 (press Enter to skip): ")).trim();
|
|
163772
|
+
const answer = String(await deps.ask(attempt === 0 && created ? "The wallet starts empty. Add money now? Amount in USDC, from 0.01 (press Enter to skip): " : "Add money now? Amount in USDC, from 0.01 (press Enter to skip): ")).trim();
|
|
163708
163773
|
if (!answer || /^(n|no|skip)$/i.test(answer)) break;
|
|
163709
163774
|
const atomic4 = usdcToAtomic(answer);
|
|
163710
163775
|
if (!atomic4 || BigInt(atomic4) < PAY_ME_MIN_ATOMIC) {
|
|
@@ -164136,7 +164201,7 @@ async function runSetupCommand(values, deps) {
|
|
|
164136
164201
|
|
|
164137
164202
|
`);
|
|
164138
164203
|
const config2 = setupConfigOf(home);
|
|
164139
|
-
await offerFundNow(deps, { tor: config2?.tor === true });
|
|
164204
|
+
await offerFundNow(deps, { tor: config2?.tor === true, created: !old });
|
|
164140
164205
|
const targets2 = values.get("--add-to") ?? [];
|
|
164141
164206
|
io.out(setupNextText({
|
|
164142
164207
|
home,
|
|
@@ -164145,7 +164210,6 @@ async function runSetupCommand(values, deps) {
|
|
|
164145
164210
|
config: config2,
|
|
164146
164211
|
fundAsked: true,
|
|
164147
164212
|
rerun: values.get(SETUP_RERUN) === "settings",
|
|
164148
|
-
inferenceNow: privateInference === true && (!old || old.inference?.enabled !== true),
|
|
164149
164213
|
targets: targets2,
|
|
164150
164214
|
added: new Set(targets2)
|
|
164151
164215
|
}));
|
|
@@ -164206,15 +164270,14 @@ Copy it to two offline places now; it is the only way to restore this wallet.
|
|
|
164206
164270
|
const targets = values.get("--add-to") ?? [];
|
|
164207
164271
|
const added = targets.length ? addToHosts(targets, home, deps, { force: values.has("--force"), npmVersion }) : /* @__PURE__ */ new Set();
|
|
164208
164272
|
const config = setupConfigOf(home);
|
|
164209
|
-
const inferenceNow = summary.privateInference === true && (!rerun || old?.inference?.enabled !== true);
|
|
164210
164273
|
if (inProxiedRun(deps.env) && deps.env[SETUP_NEXT_BY_PARENT_ENV] === "1") {
|
|
164211
164274
|
if (targets.some((target) => !added.has(target))) {
|
|
164212
|
-
io.out(setupNextText({ home, deps, npmVersion, config, fundAsked: true, rerun: true,
|
|
164275
|
+
io.out(setupNextText({ home, deps, npmVersion, config, fundAsked: true, rerun: true, targets, added }));
|
|
164213
164276
|
}
|
|
164214
164277
|
return void 0;
|
|
164215
164278
|
}
|
|
164216
|
-
if (interactive) await offerFundNow(deps, { tor: config?.tor === true });
|
|
164217
|
-
io.out(setupNextText({ home, deps, npmVersion, config, fundAsked: interactive, rerun,
|
|
164279
|
+
if (interactive) await offerFundNow(deps, { tor: config?.tor === true, created: !old });
|
|
164280
|
+
io.out(setupNextText({ home, deps, npmVersion, config, fundAsked: interactive, rerun, targets, added }));
|
|
164218
164281
|
}
|
|
164219
164282
|
async function confirmAboveBalanceCap(deps, atomic4) {
|
|
164220
164283
|
if (BigInt(atomic4) <= MAX_SHIELDED_BALANCE_ATOMIC) return true;
|
|
@@ -164240,7 +164303,7 @@ async function fillAddFunds(values, deps) {
|
|
|
164240
164303
|
const kept2 = /^[1-9][0-9]{0,19}$/.test(String(plan?.amountAtomic ?? "")) ? plan.amountAtomic : void 0;
|
|
164241
164304
|
if (!plan && !values.has("--route")) values.set("--route", "exchange");
|
|
164242
164305
|
if (!values.has("--amount")) {
|
|
164243
|
-
if (kept2) deps.io.err(`This continues
|
|
164306
|
+
if (kept2) deps.io.err(`This continues the add-funds run of ${usdcText3(kept2)} USDC that is not ready yet.
|
|
164244
164307
|
`);
|
|
164245
164308
|
if (!kept2 && !terminal) {
|
|
164246
164309
|
throw new UsageError("add-funds needs the amount of USDC (--amount, from 0.01) when it runs without a terminal; in a terminal it asks", command2);
|
|
@@ -164859,6 +164922,8 @@ var COMMANDS = [
|
|
|
164859
164922
|
flag2("--data-file", "<file>", "the request body from a file (POST)"),
|
|
164860
164923
|
flag2("--out", "<file>", "-o: write the answer to this private file (mode 600) instead of stdout"),
|
|
164861
164924
|
bool2("--include", "-i: print the HTTP status line and headers before the body (a paid answer has status 200 and the x-shinjuku-payment receipt header)"),
|
|
164925
|
+
// CU1 (mcp56, published 0.3.101): a terminal curl printed the 4-line "history: ..." paragraph before the pay question.
|
|
164926
|
+
bool2("--verbose", "in a terminal, also show the wallet's own progress lines (Tor, the RPC relay, the pool history, the memo reads); without it a terminal shows only the price question, the answer, and what it paid"),
|
|
164862
164927
|
flag2("--request-id", "<id>", "your stable name for this request; default curl-<random>, printed on stderr before any payment. Rerun with the same id to resume a stopped run: it never pays twice"),
|
|
164863
164928
|
...payerSessionFlags()
|
|
164864
164929
|
],
|
|
@@ -164881,6 +164946,7 @@ var COMMANDS = [
|
|
|
164881
164946
|
nextInOutput: true,
|
|
164882
164947
|
normalizeArgs: curlArgs,
|
|
164883
164948
|
validate: validateCurl,
|
|
164949
|
+
quietProgress: (values, deps) => terminalQuiet(values, deps),
|
|
164884
164950
|
run: (args, values, deps, io) => deps.curlMain(values, { ...deps, io })
|
|
164885
164951
|
},
|
|
164886
164952
|
{
|
|
@@ -164890,7 +164956,7 @@ var COMMANDS = [
|
|
|
164890
164956
|
flags: [
|
|
164891
164957
|
flag2("--prompt", "<text>", 'what to ask; write - to read it from stdin (the private form), or write it alone, in quotes (shinjuku infer "Summarize x402 in one line" ...)', { required: true }),
|
|
164892
164958
|
flag2("--model", "<id>", `the model (default ${DEFAULT_MODEL2}): ${INFER_MODEL_IDS.join(", ")} (${CLI_WORD} infer models lists their prices)`),
|
|
164893
|
-
flag2("--max-tokens", "<n>", "the longest answer to pay for, in tokens; default
|
|
164959
|
+
flag2("--max-tokens", "<n>", "the longest answer to pay for, in tokens; default 4096, 512 for claude-opus-5 (give 256 or more; 512 answers a short question: a reasoning model like qwen3-8-flash thinks first, and with fewer tokens it can stop before it answers, still paid); it sets the most this request can cost", { check: "count" }),
|
|
164894
164960
|
flag2("--max-payment", "<usdc>", `the most this request may pay in all, in USDC (0.02 = 2 cents). It must be at least 0.01: the wallet never sets a call's ceiling below the AI provider's 0.01 USDC floor on its standard offer, and a call on that offer also pays Shinjuku's fee, so 0.02 covers it. What a call pays is the AI provider's quote for --max-tokens plus Shinjuku's fee: a ${DEFAULT_MODEL2} answer (the default, ${DEFAULT_MAX_TOKENS} tokens) paid ${DEFAULT_MODEL_PAID_WORDS} live (the AI provider's price plus the 0.001 USDC fee) on the offer the wallet pays, 0.01 USDC plus the fee when the AI provider offers only its standard payment. A higher ceiling is refused before anything is paid. Default: the cap setup recorded, else 0.05`, { check: "atomic", usdc: true }),
|
|
164895
164961
|
flag2("--max-session", "<usdc>", "the most this run may pay in total, in USDC; at least --max-payment. Default: the cap setup recorded, else 1", { check: "atomic", usdc: true }),
|
|
164896
164962
|
flag2("--request-id", "<id>", "your stable name for this request; default infer-<random>, printed on stderr before any payment. Rerun with the same id to resume a stopped run: it never pays twice"),
|
|
@@ -165149,8 +165215,10 @@ var COMMANDS = [
|
|
|
165149
165215
|
next: SETUP_NEXT,
|
|
165150
165216
|
// Printed as "Next: ..." after a run (the runner's label), as the help page prints it.
|
|
165151
165217
|
nextLabel: "Next",
|
|
165152
|
-
// A rerun of a complete setup (SETUP_RERUN):
|
|
165153
|
-
nextAfterRun: (values) => values.get(SETUP_RERUN) === "settings" ?
|
|
165218
|
+
// A rerun of a complete setup (SETUP_RERUN): it cannot tell whether an agent app has the entry (0.3.101 live pass).
|
|
165219
|
+
nextAfterRun: (values) => values.get(SETUP_RERUN) === "settings" ? `chat privately with an AI in this terminal:
|
|
165220
|
+
${CLI_WORD} chat
|
|
165221
|
+
If an agent app already runs the wallet, close and open it so it reads these settings.` : values.get(SETUP_RERUN) === "own-address" ? "ask your agent to send money to your own address: it sends without asking you each time." : SETUP_NEXT,
|
|
165154
165222
|
// In a terminal its progress lines (tor:, rpc:, history:) show only with --verbose; Tor trouble shows in plain words
|
|
165155
165223
|
// (inference/chat.mjs hideProgressLines). Live run 2026-10-24 08:26 UTC (npm 0.3.97, laptop, Tor on): setup printed
|
|
165156
165224
|
// the raw onion line "tor: the onion ... gave no answer (the stream failed); its requests move to ...". The Tor run's
|
|
@@ -165252,6 +165320,7 @@ var COMMANDS = [
|
|
|
165252
165320
|
name: "unshield",
|
|
165253
165321
|
summary: "Send some or all of your private balance to a Solana wallet address, privately.",
|
|
165254
165322
|
env: [],
|
|
165323
|
+
normalizeArgs: unshieldArgs,
|
|
165255
165324
|
flags: [
|
|
165256
165325
|
// 0.3.97, live proof 2026-10-24: --amount and --to are optional in a terminal (unshield asks both, then a y);
|
|
165257
165326
|
// a script, a pipe, or an agent's tool must give both (askUnshield).
|
|
@@ -165902,7 +165971,8 @@ function parseFlags(command2, args) {
|
|
|
165902
165971
|
for (let index = 0; index < args.length; index += 1) {
|
|
165903
165972
|
const token = args[index];
|
|
165904
165973
|
if (!token.startsWith("--")) {
|
|
165905
|
-
|
|
165974
|
+
const example = known.has("--amount") ? "--amount 0.5" : `--pool ${GUIDE.pool}`;
|
|
165975
|
+
throw new UsageError(`unexpected argument ${index + 1} (it has no flag in front of it): every value follows its flag, like ${example}`, command2);
|
|
165906
165976
|
}
|
|
165907
165977
|
if (token.includes("=")) {
|
|
165908
165978
|
const spec2 = known.get(token.slice(0, token.indexOf("=")));
|
|
@@ -166155,7 +166225,7 @@ async function askUnshield(args, values, deps) {
|
|
|
166155
166225
|
deps.io.err(`${why}
|
|
166156
166226
|
`);
|
|
166157
166227
|
}
|
|
166158
|
-
throw new
|
|
166228
|
+
throw new AnswerDeclined("unshield_declined", `three answers were not usable, so nothing was sent. To send, run:
|
|
166159
166229
|
${cli2()} unshield`);
|
|
166160
166230
|
};
|
|
166161
166231
|
const out = [...args];
|
|
@@ -166182,16 +166252,31 @@ async function askUnshield(args, values, deps) {
|
|
|
166182
166252
|
}
|
|
166183
166253
|
let whole;
|
|
166184
166254
|
if (values.get("--amount") === "all") {
|
|
166255
|
+
const open4 = () => (deps.openWalletStore ?? openWalletStore)(resolve39(values.get("--wallet")), payerPassphrase(values, deps));
|
|
166256
|
+
let store;
|
|
166185
166257
|
try {
|
|
166186
|
-
|
|
166258
|
+
store = open4();
|
|
166259
|
+
whole = savedBalance(store);
|
|
166187
166260
|
} catch {
|
|
166188
166261
|
whole = void 0;
|
|
166189
166262
|
}
|
|
166263
|
+
const refreshArgs = !whole && store ? homeRefreshArgs(store, deps) : void 0;
|
|
166264
|
+
if (refreshArgs) {
|
|
166265
|
+
deps.io.err("Reading your private balance from the chain, so the question names the amount...\n");
|
|
166266
|
+
const silent = { out: () => {
|
|
166267
|
+
}, err: () => {
|
|
166268
|
+
} };
|
|
166269
|
+
try {
|
|
166270
|
+
if (await runShinjukuWallet(["balance", ...refreshArgs], { ...deps, io: silent }) === 0) whole = savedBalance(open4());
|
|
166271
|
+
} catch {
|
|
166272
|
+
whole = void 0;
|
|
166273
|
+
}
|
|
166274
|
+
}
|
|
166190
166275
|
}
|
|
166191
|
-
const wholeWords = !whole ?
|
|
166276
|
+
const wholeWords = !whole ? ` (its amount could not be read now; answer n and run ${cli2()} balance to see it)` : whole.current ? ` (${usdcOr(whole.atomic.toString())})` : ` (about ${usdcOr(whole.atomic.toString())} at its last read)`;
|
|
166192
166277
|
const what = values.get("--amount") === "all" ? `your whole private balance${wholeWords}` : `${usdcText3(values.get("--amount"))} USDC`;
|
|
166193
166278
|
const answer = String(await deps.ask(`Send ${what} to ${values.get("--to")}? [y/N] `)).trim();
|
|
166194
|
-
if (!/^y(es)?$/i.test(answer)) throw new
|
|
166279
|
+
if (!/^y(es)?$/i.test(answer)) throw new AnswerDeclined("unshield_declined", `you did not answer y, so nothing was sent. To send, run:
|
|
166195
166280
|
${cli2()} unshield`);
|
|
166196
166281
|
return out;
|
|
166197
166282
|
}
|
|
@@ -167303,7 +167388,7 @@ function failureHint(command2, reason, deps, values, floatError) {
|
|
|
167303
167388
|
if (/inference_tor_required/.test(reason)) return "rerun the same command with --tor added (or --proxy <http://host:port>); nothing was paid";
|
|
167304
167389
|
if (/inference_ceiling_over_cap/.test(reason)) return "raise --max-payment to the ceiling it names plus Shinjuku's fee, or lower --max-tokens; nothing was paid";
|
|
167305
167390
|
if (/inference_model_unknown/.test(reason)) return `pass --model with one of: ${INFER_MODEL_IDS.join(", ")} (${cli2()} infer models lists the prices)`;
|
|
167306
|
-
if (/inference_max_tokens_required/.test(reason)) return "add --max-tokens <n> (256 or more; 512 answers a short question), or leave --max-tokens out for
|
|
167391
|
+
if (/inference_max_tokens_required/.test(reason)) return "add --max-tokens <n> (256 or more; 512 answers a short question), or leave --max-tokens out for 4096 (512 for claude-opus-5): it sets the most the request can cost";
|
|
167307
167392
|
if (/mcp_session_cap_exceeded/.test(reason)) return "nothing was paid: this process reached --max-session. Restart it with a higher --max-session to pay more";
|
|
167308
167393
|
if (/mcp_cap_invalid/.test(reason)) {
|
|
167309
167394
|
return `start it with --max-session at least as high as --max-payment, for example: ${cli2()} mcp --max-payment 0.05 --max-session 0.2 ${PAYER_SESSION_BASE}`;
|
|
@@ -167627,8 +167712,8 @@ function floatFailureHint(reason, floatError) {
|
|
|
167627
167712
|
if (/p03_float_answer_invalid_refund_pending/.test(reason)) {
|
|
167628
167713
|
return "Shinjuku was paid, but its answer held no valid payment for this seller, so nothing went to the seller. Refund of the amount paid (price + fee) on the way (up to about 7 min). Nothing more to do";
|
|
167629
167714
|
}
|
|
167630
|
-
if (/p03_float_busy_retry_later/.test(reason)) return "nothing was paid: Shinjuku's
|
|
167631
|
-
if (/p03_float_not_ready_retry_later/.test(reason)) return "nothing was paid: Shinjuku's
|
|
167715
|
+
if (/p03_float_busy_retry_later/.test(reason)) return "nothing was paid: Shinjuku's payment service is busy right now. Rerun the same command in about 30 seconds";
|
|
167716
|
+
if (/p03_float_not_ready_retry_later/.test(reason)) return "nothing was paid: Shinjuku's payment service is not ready right now. Rerun the same command in about a minute";
|
|
167632
167717
|
if (/p03_float_payment_in_flight_retry_later/.test(reason)) return "nothing was paid: an earlier quote for this payment is still open at Shinjuku. Rerun the same command in about a minute";
|
|
167633
167718
|
if (/p03_float_price_above_capacity/.test(reason)) {
|
|
167634
167719
|
return `nothing was paid: the seller's price is above the largest price Shinjuku pays for one request now (largestAtomic in ${config}). Pay a cheaper seller, or try again later`;
|
|
@@ -167637,10 +167722,10 @@ function floatFailureHint(reason, floatError) {
|
|
|
167637
167722
|
return `nothing was paid: the seller's price plus the Shinjuku fee (feeAtomic in ${config}; 1000 = 0.001 USDC) is above your maximum (--maximum-atomic or --max-payment). Rerun with a maximum of at least price + fee`;
|
|
167638
167723
|
}
|
|
167639
167724
|
if (/p03_float_seller_uses_our_facilitator/.test(reason)) {
|
|
167640
|
-
return "nothing was paid: this seller's exact offer settles through Shinjuku's own pocket facilitator, which cannot take a payment from
|
|
167725
|
+
return "nothing was paid: this seller's exact offer settles through Shinjuku's own pocket facilitator, which cannot take a payment from Shinjuku's payment service. Ask the seller for its shielded-exact offer: the wallet pays that one first";
|
|
167641
167726
|
}
|
|
167642
167727
|
if (/p03_float_not_offered/.test(reason)) {
|
|
167643
|
-
return "nothing was paid: the facilitator (--memo-service) does not run
|
|
167728
|
+
return "nothing was paid: the facilitator (--memo-service) does not run Shinjuku's payment service, so a seller that takes only standard exact cannot be paid through it. Use the facilitator of this wallet's pool";
|
|
167644
167729
|
}
|
|
167645
167730
|
if (/p03_float_config_unreadable/.test(reason)) return `nothing was paid: ${config} did not answer, or its answer is not valid. Rerun the same command later`;
|
|
167646
167731
|
if (/p03_float_config_mismatch/.test(reason)) return "nothing was paid: the facilitator's float runs on another network or token than this wallet's pool. Use the facilitator of this wallet's pool";
|
|
@@ -167810,10 +167895,25 @@ function defaultDependencies() {
|
|
|
167810
167895
|
stdinIsTTY: () => Boolean(process.stdin.isTTY),
|
|
167811
167896
|
/** True when stdout is a terminal: add-funds then ends with a short summary instead of the status as JSON. */
|
|
167812
167897
|
stdoutIsTTY: () => Boolean(process.stdout.isTTY),
|
|
167813
|
-
/**
|
|
167814
|
-
|
|
167898
|
+
/**
|
|
167899
|
+
* One terminal question on stderr (stdout stays for output); the answer text. U7 (mcp56, published 0.3.100): Ctrl-C
|
|
167900
|
+
* at a question paused stdin with no answer, Node then printed "Detected unsettled top-level await" and nothing said
|
|
167901
|
+
* what happened. Ctrl-C, or an input that ends, now stops the command with QuestionCancelled (one plain line).
|
|
167902
|
+
*/
|
|
167903
|
+
ask: (question) => new Promise((resolveAnswer, rejectAnswer) => {
|
|
167815
167904
|
const prompt = createInterface2({ input: process.stdin, output: process.stderr, terminal: true });
|
|
167905
|
+
let answered2 = false;
|
|
167906
|
+
let interrupted = false;
|
|
167907
|
+
prompt.on("SIGINT", () => {
|
|
167908
|
+
interrupted = true;
|
|
167909
|
+
process.stderr.write("\n");
|
|
167910
|
+
prompt.close();
|
|
167911
|
+
});
|
|
167912
|
+
prompt.on("close", () => {
|
|
167913
|
+
if (!answered2) rejectAnswer(new QuestionCancelled(interrupted));
|
|
167914
|
+
});
|
|
167816
167915
|
prompt.question(question, (answer) => {
|
|
167916
|
+
answered2 = true;
|
|
167817
167917
|
prompt.close();
|
|
167818
167918
|
resolveAnswer(answer);
|
|
167819
167919
|
});
|
|
@@ -167897,10 +167997,28 @@ function isHelpRequest(argv2) {
|
|
|
167897
167997
|
args = rest.slice(1);
|
|
167898
167998
|
}
|
|
167899
167999
|
}
|
|
167900
|
-
|
|
168000
|
+
if (command2 === void 0) return false;
|
|
168001
|
+
if (!command2.normalizeArgs || command2.normalizeArgs === unshieldArgs) {
|
|
168002
|
+
if (strayWordIn(command2, command2.normalizeArgs ? command2.normalizeArgs(command2, args) : args)) return true;
|
|
168003
|
+
}
|
|
168004
|
+
return helpFlagIn(command2, args);
|
|
168005
|
+
}
|
|
168006
|
+
function strayWordIn(command2, args) {
|
|
168007
|
+
const known = new Map(command2.flags.map((entry) => [entry.name, entry]));
|
|
168008
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
168009
|
+
const token = args[index];
|
|
168010
|
+
if (!token.startsWith("--")) return true;
|
|
168011
|
+
const spec = known.get(token);
|
|
168012
|
+
if (!spec || token.includes("=")) return false;
|
|
168013
|
+
if (spec.boolean) continue;
|
|
168014
|
+
if (args[index + 1] === void 0 || args[index + 1].startsWith("--")) return false;
|
|
168015
|
+
index += 1;
|
|
168016
|
+
}
|
|
168017
|
+
return false;
|
|
167901
168018
|
}
|
|
167902
168019
|
async function runShinjukuWallet(argv2, overrides = {}) {
|
|
167903
168020
|
const deps = { ...defaultDependencies(), ...overrides };
|
|
168021
|
+
const endsProcess = Object.keys(overrides).length === 0;
|
|
167904
168022
|
setCommandVersionSource(() => deps.walletVersion().npm);
|
|
167905
168023
|
const rawIo = deps.io;
|
|
167906
168024
|
deps.io = { ...rawIo, out: (text3) => rawIo.out(fillCommandWords(text3)), err: (text3) => rawIo.err(fillCommandWords(text3)) };
|
|
@@ -168024,6 +168142,8 @@ This copy: ${walletVersionLine(deps.walletVersion())}
|
|
|
168024
168142
|
writeRunResult(deps, command2, 0);
|
|
168025
168143
|
return 0;
|
|
168026
168144
|
} catch (error) {
|
|
168145
|
+
if (endsProcess) showProgressAgain = () => {
|
|
168146
|
+
};
|
|
168027
168147
|
if (error instanceof RanBehindTorFailed) return error.exitCode;
|
|
168028
168148
|
if (error instanceof UsageError) {
|
|
168029
168149
|
let setUp = false;
|
|
@@ -168047,6 +168167,16 @@ This copy: ${walletVersionLine(deps.walletVersion())}
|
|
|
168047
168167
|
if (reason.startsWith(`${NOT_SET_UP_CODE}: `)) {
|
|
168048
168168
|
const plain = reason.slice(NOT_SET_UP_CODE.length + 2);
|
|
168049
168169
|
io.err(`${plain[0].toUpperCase()}${plain.slice(1)}
|
|
168170
|
+
`);
|
|
168171
|
+
return 1;
|
|
168172
|
+
}
|
|
168173
|
+
if (error instanceof QuestionCancelled) {
|
|
168174
|
+
io.err(`${CLI} ${command2.name} ${error.message}
|
|
168175
|
+
`);
|
|
168176
|
+
return 1;
|
|
168177
|
+
}
|
|
168178
|
+
if (error instanceof AnswerDeclined) {
|
|
168179
|
+
io.err(`${CLI} ${command2.name} stopped: ${error.plain}
|
|
168050
168180
|
`);
|
|
168051
168181
|
return 1;
|
|
168052
168182
|
}
|