shinjuku-shield 0.3.121 → 0.3.122
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 +41 -20
package/README.md
CHANGED
|
@@ -6,19 +6,19 @@ answers privately, in a terminal chat or for your agent app. Its `mcp`
|
|
|
6
6
|
command runs a local MCP server (stdio) for your agent. Your keys never
|
|
7
7
|
leave your machine.
|
|
8
8
|
|
|
9
|
-
This is version 0.3.
|
|
9
|
+
This is version 0.3.122. The npm packages `shinjuku-shield` and
|
|
10
10
|
`shinjuku-shielded` hold the same files. The command is `shinjuku`.
|
|
11
11
|
|
|
12
12
|
## Set up
|
|
13
13
|
|
|
14
14
|
```sh
|
|
15
|
-
npm install -g shinjuku@0.3.
|
|
15
|
+
npm install -g shinjuku@0.3.122
|
|
16
16
|
shinjuku setup
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
Type the two lines as they are. `npx install shinjuku` does not work: npx
|
|
20
20
|
reads `install` as the name of another npm package. To set up without
|
|
21
|
-
installing, type `npx shinjuku@0.3.
|
|
21
|
+
installing, type `npx shinjuku@0.3.122 setup`.
|
|
22
22
|
|
|
23
23
|
Setup makes the wallet on this machine, a private passphrase file, and the
|
|
24
24
|
checked proof tools (about 191 MB), and writes `config.json`. It also writes
|
|
@@ -36,13 +36,13 @@ Every wallet command works after `shinjuku`, for example `shinjuku balance`,
|
|
|
36
36
|
Claude Code:
|
|
37
37
|
|
|
38
38
|
```sh
|
|
39
|
-
claude mcp add --scope user shinjuku -- npx -y --no-audit --no-fund shinjuku-shield@0.3.
|
|
39
|
+
claude mcp add --scope user shinjuku -- npx -y --no-audit --no-fund shinjuku-shield@0.3.122 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.122", "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": "67cedf24617c4cd78d268b549ad4b346101b6de7338a5a3889df8f81a29c78a3",
|
|
5
|
+
"bytes": 8472739,
|
|
6
|
+
"sourceCommit": "31eb1a0d3a0f1a9d380e2b1bf046d8abcc5420cc",
|
|
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",
|
|
@@ -1037,5 +1037,5 @@
|
|
|
1037
1037
|
"version": "1.8.0"
|
|
1038
1038
|
}
|
|
1039
1039
|
],
|
|
1040
|
-
"publishedAt": "2026-10-
|
|
1040
|
+
"publishedAt": "2026-10-28T19:36:37.026Z"
|
|
1041
1041
|
}
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "shinjuku-shield",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.122",
|
|
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": "67cedf24",
|
|
7
|
+
"shinjukuSha256": "67cedf24617c4cd78d268b549ad4b346101b6de7338a5a3889df8f81a29c78a3",
|
|
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
|
@@ -127422,7 +127422,15 @@ ${canonical5}`;
|
|
|
127422
127422
|
{ requestId, paid: false, balanceEmpty: true, ...publicAtomic ? { publicAtomic } : {} }
|
|
127423
127423
|
);
|
|
127424
127424
|
}
|
|
127425
|
-
|
|
127425
|
+
async function knownZeroFresh() {
|
|
127426
|
+
if (knownZeroBalance({ maxAgeMs: INBOUND_REFRESH_AGE_MS }).empty) return true;
|
|
127427
|
+
if (!knownZeroBalance().empty || refreshFailedAt && Date.now() - refreshFailedAt < REFRESH_RETRY_MS) return false;
|
|
127428
|
+
const outcome = await Promise.race([refreshShared().then(() => "done", () => "failed"), sleep2(balanceRefreshWaitMs).then(() => "waiting")]);
|
|
127429
|
+
return outcome === "done" && knownZeroBalance({ maxAgeMs: INBOUND_REFRESH_AGE_MS }).empty;
|
|
127430
|
+
}
|
|
127431
|
+
const zeroBeforeAsk = async (tool, requestId) => await knownZeroFresh() ? zeroBalanceStop({ tool, requestId, same: tool === "x402_pay" ? "the same url, method, headers, and body" : "the same arguments" }) : void 0;
|
|
127432
|
+
const floatSplitOf = (error) => ATOMIC_TEXT.test(String(error?.priceAtomic ?? "")) && ATOMIC_TEXT.test(String(error?.feeAtomic ?? "")) ? { priceAtomic: String(error.priceAtomic), feeAtomic: String(error.feeAtomic) } : void 0;
|
|
127433
|
+
const splitWords = (split4, price) => split4 ? ` (${price} ${usdcText3(split4.priceAtomic)} USDC plus Shinjuku's fee ${usdcText3(split4.feeAtomic)} USDC)` : "";
|
|
127426
127434
|
async function askLimit2({ requestId, url, numbers, calledAt, message }) {
|
|
127427
127435
|
const answer = await confirmOnce({ message, waitMs: budgetLeft(calledAt) });
|
|
127428
127436
|
if (!answer.ok) {
|
|
@@ -127485,7 +127493,7 @@ ${canonical5}`;
|
|
|
127485
127493
|
async function payCall({ target, request, argument: argument2, requestId, given, calledAt, progress: progress3, canProgress, signal }) {
|
|
127486
127494
|
let cap = policy.resolvePaymentCap(argument2, { requestId });
|
|
127487
127495
|
if (!cap.ok && cap.error === "mcp_cap_argument_above_launch_cap") {
|
|
127488
|
-
const zero = zeroBeforeAsk("x402_pay", requestId);
|
|
127496
|
+
const zero = await zeroBeforeAsk("x402_pay", requestId);
|
|
127489
127497
|
if (zero) return zero;
|
|
127490
127498
|
const numbers = { totalAtomic: String(argument2), capAtomic: policy.limits.maxPaymentAtomic };
|
|
127491
127499
|
const asked = await askLimit2({
|
|
@@ -127595,21 +127603,22 @@ ${canonical5}`;
|
|
|
127595
127603
|
const launch = policy.limits.maxPaymentAtomic;
|
|
127596
127604
|
const total = code2 === "p03_float_over_maximum" ? ATOMIC_TEXT.test(String(error?.paidAtomic ?? "")) ? String(error.paidAtomic) : void 0 : capNumbers(error?.refusal).totalAtomic;
|
|
127597
127605
|
if (total !== void 0 && BigInt(total) > BigInt(launch) && BigInt(maxNow) === BigInt(launch)) {
|
|
127598
|
-
const zero = zeroBeforeAsk("x402_pay", requestId);
|
|
127606
|
+
const zero = await zeroBeforeAsk("x402_pay", requestId);
|
|
127599
127607
|
if (zero) return zero;
|
|
127600
127608
|
const numbers = { totalAtomic: total, capAtomic: launch };
|
|
127609
|
+
const split4 = code2 === "p03_float_over_maximum" ? floatSplitOf(error) : void 0;
|
|
127601
127610
|
const asked = await askLimit2({
|
|
127602
127611
|
requestId,
|
|
127603
127612
|
url: target.url,
|
|
127604
127613
|
numbers,
|
|
127605
127614
|
calledAt,
|
|
127606
|
-
message: `This costs ${usdcText3(total)} USDC. Your ${payCapName(launch)} is ${usdcText3(launch)} USDC. Allow it once?`
|
|
127615
|
+
message: `This costs ${usdcText3(total)} USDC${splitWords(split4, "the price")}. Your ${payCapName(launch)} is ${usdcText3(launch)} USDC. Allow it once?`
|
|
127607
127616
|
});
|
|
127608
127617
|
if (asked.ok) {
|
|
127609
127618
|
maxNow = total;
|
|
127610
127619
|
continue;
|
|
127611
127620
|
}
|
|
127612
|
-
if (asked.why !== "unsupported") return notAllowed(asked.why, { tool: "x402_pay", requestId, numbers });
|
|
127621
|
+
if (asked.why !== "unsupported") return notAllowed(asked.why, { tool: "x402_pay", requestId, numbers }, split4 ?? {});
|
|
127613
127622
|
askUnshown = true;
|
|
127614
127623
|
}
|
|
127615
127624
|
}
|
|
@@ -128426,6 +128435,7 @@ ${canonical5}`;
|
|
|
128426
128435
|
};
|
|
128427
128436
|
const positive2 = (atomic4) => /^[1-9][0-9]*$/.test(String(atomic4 ?? ""));
|
|
128428
128437
|
let refresh = {};
|
|
128438
|
+
let backgroundWalked = false;
|
|
128429
128439
|
const recentlyFailed = refreshFailedAt && Date.now() - refreshFailedAt < REFRESH_RETRY_MS && !refreshRun;
|
|
128430
128440
|
if (report.split?.shieldedAtomic != null && report.status === "stale") {
|
|
128431
128441
|
if (!recentlyFailed && (!finalityWait || refreshDeferred)) refreshShared().catch(() => {
|
|
@@ -128443,7 +128453,9 @@ ${canonical5}`;
|
|
|
128443
128453
|
refresh = { refreshed: true };
|
|
128444
128454
|
} else refresh = { refreshing: true, refreshReason: "refund_check" };
|
|
128445
128455
|
} else if (report.split?.shieldedAtomic != null && !recentlyFailed && !finalityWait && !refreshRun && (report.detail?.lastRefresh?.ageSeconds ?? 0) * 1e3 >= INBOUND_REFRESH_AGE_MS) {
|
|
128446
|
-
refreshShared({ background: true }).
|
|
128456
|
+
refreshShared({ background: true }).then(() => {
|
|
128457
|
+
backgroundWalked = true;
|
|
128458
|
+
}, () => {
|
|
128447
128459
|
});
|
|
128448
128460
|
} else if (report.split?.shieldedAtomic == null && recentlyFailed) {
|
|
128449
128461
|
refresh = { refreshed: false, refreshError: refreshFailedCode ?? "mcp_refresh_failed" };
|
|
@@ -128505,6 +128517,13 @@ ${canonical5}`;
|
|
|
128505
128517
|
});
|
|
128506
128518
|
const answered2 = await Promise.race([publicRead, answerWindow]);
|
|
128507
128519
|
if (tokensAnswered.reading) await Promise.race([tokensRead, answerWindow]);
|
|
128520
|
+
if (backgroundWalked) {
|
|
128521
|
+
try {
|
|
128522
|
+
store = session.openStore();
|
|
128523
|
+
} catch {
|
|
128524
|
+
}
|
|
128525
|
+
reread("refresh");
|
|
128526
|
+
}
|
|
128508
128527
|
mark("balance-public-read", answered2.reading ? "missed" : answered2.read ? "answered" : "failed");
|
|
128509
128528
|
mark("balance-tokens-read", tokensAnswered.reading ? "missed" : tokensAnswered.rows ? "answered" : "failed");
|
|
128510
128529
|
let ownTokens;
|
|
@@ -131143,7 +131162,7 @@ ${canonical5}`;
|
|
|
131143
131162
|
const capNext = (detail) => `Nothing was moved. Tell your owner: ${detail}. ${capRaiseText(spec.capFlag)} Then call ${spec.tool} again.`;
|
|
131144
131163
|
if (max !== void 0 && amount > max) {
|
|
131145
131164
|
const detail = `${record ? `the recorded ${spec.noun} of request_id "${request.requestId}" is not finished; its ` : ""}amount_atomic ${amount} (${usdcText3(amount)} USDC) is above the ${capName(spec.capFlag)} of ${usdcFlagText(max)} USDC`;
|
|
131146
|
-
const empty = kind === "unshield" && !record &&
|
|
131165
|
+
const empty = kind === "unshield" && !record && await knownZeroFresh() ? zeroBalanceFacts() : void 0;
|
|
131147
131166
|
if (empty && !empty.depositInFlight && !empty.heldUnknown) {
|
|
131148
131167
|
return refuse12(
|
|
131149
131168
|
"mcp_unshield_balance_empty",
|
|
@@ -133876,7 +133895,7 @@ ${canonical5}`;
|
|
|
133876
133895
|
const facts = { model: args.model, maxTokens: args.max_tokens, ceilingAtomic: ceiling.toString(), ceiling: usd(ceiling) };
|
|
133877
133896
|
let cap = policy.resolvePaymentCap(argument2, { requestId });
|
|
133878
133897
|
if (!cap.ok && cap.error === "mcp_cap_argument_above_launch_cap") {
|
|
133879
|
-
const zero = zeroBeforeAsk("inference_chat", requestId);
|
|
133898
|
+
const zero = await zeroBeforeAsk("inference_chat", requestId);
|
|
133880
133899
|
if (zero) return zero;
|
|
133881
133900
|
const numbers = { totalAtomic: String(argument2), capAtomic: launch };
|
|
133882
133901
|
const asked2 = await askLimit2({
|
|
@@ -133926,7 +133945,7 @@ ${canonical5}`;
|
|
|
133926
133945
|
}
|
|
133927
133946
|
);
|
|
133928
133947
|
}
|
|
133929
|
-
const zero = zeroBeforeAsk("inference_chat", requestId);
|
|
133948
|
+
const zero = await zeroBeforeAsk("inference_chat", requestId);
|
|
133930
133949
|
if (zero) return zero;
|
|
133931
133950
|
askedLimit = true;
|
|
133932
133951
|
const numbers = { totalAtomic: ceiling.toString(), capAtomic: launch };
|
|
@@ -134008,22 +134027,23 @@ ${canonical5}`;
|
|
|
134008
134027
|
const total = ATOMIC_TEXT.test(String(error?.paidAtomic ?? "")) ? String(error.paidAtomic) : void 0;
|
|
134009
134028
|
const lifted = BigInt(narrowed) > BigInt(launch);
|
|
134010
134029
|
if (total !== void 0 && BigInt(total) > BigInt(launch) && BigInt(narrowed) === BigInt(launch) && !askedLimit) {
|
|
134011
|
-
const zero = zeroBeforeAsk("inference_chat", requestId);
|
|
134030
|
+
const zero = await zeroBeforeAsk("inference_chat", requestId);
|
|
134012
134031
|
if (zero) return zero;
|
|
134013
134032
|
askedLimit = true;
|
|
134014
134033
|
const numbers = { totalAtomic: total, capAtomic: launch };
|
|
134034
|
+
const split4 = floatSplitOf(error);
|
|
134015
134035
|
const asked2 = await askLimit2({
|
|
134016
134036
|
requestId,
|
|
134017
134037
|
url: target.url,
|
|
134018
134038
|
numbers,
|
|
134019
134039
|
calledAt,
|
|
134020
|
-
message: `This costs ${usdcText3(total)} USDC with the fee. Your ${payCapName(launch)} is ${usdcText3(launch)} USDC. Allow it once?`
|
|
134040
|
+
message: `This costs ${usdcText3(total)} USDC${split4 ? splitWords(split4, "the AI provider's price") : " with the fee"}. Your ${payCapName(launch)} is ${usdcText3(launch)} USDC. Allow it once?`
|
|
134021
134041
|
});
|
|
134022
134042
|
if (asked2.ok) {
|
|
134023
134043
|
narrowed = total;
|
|
134024
134044
|
continue;
|
|
134025
134045
|
}
|
|
134026
|
-
if (asked2.why !== "unsupported") return notAllowed(asked2.why, { tool: "inference_chat", requestId, numbers }, facts);
|
|
134046
|
+
if (asked2.why !== "unsupported") return notAllowed(asked2.why, { tool: "inference_chat", requestId, numbers }, { ...facts, ...split4 });
|
|
134027
134047
|
return refuse12("p03_float_over_maximum", floatRefusal(error)[1], limitNext(numbers), { requestId, paid: false, ...numbers, ...facts });
|
|
134028
134048
|
}
|
|
134029
134049
|
if (total !== void 0 && lifted) {
|
|
@@ -135299,8 +135319,8 @@ var init_tools = __esm({
|
|
|
135299
135319
|
"p03_float_refund_pending"
|
|
135300
135320
|
]);
|
|
135301
135321
|
FLOAT_PRIVATE_LEG = "a private payment, so this answer has no transaction ID; wallet_receipts lists it";
|
|
135302
|
-
SELLER_ONLY_HERE = "
|
|
135303
|
-
outsideWalletRule = (what) => `Never reach ${what} outside this wallet (no curl, browser, fetch or DNS lookup of your own)` + (inTorRun() ? ": this wallet reaches it over Tor, and a
|
|
135322
|
+
SELLER_ONLY_HERE = "Reach a seller URL or its domain only with this wallet's tools, never yourself (no curl, browser, fetch, ping, DNS or DNS-over-HTTPS lookup), also when the user asks for no Tor: that would show the user's IP address to the site or to a DNS company.";
|
|
135323
|
+
outsideWalletRule = (what) => `Never reach ${what} or its domain outside this wallet (no curl, browser, fetch, ping, DNS or DNS-over-HTTPS lookup of your own), also when the user asks for no Tor` + (inTorRun() ? ": this wallet reaches it over Tor, and a lookup of your own would show the user's IP address" : "");
|
|
135304
135324
|
proxyStartStep = (tor) => tor ? `Make sure Tor is running (start it, or run ${terminalCommand2("setup")} again)` : "Tell the user to make sure the private connection this wallet runs through (its proxy) is running";
|
|
135305
135325
|
MONEY_ID2 = /^[A-Za-z0-9_-]{1,44}$/;
|
|
135306
135326
|
toRecordId = (requestId) => requestId === "" ? "" : recordId(String(requestId));
|
|
@@ -136911,7 +136931,7 @@ var init_stdioServer = __esm({
|
|
|
136911
136931
|
SUPPORTED_PROTOCOL_VERSIONS = Object.freeze(["2025-06-18", "2025-03-26", "2024-11-05"]);
|
|
136912
136932
|
MAX_LINE_BYTES = 4 * 1024 * 1024;
|
|
136913
136933
|
POSITIVE_ATOMIC7 = /^[1-9][0-9]{0,30}$/;
|
|
136914
|
-
INSTRUCTIONS = `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 the numbers. Never tell the user a tool, field, code or protocol name (x402, MCP) unless told to. Map the user's 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 private); "shield the USDC on this wallet's own address" -> wallet_shield; "stop" / "cancel" -> wallet_cancel with the request_id of what to stop; "pay this URL" -> x402_pay (no preview needed); "what does this URL cost" -> x402_preview (only when asked); "find a paid API for X" -> x402_discover, then x402_pay on the url it found; "send 2 USDC to <address>" -> wallet_unshield; "show my payments" -> wallet_receipts; "send another token" -> wallet_transfer_token; "ask an AI model" / "which AI models" -> inference_chat (
|
|
136934
|
+
INSTRUCTIONS = `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 the numbers. Never tell the user a tool, field, code or protocol name (x402, MCP) unless told to. Map the user's 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 private); "shield the USDC on this wallet's own address" -> wallet_shield; "stop" / "cancel" -> wallet_cancel with the request_id of what to stop; "pay this URL" -> x402_pay (no preview needed); "what does this URL cost" -> x402_preview (only when asked); "find a paid API for X" -> x402_discover, then x402_pay on the url it found; "send 2 USDC to <address>" -> wallet_unshield; "show my payments" -> wallet_receipts; "send another token" -> wallet_transfer_token; "ask an AI model" / "which AI models" -> inference_chat (with no prompt it lists the models and prices); "give my other AI app a private AI" -> inference_server (a local OpenAI-compatible URL and key for that app). wallet_balance answers ONE balance (balanceAtomic), and x402_pay pays any paid URL from it (a seller that cannot take a private payment is paid through Shinjuku: max_payment covers amountAtomic, fee included). Fields ending in Atomic are atomic units (1000000 = 1 USDC); tell the user USDC. The wallet does its own upkeep (no user command). 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 x402_pay: the same request_id never pays or moves money twice (a code ending in _retry_same_request: call again with it). A wallet_unshield send to an address not approved ahead asks the user to confirm first. x402_pay never pays above the owner's limits (one payment; any 24 hours); 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 app and its model provider see every URL, body, price and paid answer you handle; reach a seller or its domain only through these tools, never yourself (no curl, browser or DNS lookup, DNS-over-HTTPS too), also when the user asks for no Tor: it shows the user's IP address to the site or a DNS company. 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.`;
|
|
136915
136935
|
MCP_LOG_LEVELS = Object.freeze(["debug", "info", "notice", "warning", "error", "critical", "alert", "emergency"]);
|
|
136916
136936
|
POOL_SWITCH_LOG_LEVEL = "info";
|
|
136917
136937
|
validId = (id) => id === null || typeof id === "string" || typeof id === "number" && Number.isFinite(id);
|
|
@@ -136947,7 +136967,7 @@ var init_stdioServer = __esm({
|
|
|
136947
136967
|
MCP_CLOSE_UNREADABLE_BOUND_MS = 6e4;
|
|
136948
136968
|
MCP_CLOSE_POLL_MS = 500;
|
|
136949
136969
|
closeHistoryBusy = (server) => () => compactHistoryReadsRunning() > 0 || memoReadsAheadRunning() > 0 || server.refreshOpen?.() === true;
|
|
136950
|
-
SETUP_INSTRUCTIONS = `This Shinjuku Shield wallet is NOT SET UP
|
|
136970
|
+
SETUP_INSTRUCTIONS = `This Shinjuku Shield wallet is NOT SET UP 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, creates the wallet and downloads the proof tools (minutes: call again as next says). At stage done the wallet tools work. After setup: ${INSTRUCTIONS}`;
|
|
136951
136971
|
TOR_RELAY_READY_MS = 18e4;
|
|
136952
136972
|
RELAY_INIT_ID = "shinjuku-wallet-relay-initialize";
|
|
136953
136973
|
runMcp = runMcpServer;
|
|
@@ -137019,11 +137039,12 @@ function errorBody(error, restartStep, leastAtomic = 0n) {
|
|
|
137019
137039
|
} } };
|
|
137020
137040
|
}
|
|
137021
137041
|
if (code2 === "p03_merchant_respend_no_spendable_account") {
|
|
137042
|
+
const why = error?.knownZero === true ? "your private balance is 0 USDC, so there is nothing to pay with yet" : "this wallet has nothing it can pay with yet (its private balance is 0, or it holds only payments it received, which can pay only after you add money once)";
|
|
137022
137043
|
return { status: 402, body: { error: {
|
|
137023
137044
|
type: OPENAI_TYPE.quota,
|
|
137024
137045
|
param: null,
|
|
137025
137046
|
code: OPENAI_TYPE.quota,
|
|
137026
|
-
message: `nothing was paid:
|
|
137047
|
+
message: `nothing was paid: ${why}. Add money first: run ${commandLine("add-funds")} in a terminal (it asks the amount, from 0.01 USDC), then send the request again. This server pays from the new balance once add-funds says ready; nothing to restart`
|
|
137027
137048
|
} } };
|
|
137028
137049
|
}
|
|
137029
137050
|
if (INSUFFICIENT_CODE.test(code2 ?? "")) {
|
|
@@ -137263,7 +137284,7 @@ function createInferenceServer({
|
|
|
137263
137284
|
} catch {
|
|
137264
137285
|
empty = false;
|
|
137265
137286
|
}
|
|
137266
|
-
if (empty) throw new Error("p03_merchant_respend_no_spendable_account");
|
|
137287
|
+
if (empty) throw Object.assign(new Error("p03_merchant_respend_no_spendable_account"), { knownZero: true });
|
|
137267
137288
|
let result;
|
|
137268
137289
|
try {
|
|
137269
137290
|
result = await inference.inferenceChat({
|
|
@@ -144948,7 +144969,7 @@ function inferPreflight(inference, values, prompt, deps) {
|
|
|
144948
144969
|
const least = floor + SHINJUKU_FEE_ATOMIC;
|
|
144949
144970
|
const fits = (bound) => bound === void 0 || least <= BigInt(bound);
|
|
144950
144971
|
const lowerTokens = ceiling !== void 0 && ceiling > floor && fits(values.get("--max-payment")) && fits(limits?.maxPaymentAtomic) && fits(limits?.maxSessionAtomic) && fits(room?.day?.leftAtomic) && fits(room?.total?.leftAtomic);
|
|
144951
|
-
throw new PublicFailure(`${CEILING_OVER_CAP_CODE}: the AI provider's price for this request may be up to ${usdcOr(worst)} (${ceiling === void 0 ? "its minimum for one request" : `ceiling ${usdcOr(ceiling)}, minimum ${usdcOr(floor)}`}), and with Shinjuku's ${usdcOr(SHINJUKU_FEE_ATOMIC)} fee up to ${usdcOr(needed)} in all; that is above --max-payment ${usdcFlagText(values.get("--max-payment"))}
|
|
144972
|
+
throw new PublicFailure(`${CEILING_OVER_CAP_CODE}: the AI provider's price for this request may be up to ${usdcOr(worst)} (${ceiling === void 0 ? "its minimum for one request" : `ceiling ${usdcOr(ceiling)}, minimum ${usdcOr(floor)}`}), and with Shinjuku's ${usdcOr(SHINJUKU_FEE_ATOMIC)} fee up to ${usdcOr(needed)} in all; that is above --max-payment ${usdcFlagText(values.get("--max-payment"))} USDC; nothing was paid. ${overLimit ?? `Raise --max-payment to at least ${usdcFlagText(needed)} USDC`}${lowerTokens ? ", or lower --max-tokens" : ""}. The cap is only a limit, not the price: the call pays the AI provider's price for its tokens plus the 0.001 USDC fee, and a larger cap never pays more`);
|
|
144952
144973
|
}
|
|
144953
144974
|
return { model, maxTokens, ceiling, worst };
|
|
144954
144975
|
}
|
|
@@ -144997,7 +145018,7 @@ async function runInfer(values, deps) {
|
|
|
144997
145018
|
try {
|
|
144998
145019
|
assertSessionPool(values, session.pool);
|
|
144999
145020
|
if (!quiet) {
|
|
145000
|
-
io.err(`model ${model}: this request may pay the AI provider up to ${usdcOr(worst)}, plus Shinjuku's fee, and never more than --max-payment ${usdcFlagText(values.get("--max-payment"))}
|
|
145021
|
+
io.err(`model ${model}: this request may pay the AI provider up to ${usdcOr(worst)}, plus Shinjuku's fee, and never more than --max-payment ${usdcFlagText(values.get("--max-payment"))} USDC in all. ${inference.INFERENCE_NOTICE ?? `${INFER_COST_LINE}.`}
|
|
145001
145022
|
`);
|
|
145002
145023
|
io.err(`request-id ${requestId}${given ? "" : ` (if this run stops, rerun with --request-id ${requestId}: it never pays twice)`}
|
|
145003
145024
|
`);
|