shinjuku-shielded 0.3.183 → 0.3.184
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 +183 -57
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.184. The npm packages `shinjuku-shield` and
|
|
10
10
|
`shinjuku-shielded` hold the same files. The command is `shinjuku`.
|
|
11
11
|
|
|
12
12
|
## Set up
|
|
13
13
|
|
|
14
14
|
```sh
|
|
15
|
-
npx -y shinjuku@0.3.
|
|
15
|
+
npx -y shinjuku@0.3.184 setup
|
|
16
16
|
```
|
|
17
17
|
|
|
18
18
|
Setup offers to install the `shinjuku` command and, on Windows, adds npm's
|
|
@@ -35,13 +35,13 @@ Every wallet command works after `shinjuku`, for example `shinjuku balance`,
|
|
|
35
35
|
Claude Code:
|
|
36
36
|
|
|
37
37
|
```sh
|
|
38
|
-
claude mcp add --scope user shinjuku -- npx -y --no-audit --no-fund shinjuku-shield@0.3.
|
|
38
|
+
claude mcp add --scope user shinjuku -- npx -y --no-audit --no-fund shinjuku-shield@0.3.184 mcp
|
|
39
39
|
```
|
|
40
40
|
|
|
41
41
|
Claude Desktop (`claude_desktop_config.json`) or Cursor (`~/.cursor/mcp.json`):
|
|
42
42
|
|
|
43
43
|
```json
|
|
44
|
-
{ "mcpServers": { "shinjuku": { "command": "npx", "args": ["-y", "--no-audit", "--no-fund", "shinjuku-shield@0.3.
|
|
44
|
+
{ "mcpServers": { "shinjuku": { "command": "npx", "args": ["-y", "--no-audit", "--no-fund", "shinjuku-shield@0.3.184", "mcp"] } } }
|
|
45
45
|
```
|
|
46
46
|
|
|
47
47
|
On native Windows, if the host cannot find `npx`, use `"command": "cmd"` and
|
|
@@ -54,7 +54,7 @@ Codex (the Codex app and Codex CLI read the same file, `~/.codex/config.toml`):
|
|
|
54
54
|
```toml
|
|
55
55
|
[mcp_servers.shinjuku]
|
|
56
56
|
command = "npx"
|
|
57
|
-
args = ["-y", "--no-audit", "--no-fund", "shinjuku-shield@0.3.
|
|
57
|
+
args = ["-y", "--no-audit", "--no-fund", "shinjuku-shield@0.3.184", "mcp"]
|
|
58
58
|
startup_timeout_sec = 120
|
|
59
59
|
tool_timeout_sec = 300
|
|
60
60
|
```
|
package/manifest.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema": "carbon-shielded-wallet/bundle-manifest/v1",
|
|
3
3
|
"file": "shinjuku-wallet.mjs",
|
|
4
|
-
"sha256": "
|
|
5
|
-
"bytes":
|
|
6
|
-
"sourceCommit": "
|
|
4
|
+
"sha256": "fed76293d7f682c50f249284a7f4bbf14d2d6c7d8926c052c6ef1f683419b8dd",
|
|
5
|
+
"bytes": 9349716,
|
|
6
|
+
"sourceCommit": "37820c4cf40bdbd57dece9d1b739e1c541f534ed",
|
|
7
7
|
"sourceDirty": false,
|
|
8
8
|
"installRecordMatchesLockfile": true,
|
|
9
9
|
"releaseRule": "valid only when two fresh npm ci --ignore-scripts builds on different OSes give the same sha256; installRecordMatchesLockfile true means every entry npm installed equals its package-lock.json entry and every entry not marked optional, devOptional included, is installed: an optional entry (a package for another platform) may be absent",
|
|
@@ -1038,5 +1038,5 @@
|
|
|
1038
1038
|
"version": "1.8.0"
|
|
1039
1039
|
}
|
|
1040
1040
|
],
|
|
1041
|
-
"publishedAt": "2026-11-
|
|
1041
|
+
"publishedAt": "2026-11-06T16:14:51.926Z"
|
|
1042
1042
|
}
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "shinjuku-shielded",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.184",
|
|
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": "fed76293",
|
|
7
|
+
"shinjukuSha256": "fed76293d7f682c50f249284a7f4bbf14d2d6c7d8926c052c6ef1f683419b8dd",
|
|
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
|
@@ -43143,9 +43143,19 @@ function facilitatorRpcUrl(origin) {
|
|
|
43143
43143
|
url = void 0;
|
|
43144
43144
|
}
|
|
43145
43145
|
const base = url && (url.protocol === "https:" || url.protocol === "http:") ? payHostOf(url.origin) : DEFAULT_FACILITATOR_ORIGIN;
|
|
43146
|
-
relayOrigins.
|
|
43146
|
+
if (!relayOrigins.has(base)) {
|
|
43147
|
+
relayOrigins.add(base);
|
|
43148
|
+
builtRelayOrigins.add(base);
|
|
43149
|
+
try {
|
|
43150
|
+
process.env[RELAY_ORIGINS_ENV] = [...builtRelayOrigins].join(" ");
|
|
43151
|
+
} catch {
|
|
43152
|
+
}
|
|
43153
|
+
}
|
|
43147
43154
|
return `${base}${FACILITATOR_RPC_PATH}`;
|
|
43148
43155
|
}
|
|
43156
|
+
function relayOriginsEnv() {
|
|
43157
|
+
return builtRelayOrigins.size ? { [RELAY_ORIGINS_ENV]: [...builtRelayOrigins].join(" ") } : {};
|
|
43158
|
+
}
|
|
43149
43159
|
function isShinjukuRelayUrl(input) {
|
|
43150
43160
|
try {
|
|
43151
43161
|
const url = new URL(typeof input === "string" || input instanceof URL ? input : input?.url);
|
|
@@ -43189,7 +43199,7 @@ function resolveRpcUrl2({ rpcFile, rpc, env = process.env, origin, readFile: rea
|
|
|
43189
43199
|
}
|
|
43190
43200
|
return { url, source: "relay" };
|
|
43191
43201
|
}
|
|
43192
|
-
var DEFAULT_FACILITATOR_ORIGIN, PAY_HOSTS, FACILITATOR_RPC_PATH, RPC_ENV, relayOrigins;
|
|
43202
|
+
var DEFAULT_FACILITATOR_ORIGIN, PAY_HOSTS, FACILITATOR_RPC_PATH, RPC_ENV, RELAY_ORIGINS_ENV, builtRelayOrigins, relayOrigins;
|
|
43193
43203
|
var init_rpcDefault = __esm({
|
|
43194
43204
|
"wallet/src/rpcDefault.mjs"() {
|
|
43195
43205
|
"use strict";
|
|
@@ -43201,7 +43211,16 @@ var init_rpcDefault = __esm({
|
|
|
43201
43211
|
});
|
|
43202
43212
|
FACILITATOR_RPC_PATH = "/api/solana-rpc";
|
|
43203
43213
|
RPC_ENV = "UNDERMARKET_SOLANA_RPC_URL";
|
|
43204
|
-
|
|
43214
|
+
RELAY_ORIGINS_ENV = "SHINJUKU_RELAY_ORIGINS";
|
|
43215
|
+
builtRelayOrigins = new Set(String(process.env[RELAY_ORIGINS_ENV] ?? "").split(/\s+/).flatMap((value2) => {
|
|
43216
|
+
try {
|
|
43217
|
+
const url = new URL(value2);
|
|
43218
|
+
return (url.protocol === "https:" || url.protocol === "http:") && url.origin === value2 ? [value2] : [];
|
|
43219
|
+
} catch {
|
|
43220
|
+
return [];
|
|
43221
|
+
}
|
|
43222
|
+
}));
|
|
43223
|
+
relayOrigins = /* @__PURE__ */ new Set([DEFAULT_FACILITATOR_ORIGIN, ...Object.keys(PAY_HOSTS), ...Object.values(PAY_HOSTS), ...builtRelayOrigins]);
|
|
43205
43224
|
}
|
|
43206
43225
|
});
|
|
43207
43226
|
|
|
@@ -43832,6 +43851,16 @@ async function onOwnTagDispatcher(dispatcher, task) {
|
|
|
43832
43851
|
}
|
|
43833
43852
|
}
|
|
43834
43853
|
}
|
|
43854
|
+
function routeDispatcherOf(url) {
|
|
43855
|
+
let origin;
|
|
43856
|
+
try {
|
|
43857
|
+
origin = new URL(String(url)).origin;
|
|
43858
|
+
} catch {
|
|
43859
|
+
origin = void 0;
|
|
43860
|
+
}
|
|
43861
|
+
if (origin !== void 0 && routedOrigins.has(origin)) return onionInit({}).dispatcher;
|
|
43862
|
+
return ownTag.getStore()?.dispatcher;
|
|
43863
|
+
}
|
|
43835
43864
|
function onionInit(init = {}) {
|
|
43836
43865
|
if (runEnded()) return init;
|
|
43837
43866
|
const own = ownTagInit(init);
|
|
@@ -48313,6 +48342,40 @@ var init_relayLimit = __esm({
|
|
|
48313
48342
|
}
|
|
48314
48343
|
});
|
|
48315
48344
|
|
|
48345
|
+
// wallet/src/cli/homeJob.mjs
|
|
48346
|
+
function stepWords(lead, words2, line, { env = process.env, first, inline = false } = {}) {
|
|
48347
|
+
const key = homeKeyOf(words2);
|
|
48348
|
+
const comma = /\bor$/.test(lead) ? "" : ",";
|
|
48349
|
+
if (inHomeJob(env) && key) return `${lead}${comma} ${first ? `${first}, then ` : ""}press [${key}] on the home screen.`;
|
|
48350
|
+
return inline ? `${lead}: ${line}` : `${lead}${comma} run:
|
|
48351
|
+
${line}`;
|
|
48352
|
+
}
|
|
48353
|
+
function stepName(words2, line, { env = process.env } = {}) {
|
|
48354
|
+
const key = homeKeyOf(words2);
|
|
48355
|
+
return inHomeJob(env) && key ? `press [${key}] on the home screen` : line;
|
|
48356
|
+
}
|
|
48357
|
+
var HOME_JOB_ENV, LAUNCHER_PID_ENV, inHomeJob, HOME_KEY, JOB_NAME, jobLabel, homeKeyOf;
|
|
48358
|
+
var init_homeJob = __esm({
|
|
48359
|
+
"wallet/src/cli/homeJob.mjs"() {
|
|
48360
|
+
"use strict";
|
|
48361
|
+
HOME_JOB_ENV = "SHINJUKU_WALLET_HOME_JOB";
|
|
48362
|
+
LAUNCHER_PID_ENV = "SHINJUKU_WALLET_LAUNCHER_PID";
|
|
48363
|
+
inHomeJob = (env = process.env) => env?.[HOME_JOB_ENV] === "1";
|
|
48364
|
+
HOME_KEY = { "add-funds": "a", unshield: "u", curl: "p", chat: "t", setup: "s", restore: "r", limits: "l" };
|
|
48365
|
+
JOB_NAME = {
|
|
48366
|
+
"add-funds": "add funds",
|
|
48367
|
+
unshield: "send money out",
|
|
48368
|
+
curl: "pay a link",
|
|
48369
|
+
chat: "private AI chat",
|
|
48370
|
+
setup: "setup",
|
|
48371
|
+
restore: "restore",
|
|
48372
|
+
limits: "spending limits"
|
|
48373
|
+
};
|
|
48374
|
+
jobLabel = (name, typed, env = process.env) => inHomeJob(env) && JOB_NAME[name] ? JOB_NAME[name] : typed;
|
|
48375
|
+
homeKeyOf = (words2) => HOME_KEY[String(words2 ?? "").trim().split(/\s+/)[0]];
|
|
48376
|
+
}
|
|
48377
|
+
});
|
|
48378
|
+
|
|
48316
48379
|
// wallet/src/net/proxy.mjs
|
|
48317
48380
|
import { spawn } from "node:child_process";
|
|
48318
48381
|
import { randomBytes as randomBytes5 } from "node:crypto";
|
|
@@ -48825,7 +48888,8 @@ function proxiedChild(args, plainProxy, stdio) {
|
|
|
48825
48888
|
NODE_USE_ENV_PROXY: "1",
|
|
48826
48889
|
NODE_OPTIONS: proxiedNodeOptions(process.env.NODE_OPTIONS),
|
|
48827
48890
|
...proxyEnv(proxy),
|
|
48828
|
-
[MARK]: `tor ${proxy}
|
|
48891
|
+
[MARK]: `tor ${proxy}`,
|
|
48892
|
+
[LAUNCHER_PID_ENV]: launcherPid()
|
|
48829
48893
|
};
|
|
48830
48894
|
delete env[QUIET_RUN_MARK];
|
|
48831
48895
|
const quiet = quietRun(args);
|
|
@@ -48836,7 +48900,7 @@ function reexec(args, plainProxy) {
|
|
|
48836
48900
|
return waitForChild(proxiedChild(args, plainProxy, "inherit"));
|
|
48837
48901
|
}
|
|
48838
48902
|
function directChild(args) {
|
|
48839
|
-
const env = { ...process.env, [DIRECT_RUN_MARK]: "1" };
|
|
48903
|
+
const env = { ...process.env, [DIRECT_RUN_MARK]: "1", [LAUNCHER_PID_ENV]: launcherPid() };
|
|
48840
48904
|
delete env.NODE_USE_ENV_PROXY;
|
|
48841
48905
|
if (env.NODE_OPTIONS !== void 0) env.NODE_OPTIONS = withoutEnvProxyFlag(env.NODE_OPTIONS);
|
|
48842
48906
|
return spawn(
|
|
@@ -48981,7 +49045,7 @@ function torChild(argv2, stdio) {
|
|
|
48981
49045
|
if (!options.mode) throw new ProxyUsageError("torChild needs --tor");
|
|
48982
49046
|
return proxiedChild(options.args, options.proxy, stdio);
|
|
48983
49047
|
}
|
|
48984
|
-
var relayKeyOf, READ_ONLY_METHOD, readOnlyPost, TOR_HTTP_TUNNEL, TOR_CHECK, PROOF_TIMEOUT_MS, LOCAL_PROOF_TIMEOUT_MS, LOCAL_PROOF_MAX_BYTES, torProvenAt, proxyProvenAt, MARK, TOR_RUN_STARTED_ENV, ownProxyRefused, ONION_V3, RETRY_AFTER_CAP_MS, RETRY_AFTER_FLOOR_MS, RETRY_AFTER_DEFAULT_MS, RPC_NO_ANSWER_LIMIT_MS, RPC_PACING_CAP_MS, PACING_NOTICE_EVERY_MS, PACING_RATE_WINDOW_MS, TOR_MAX_ROTATIONS, runStartedAt, rpcNotBefore, pacingWaiters, pacingSince, pacedMs, rpcAnswered, lastAnswerAt, readSteps, pacingNoticeAt, pacingSamples, torMoves, torCircuitId, torMovesRefused, pendingMove, inTorRunOf, inTorRun, runNetworkMode, isOnionOrigin, ProxyUsageError, isOnionHost, PROXY_REMOVED, ENV_PROXY_NAMES, OUTER_PROXY_ENV, DIRECT_RUN_MARK, USE_ENV_PROXY_FLAG, withoutEnvProxyFlag, TOR_MIN_VERSION, localTorProof, TOR_EXPERT_BUNDLE, TOR_EXPERT_BUNDLE_SHA256, TOR_EXPERT_BUNDLE_URL, TUNNEL_LINE, TOR_DEB_KEY, TOR_DEB_KEYRING, TOR_INSTALL, torStart, LOCAL_TUNNEL, torStartText, TOR_WINDOW, torNotRunningMessage, torUpdateHow, TOR_STOP_OLD_WINDOWS, torTooOldWhy, torTooOldMessage, NOTICE, TOR_NOTICE_LINE, ONION_DETAIL_LINE, withoutOnionDetail, QUIET_RUN_MARK, QUIET_RUNS, QUIET_TERMINAL_COMMANDS, INFER_SUBCOMMANDS, quietRun, TOR_TROUBLE_LINE, TOR_WAIT_PLAIN, TOR_TROUBLE_PLAIN, promptRedraw, TOR_TROUBLE_SAID, quietTorErr, withRunTag, proxyEnv, pacedSoFar, RESENDABLE_METHOD, torCircuit, GLOBAL_DISPATCHER4, laneDispatchers, laneOfDispatcher, PROXY_WARNING_FLAG, proxiedExecArgv, proxiedNodeOptions, TOR_FROM_CONFIG_ENV, TOR_FROM_CONFIG_HINT, TOR_FROM_CONFIG_SENTENCE, torStarter;
|
|
49048
|
+
var relayKeyOf, READ_ONLY_METHOD, readOnlyPost, TOR_HTTP_TUNNEL, TOR_CHECK, PROOF_TIMEOUT_MS, LOCAL_PROOF_TIMEOUT_MS, LOCAL_PROOF_MAX_BYTES, torProvenAt, proxyProvenAt, MARK, TOR_RUN_STARTED_ENV, ownProxyRefused, ONION_V3, RETRY_AFTER_CAP_MS, RETRY_AFTER_FLOOR_MS, RETRY_AFTER_DEFAULT_MS, RPC_NO_ANSWER_LIMIT_MS, RPC_PACING_CAP_MS, PACING_NOTICE_EVERY_MS, PACING_RATE_WINDOW_MS, TOR_MAX_ROTATIONS, runStartedAt, rpcNotBefore, pacingWaiters, pacingSince, pacedMs, rpcAnswered, lastAnswerAt, readSteps, pacingNoticeAt, pacingSamples, torMoves, torCircuitId, torMovesRefused, pendingMove, inTorRunOf, inTorRun, runNetworkMode, isOnionOrigin, ProxyUsageError, isOnionHost, PROXY_REMOVED, ENV_PROXY_NAMES, OUTER_PROXY_ENV, DIRECT_RUN_MARK, USE_ENV_PROXY_FLAG, withoutEnvProxyFlag, TOR_MIN_VERSION, localTorProof, TOR_EXPERT_BUNDLE, TOR_EXPERT_BUNDLE_SHA256, TOR_EXPERT_BUNDLE_URL, TUNNEL_LINE, TOR_DEB_KEY, TOR_DEB_KEYRING, TOR_INSTALL, torStart, LOCAL_TUNNEL, torStartText, TOR_WINDOW, torNotRunningMessage, torUpdateHow, TOR_STOP_OLD_WINDOWS, torTooOldWhy, torTooOldMessage, NOTICE, TOR_NOTICE_LINE, ONION_DETAIL_LINE, withoutOnionDetail, QUIET_RUN_MARK, QUIET_RUNS, QUIET_TERMINAL_COMMANDS, INFER_SUBCOMMANDS, quietRun, TOR_TROUBLE_LINE, TOR_WAIT_PLAIN, TOR_TROUBLE_PLAIN, promptRedraw, TOR_TROUBLE_SAID, quietTorErr, withRunTag, proxyEnv, pacedSoFar, RESENDABLE_METHOD, torCircuit, GLOBAL_DISPATCHER4, laneDispatchers, laneOfDispatcher, PROXY_WARNING_FLAG, proxiedExecArgv, proxiedNodeOptions, TOR_FROM_CONFIG_ENV, TOR_FROM_CONFIG_HINT, TOR_FROM_CONFIG_SENTENCE, launcherPid, torStarter;
|
|
48985
49049
|
var init_proxy = __esm({
|
|
48986
49050
|
"wallet/src/net/proxy.mjs"() {
|
|
48987
49051
|
"use strict";
|
|
@@ -48993,6 +49057,7 @@ var init_proxy = __esm({
|
|
|
48993
49057
|
init_relayLimit();
|
|
48994
49058
|
init_rpcDefault();
|
|
48995
49059
|
init_phaseTiming();
|
|
49060
|
+
init_homeJob();
|
|
48996
49061
|
relayKeyOf = (input) => {
|
|
48997
49062
|
if (!isShinjukuRelayUrl(input)) return void 0;
|
|
48998
49063
|
return `${new URL(typeof input === "string" || input instanceof URL ? input : input.url).origin}${FACILITATOR_RPC_PATH}`;
|
|
@@ -49181,6 +49246,7 @@ ${command}`;
|
|
|
49181
49246
|
TOR_FROM_CONFIG_ENV = "SHINJUKU_WALLET_TOR_FROM_CONFIG";
|
|
49182
49247
|
TOR_FROM_CONFIG_HINT = '. Tor is on for every command because setup recorded it (config.json "tor": true); to run this one command without Tor, add --no-tor (the servers then see your IP address)';
|
|
49183
49248
|
TOR_FROM_CONFIG_SENTENCE = " Tor is on for every command because you chose it in setup.";
|
|
49249
|
+
launcherPid = () => process.env[LAUNCHER_PID_ENV] ?? String(process.ppid);
|
|
49184
49250
|
}
|
|
49185
49251
|
});
|
|
49186
49252
|
|
|
@@ -106022,6 +106088,16 @@ function refundEtaLeft(dueAtMs, now = Date.now()) {
|
|
|
106022
106088
|
function floatRefundReadDue(record, now = Date.now()) {
|
|
106023
106089
|
return Number.isSafeInteger(record?.refundDueAtMs) && now >= record.refundDueAtMs - REFUND_READ_EARLY_MS;
|
|
106024
106090
|
}
|
|
106091
|
+
function sellerWaitMs(record) {
|
|
106092
|
+
const seconds2 = (record?.sellerRequirement ?? record?.requirement)?.maxTimeoutSeconds;
|
|
106093
|
+
if (!Number.isSafeInteger(seconds2) || seconds2 <= 0 || seconds2 > SELLER_TIMEOUT_ABSURD_SECONDS) return SELLER_TIMEOUT_MS;
|
|
106094
|
+
return Math.min(Math.max(seconds2 * 1e3, SELLER_TIMEOUT_MS), FLOAT_KEEP_BYTES_MS);
|
|
106095
|
+
}
|
|
106096
|
+
function sellerAnswerInit(url, init, ms) {
|
|
106097
|
+
const target = () => init.dispatcher ?? routeDispatcherOf(url) ?? globalThis[GLOBAL_DISPATCHER5];
|
|
106098
|
+
if (target() === void 0) return init;
|
|
106099
|
+
return { ...init, dispatcher: { dispatch: (options, handler) => target().dispatch({ ...options, headersTimeout: ms, bodyTimeout: ms }, handler) } };
|
|
106100
|
+
}
|
|
106025
106101
|
async function sellerRefusalText(response) {
|
|
106026
106102
|
let text3 = "";
|
|
106027
106103
|
let reader;
|
|
@@ -107488,7 +107564,8 @@ async function payViaFloat({
|
|
|
107488
107564
|
let resendUntilMs;
|
|
107489
107565
|
let answeredAtMs;
|
|
107490
107566
|
let dispatcher;
|
|
107491
|
-
const
|
|
107567
|
+
const waitMs = sellerWaitMs(record);
|
|
107568
|
+
const sellerTimeout = AbortSignal.timeout(waitMs);
|
|
107492
107569
|
const stopResends = () => Date.now() > resendUntilMs || ["landed", "dead", "final", "cancelled"].includes(watch.verdict()?.state);
|
|
107493
107570
|
for (let resend = 0; ; resend += 1) {
|
|
107494
107571
|
const init = {
|
|
@@ -107500,7 +107577,7 @@ async function payViaFloat({
|
|
|
107500
107577
|
};
|
|
107501
107578
|
const socketWatch = resend === 0 ? watchRequestSocket(record.url) : void 0;
|
|
107502
107579
|
try {
|
|
107503
|
-
response = await fetchImpl(record.url, dispatcher === void 0 ? keepAliveInit(init) : { ...init, dispatcher });
|
|
107580
|
+
response = await fetchImpl(record.url, sellerAnswerInit(record.url, dispatcher === void 0 ? keepAliveInit(init) : { ...init, dispatcher }, waitMs));
|
|
107504
107581
|
} catch (error) {
|
|
107505
107582
|
unanswered2(error);
|
|
107506
107583
|
} finally {
|
|
@@ -107802,13 +107879,13 @@ async function selfBroadcastLeg({ store, walName: walName2, record, sendRequest,
|
|
|
107802
107879
|
mark("seller-sent");
|
|
107803
107880
|
let response;
|
|
107804
107881
|
try {
|
|
107805
|
-
response = await fetchImpl(record.url, keepAliveInit({
|
|
107882
|
+
response = await fetchImpl(record.url, sellerAnswerInit(record.url, keepAliveInit({
|
|
107806
107883
|
method: sendRequest.method,
|
|
107807
107884
|
headers: { ...Object.fromEntries(sendRequest.headers), "PAYMENT-SIGNATURE": header },
|
|
107808
107885
|
...sendRequest.method === "POST" ? { body: Buffer.from(sendRequest.bodyBase64, "base64") } : {},
|
|
107809
107886
|
redirect: "error",
|
|
107810
|
-
signal: AbortSignal.timeout(
|
|
107811
|
-
}));
|
|
107887
|
+
signal: AbortSignal.timeout(sellerWaitMs(record))
|
|
107888
|
+
}), sellerWaitMs(record)));
|
|
107812
107889
|
} catch (error) {
|
|
107813
107890
|
const timedOut = error?.name === "TimeoutError" || error?.cause?.name === "TimeoutError";
|
|
107814
107891
|
if (!timedOut && !proxyRefusedConnection(error) && await resendUnanswered()) {
|
|
@@ -107939,7 +108016,7 @@ function paidResult(record, replayed) {
|
|
|
107939
108016
|
float: { floatId: record.floatId }
|
|
107940
108017
|
};
|
|
107941
108018
|
}
|
|
107942
|
-
var import_web3115, FLOAT_PAYMENT_SCHEMA2, REGENERATE_CODES, FLOAT_PAYMENT_WAL_PREFIX2, FLOAT_CONFIG_SCHEMA, FLOAT_PAY_PATH, FLOAT_MEMO_PATH, FLOAT_STATUS_PATH, MAX_BODY_BYTES, FLOAT_REFUND_ETA_SECONDS, REFUND_READ_EARLY_MS, REFUND_ETA_MAX_SECONDS, refundDueOf, REFUND_SETTLED_AFTER_MS, REFUND_OUTCOME_NEWS_MS, FINISHING_POLL_MS, FINISHING_LIMIT_MS, SELLER_TIMEOUT_MS, FLOAT_STATUS_START_MS, FLOAT_STATUS_POLL_MS, FLOAT_STATUS_TIMEOUT_MS, FLOAT_TRANSFER_DEAD, FLOAT_PAYMENT_REVERTED, VERDICT_POLL_MS, SELLER_ANSWER_VERDICT_MS, TRANSFER_MIN_BLOCKS_LEFT, TRANSFER_FRESH_MS, BLOCK_HEIGHT_TIMEOUT_MS, CONFIG_TIMEOUT_MS, MEMO_UPLOAD_TIMEOUT_MS, CONFIG_CACHE_MS, FLOAT_POOL_WARM_MS, DECIMAL3, POSITIVE, PENDING_CODES, FLOAT_FRONT_HEADER, hash7, fail22, GENERIC_REASON, SELLER_REASON_MAX, SELLER_REASON_READ_BYTES, FEE_PAYER_RESENDS, FEE_PAYER_RESEND_MS, GLOBAL_DISPATCHER5, sortedJson, MODEL_ID, floatPaymentWalName, floatRecordName, FLOAT_KEEP_BYTES_MS, memoryOnlyNeedsScrub, FLOAT_KEEP_OPEN_REQUEST_MS, configCache, configGeneration, configReadSequence, configReads, configRefreshes, SPECULATED_MAX_AGE_MS, speculatedQuotes, poolDomains, FLOAT_FACTS_SCHEMA, floatFacts, floatFactsKey, floatFactsMac, poolDomainReads, poolDomainWarmFailedAt, WARM_RETRY_MS, payerGenerator, etaEntry, loadPayerGenerator, plainText, BROADCAST_REFUSED, BROADCAST_REFUSED_STANDARD, BROADCAST_DEAD, TRANSFER_LANDING_WINDOW_MS, PROOF_DELIVERY_MS, SELF_BROADCAST_LEG1_LEFT_MS, BROADCAST_UNSIGNED, BROADCAST_NO_LOOKUP, BROADCAST_LANDED, BROADCAST_LIMIT_MS, BROADCAST_QUOTE_MARGIN_MS, SELF_BROADCAST_RESEND_MS, SELF_BROADCAST_UNANSWERED_RESEND_MS, SELLER_HEADERS_MAX_COUNT, SELLER_HEADERS_MAX_BYTES, FINAL_AFTER_202_MS, SELLER_HEADERS_KEPT;
|
|
108019
|
+
var import_web3115, FLOAT_PAYMENT_SCHEMA2, REGENERATE_CODES, FLOAT_PAYMENT_WAL_PREFIX2, FLOAT_CONFIG_SCHEMA, FLOAT_PAY_PATH, FLOAT_MEMO_PATH, FLOAT_STATUS_PATH, MAX_BODY_BYTES, FLOAT_REFUND_ETA_SECONDS, REFUND_READ_EARLY_MS, REFUND_ETA_MAX_SECONDS, refundDueOf, REFUND_SETTLED_AFTER_MS, REFUND_OUTCOME_NEWS_MS, FINISHING_POLL_MS, FINISHING_LIMIT_MS, SELLER_TIMEOUT_MS, SELLER_TIMEOUT_ABSURD_SECONDS, FLOAT_STATUS_START_MS, FLOAT_STATUS_POLL_MS, FLOAT_STATUS_TIMEOUT_MS, FLOAT_TRANSFER_DEAD, FLOAT_PAYMENT_REVERTED, VERDICT_POLL_MS, SELLER_ANSWER_VERDICT_MS, TRANSFER_MIN_BLOCKS_LEFT, TRANSFER_FRESH_MS, BLOCK_HEIGHT_TIMEOUT_MS, CONFIG_TIMEOUT_MS, MEMO_UPLOAD_TIMEOUT_MS, CONFIG_CACHE_MS, FLOAT_POOL_WARM_MS, DECIMAL3, POSITIVE, PENDING_CODES, FLOAT_FRONT_HEADER, hash7, fail22, GENERIC_REASON, SELLER_REASON_MAX, SELLER_REASON_READ_BYTES, FEE_PAYER_RESENDS, FEE_PAYER_RESEND_MS, GLOBAL_DISPATCHER5, sortedJson, MODEL_ID, floatPaymentWalName, floatRecordName, FLOAT_KEEP_BYTES_MS, memoryOnlyNeedsScrub, FLOAT_KEEP_OPEN_REQUEST_MS, configCache, configGeneration, configReadSequence, configReads, configRefreshes, SPECULATED_MAX_AGE_MS, speculatedQuotes, poolDomains, FLOAT_FACTS_SCHEMA, floatFacts, floatFactsKey, floatFactsMac, poolDomainReads, poolDomainWarmFailedAt, WARM_RETRY_MS, payerGenerator, etaEntry, loadPayerGenerator, plainText, BROADCAST_REFUSED, BROADCAST_REFUSED_STANDARD, BROADCAST_DEAD, TRANSFER_LANDING_WINDOW_MS, PROOF_DELIVERY_MS, SELF_BROADCAST_LEG1_LEFT_MS, BROADCAST_UNSIGNED, BROADCAST_NO_LOOKUP, BROADCAST_LANDED, BROADCAST_LIMIT_MS, BROADCAST_QUOTE_MARGIN_MS, SELF_BROADCAST_RESEND_MS, SELF_BROADCAST_UNANSWERED_RESEND_MS, SELLER_HEADERS_MAX_COUNT, SELLER_HEADERS_MAX_BYTES, FINAL_AFTER_202_MS, SELLER_HEADERS_KEPT;
|
|
107943
108020
|
var init_floatPay = __esm({
|
|
107944
108021
|
"wallet/src/pay/floatPay.mjs"() {
|
|
107945
108022
|
"use strict";
|
|
@@ -107986,6 +108063,7 @@ var init_floatPay = __esm({
|
|
|
107986
108063
|
FINISHING_POLL_MS = 2e3;
|
|
107987
108064
|
FINISHING_LIMIT_MS = 6e4;
|
|
107988
108065
|
SELLER_TIMEOUT_MS = 12e4;
|
|
108066
|
+
SELLER_TIMEOUT_ABSURD_SECONDS = 86400;
|
|
107989
108067
|
FLOAT_STATUS_START_MS = 45e3;
|
|
107990
108068
|
FLOAT_STATUS_POLL_MS = 5e3;
|
|
107991
108069
|
FLOAT_STATUS_TIMEOUT_MS = 5e3;
|
|
@@ -135533,7 +135611,7 @@ ${canonical5}`;
|
|
|
135533
135611
|
const balance = {
|
|
135534
135612
|
name: "wallet_balance",
|
|
135535
135613
|
title: "Balance",
|
|
135536
|
-
description: `Use this
|
|
135614
|
+
description: `Use this for "what is my balance" or "how much USDC do I have": it answers ONE balance (balanceAtomic, what a payment can spend) and the public (unshielded) USDC. Always safe: it ${BALANCE_READ_DOES}. On "show my wallet", print \`card\` as it is (at most 8 lines). largestPaymentAtomic: the most ONE payment can spend now; a payment above it is not refused: pay_for_service gets the balance ready first (a tell-first answer, then doneInMinutesLow to doneInMinutesHigh minutes) (changeSettling: 0 only while the last payment's change settles, about changeReadyInSeconds; then one payment can use it all, or up to changeUpToAtomic). balanceParts (above 1): never mention parts, accounts or a merge; say only that a large payment or send first gets the balance ready. balanceAtomic is one number; breakdown names the rest (shieldedAtomic is the same value; privateSendPendingAtomic is what a running private send has not sent yet, already taken off; refundsInFlightAtomic is a refund Shinjuku proved, on its way, not in balanceAtomic; refundsNotCertainAtomic a refund the seller may have kept, in no number; openPaymentsAtomic: paid, waiting on its seller (same request_id finishes it, else refunded); setAsideAtomic (when not 0): value an older version set aside; totalAtomic adds these; during a pool move, pools lists each pool's share, movingAtomic is value on its way to the new pool, and move and poolSwitches show the move). unshieldedAtomic is the public USDC on the wallet's own Solana key (ownAddress), which wallet_shield makes private; unshieldedSolLamports is that key's SOL (Shinjuku pays every fee and rent). A stale balance (a new deposit, a received payment) reads the chain first; past about 20 s it answers the last balance with refreshing: true and finishes in the background (call again in 30 s); with a refreshReason that balance is exact and counts what the reason names (payment_settling: a payment that settles; account_join: all of it, while the wallet gets it ready to send; pool_move: value that arrives from the old pool; refund_check: a refund counted from an old read, which the wallet checks now (never say it is still on its way); first_check: a new wallet's own landed deposits (its first history check)). status reading (balanceAtomic null): the first read of a wallet that may hold money is not done; call again in 30 s. If the public read fails, unshieldedAtomic is null with unshieldedReason. ownKeyTokens: the other tokens on ownAddress (not its USDC; [] when none; null when not read now: say nothing of other tokens), each { mint, amountAtomic, decimals, amount }, at most 10 (ownKeyTokensMore counts the rest); a token is its mint, never a name or symbol; no wallet tool sells, swaps or sends them: they stay on ownAddress. earlierDeposits (when any): USDC at an earlier pool's one-time deposit address, each with a notice line to tell the user; the wallet moves it itself. addFunds (when any): each open wallet_add_funds address, its state and the USDC known to wait there (heldAtomic; null with heldNote when not read in time). startsAtNextRequest true (old name): it starts by itself once USDC is seen there (startsInMinutes; 0: at once). landingAtomic (when not 0): added USDC that landed on chain, not in balanceAtomic yet; this call finishes it (up to about 20 s), else call again when next says. 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 counters. To add money, use wallet_add_funds. version: this wallet's version. Amounts are atomic (1000000 = 1 USDC); say and usdc give USDC.`,
|
|
135537
135615
|
inputSchema: { type: "object", properties: {
|
|
135538
135616
|
verbose: { type: "boolean", description: "Optional. true adds `internal`: the engineering numbers (funded balance records, notes, payments without waiting, a 0 set-aside value). Default false." }
|
|
135539
135617
|
}, additionalProperties: false },
|
|
@@ -140459,7 +140537,7 @@ ${canonical5}`;
|
|
|
140459
140537
|
name: "wallet_unshield",
|
|
140460
140538
|
// UX130-13: a host that defers tools may show only the title: it says where a send goes by default.
|
|
140461
140539
|
title: "Send USDC privately",
|
|
140462
|
-
description: `Use this
|
|
140540
|
+
description: `Use this for "send 2 USDC to <address>" or "withdraw to my wallet" (for "my wallet" leave \`to\` out: it uses the address saved at setup, or says how to set one; never ask the user first): it sends amount (USDC, like "2"; or amount_atomic) from the PRIVATE balance as plain USDC to \`to\`, a public Solana address. BEFORE you call it to send all of the balance when wallet_balance showed balanceParts above 1, write to the user that the wallet first gets the balance ready to send (never say how the wallet stores the balance; some apps show nothing until this call ends). Privately: the chain shows the pool paying the address, not which wallet paid. This wallet's own public address (ownAddress in wallet_balance: it holds the public USDC, wallet_shield deposits from it) is refused as \`to\`: an exit there would show on chain that the private balance is this wallet's, even if that address never deposited (wallet_add_funds deposits come from one-time addresses, not from it; never tell the user they came from it). Shinjuku pays every network fee; no SOL is needed. The user's saved own addresses (setup or this app's wallet entry) send at once. Any other address needs the user's yes in a dialog of this app; a client that cannot ask is refused (mcp_unshield_to_not_allowed) and a decline sends nothing (mcp_unshield_declined). \`to\` must already be able to receive USDC: an address that cannot is refused before any dialog (mcp_unshield_to_invalid). It runs in steps and may wait for the pool's next anchor. Each call answers within about 20 s (at once when the send ends; a dialog may take longer) with ok: true and stage: confirming, queued, refreshing, self-pay = preparing, exit = sending, done; joining = the wallet first gets the balance ready, then sends; each call goes on with it (joinSteps: its steps, in order; doneInMinutesLow to doneInMinutesHigh: the time to say). For the status, call wallet_unshield again with the SAME request_id, amount and to. When the balance must first be made ready, 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: when this app sends a progress token with that next call, the call gets the balance ready and then sends, with a progress line every ${JOIN_STEP_MS / 1e3} s ("getting your balance ready to send"; some apps show none, so the line is said before the call, as above). It answers when the send is done, or after about ${joinAnswerSeconds(JOIN_CALL_MAX_MS)} s with how far it got (joinsDone; sendState sending: the USDC is leaving, never say nothing moved); then call again with the same request_id. Without a progress token it answers within about 20 s with stage joining: call again until it sends. The same request_id never sends twice, also after a restart. request_id is optional: without it the answer names the id it made, and the same call again within 10 minutes after it ends reads that same send. An optional unshield limit the user sets may bound each call and what this wallet sends in any 24 hours, from every app (mcp_unshield_cap_exceeded: tell the user). Other refusals: mcp_argument_invalid, mcp_request_id_reused, wallet_locked, mcp_tool_disabled, mcp_unshield_failed, and the unshield's own p03_* codes. A call the app stopped, rejected or interrupted, or one that failed, may still send: call wallet_cancel (no request_id) before you tell the user anything about that send; never say nothing was sent without it. A send is one payment to \`to\`. ${HOST_BLOCKED_LINE}`,
|
|
140463
140541
|
inputSchema: {
|
|
140464
140542
|
type: "object",
|
|
140465
140543
|
properties: {
|
|
@@ -146898,39 +146976,6 @@ var init_consolePaste = __esm({
|
|
|
146898
146976
|
}
|
|
146899
146977
|
});
|
|
146900
146978
|
|
|
146901
|
-
// wallet/src/cli/homeJob.mjs
|
|
146902
|
-
function stepWords(lead, words2, line, { env = process.env, first, inline = false } = {}) {
|
|
146903
|
-
const key = homeKeyOf(words2);
|
|
146904
|
-
const comma = /\bor$/.test(lead) ? "" : ",";
|
|
146905
|
-
if (inHomeJob(env) && key) return `${lead}${comma} ${first ? `${first}, then ` : ""}press [${key}] on the home screen.`;
|
|
146906
|
-
return inline ? `${lead}: ${line}` : `${lead}${comma} run:
|
|
146907
|
-
${line}`;
|
|
146908
|
-
}
|
|
146909
|
-
function stepName(words2, line, { env = process.env } = {}) {
|
|
146910
|
-
const key = homeKeyOf(words2);
|
|
146911
|
-
return inHomeJob(env) && key ? `press [${key}] on the home screen` : line;
|
|
146912
|
-
}
|
|
146913
|
-
var HOME_JOB_ENV, inHomeJob, HOME_KEY, JOB_NAME, jobLabel, homeKeyOf;
|
|
146914
|
-
var init_homeJob = __esm({
|
|
146915
|
-
"wallet/src/cli/homeJob.mjs"() {
|
|
146916
|
-
"use strict";
|
|
146917
|
-
HOME_JOB_ENV = "SHINJUKU_WALLET_HOME_JOB";
|
|
146918
|
-
inHomeJob = (env = process.env) => env?.[HOME_JOB_ENV] === "1";
|
|
146919
|
-
HOME_KEY = { "add-funds": "a", unshield: "u", curl: "p", chat: "t", setup: "s", restore: "r", limits: "l" };
|
|
146920
|
-
JOB_NAME = {
|
|
146921
|
-
"add-funds": "add funds",
|
|
146922
|
-
unshield: "send money out",
|
|
146923
|
-
curl: "pay a link",
|
|
146924
|
-
chat: "private AI chat",
|
|
146925
|
-
setup: "setup",
|
|
146926
|
-
restore: "restore",
|
|
146927
|
-
limits: "spending limits"
|
|
146928
|
-
};
|
|
146929
|
-
jobLabel = (name, typed, env = process.env) => inHomeJob(env) && JOB_NAME[name] ? JOB_NAME[name] : typed;
|
|
146930
|
-
homeKeyOf = (words2) => HOME_KEY[String(words2 ?? "").trim().split(/\s+/)[0]];
|
|
146931
|
-
}
|
|
146932
|
-
});
|
|
146933
|
-
|
|
146934
146979
|
// wallet/src/cli/homeMark.mjs
|
|
146935
146980
|
var MARK_WIDTH, MARK2, MARK_CLASS, EYE, COMPACT_MARK;
|
|
146936
146981
|
var init_homeMark = __esm({
|
|
@@ -147789,7 +147834,15 @@ function homeScreenNeeds() {
|
|
|
147789
147834
|
}
|
|
147790
147835
|
return { columns: MIN_COLUMNS, rows: 80 };
|
|
147791
147836
|
}
|
|
147792
|
-
async function runJobView({
|
|
147837
|
+
async function runJobView({
|
|
147838
|
+
title,
|
|
147839
|
+
run: run2,
|
|
147840
|
+
stdout = process.stdout,
|
|
147841
|
+
stdin = process.stdin,
|
|
147842
|
+
env = process.env,
|
|
147843
|
+
launcherGone = launcherWatch(),
|
|
147844
|
+
platform = process.platform
|
|
147845
|
+
} = {}) {
|
|
147793
147846
|
const codes = paletteFor(screenColor(stdout, env));
|
|
147794
147847
|
const paint2 = (parts) => parts.map(([text3, cls]) => codes && cls ? `${codes[cls]}${text3}${RESET2}` : text3).join("");
|
|
147795
147848
|
const write = (text3) => {
|
|
@@ -147811,6 +147864,22 @@ ${rule}
|
|
|
147811
147864
|
code2 = 1;
|
|
147812
147865
|
}
|
|
147813
147866
|
const end2 = code2 === 0 ? [["\u25C6 ", "crim"], [`${clean4(title)}: done`, "bone"]] : code2 === 130 ? [["\u25C6 ", "crim"], [`${clean4(title)}: stopped (Ctrl+C)`, "bone"]] : [["\u25CB ", "mute"], [`${clean4(title)}: it stopped; its message is above`, "bone"]];
|
|
147867
|
+
const gone = () => {
|
|
147868
|
+
try {
|
|
147869
|
+
return launcherGone();
|
|
147870
|
+
} catch {
|
|
147871
|
+
return false;
|
|
147872
|
+
}
|
|
147873
|
+
};
|
|
147874
|
+
const shellAgain = (first) => write(`${first ? `
|
|
147875
|
+
${"\u2500".repeat(width)}
|
|
147876
|
+
${end2.map(([text3]) => text3).join("")}
|
|
147877
|
+
` : ""}The wallet screen has closed: the command that started it ended with the Ctrl+C.
|
|
147878
|
+
` + (platform === "win32" ? 'If this window asks "Terminate batch job (Y/N)?", type Y and press Enter. ' : "") + "To open the wallet again, run the same command.\n");
|
|
147879
|
+
if (gone()) {
|
|
147880
|
+
shellAgain(true);
|
|
147881
|
+
return { code: code2, next: "quit", launcherGone: true };
|
|
147882
|
+
}
|
|
147814
147883
|
write(`
|
|
147815
147884
|
${rule}
|
|
147816
147885
|
${paint2(end2)}
|
|
@@ -147820,15 +147889,24 @@ ${paint2([["any other key, [q] too, goes back to the home screen", "mute"]])}
|
|
|
147820
147889
|
if (!stdin?.isTTY || typeof stdin.setRawMode !== "function") return { code: code2, next: "quit" };
|
|
147821
147890
|
const rawBefore = Boolean(stdin.isRaw);
|
|
147822
147891
|
let key;
|
|
147892
|
+
let ended2 = false;
|
|
147893
|
+
let poll;
|
|
147823
147894
|
try {
|
|
147824
147895
|
stdin.setRawMode(true);
|
|
147825
147896
|
key = await new Promise((done) => {
|
|
147826
147897
|
stdin.once("data", (chunk) => done(String(chunk)));
|
|
147898
|
+
poll = setInterval(() => {
|
|
147899
|
+
if (gone()) {
|
|
147900
|
+
ended2 = true;
|
|
147901
|
+
done(void 0);
|
|
147902
|
+
}
|
|
147903
|
+
}, LAUNCHER_POLL_MS);
|
|
147827
147904
|
stdin.resume();
|
|
147828
147905
|
});
|
|
147829
147906
|
} catch {
|
|
147830
147907
|
key = void 0;
|
|
147831
147908
|
} finally {
|
|
147909
|
+
clearInterval(poll);
|
|
147832
147910
|
stdin.pause();
|
|
147833
147911
|
await stopReading(stdin);
|
|
147834
147912
|
try {
|
|
@@ -147836,8 +147914,24 @@ ${paint2([["any other key, [q] too, goes back to the home screen", "mute"]])}
|
|
|
147836
147914
|
} catch {
|
|
147837
147915
|
}
|
|
147838
147916
|
}
|
|
147917
|
+
if (ended2) {
|
|
147918
|
+
shellAgain(false);
|
|
147919
|
+
return { code: code2, next: "quit", launcherGone: true };
|
|
147920
|
+
}
|
|
147839
147921
|
return key === void 0 ? { code: code2, next: "quit" } : { code: code2, next: "back", key };
|
|
147840
147922
|
}
|
|
147923
|
+
function launcherWatch(launcher = LAUNCHER_AT_LOAD, parent = PARENT_AT_LOAD) {
|
|
147924
|
+
return () => {
|
|
147925
|
+
if (!Number.isSafeInteger(launcher) || launcher <= 1) return false;
|
|
147926
|
+
if (process.ppid !== parent) return true;
|
|
147927
|
+
try {
|
|
147928
|
+
process.kill(launcher, 0);
|
|
147929
|
+
return false;
|
|
147930
|
+
} catch (error) {
|
|
147931
|
+
return error?.code !== "EPERM";
|
|
147932
|
+
}
|
|
147933
|
+
};
|
|
147934
|
+
}
|
|
147841
147935
|
async function waitForRoom({ stdout = process.stdout, stdin = process.stdin, env = process.env } = {}) {
|
|
147842
147936
|
if (!stdin?.isTTY || typeof stdin.setRawMode !== "function") return "off";
|
|
147843
147937
|
const needs = homeScreenNeeds();
|
|
@@ -147892,11 +147986,12 @@ async function waitForRoom({ stdout = process.stdout, stdin = process.stdin, env
|
|
|
147892
147986
|
}
|
|
147893
147987
|
}
|
|
147894
147988
|
}
|
|
147895
|
-
var MIN_COLUMNS, WIDE_COLUMNS, WIDE_WIDTH, LEFT_X, LEFT_WIDTH, PANEL_X, PANEL_WIDTH, TOP, BAND_MS, BAND_CHANCE, KATAKANA, FONT, AGENT_KEY, HELP_KEY, QUIT_KEY, KEY_HELP, lettersOf, PANELS, ALL_PIECES, KEYS_LINE, FIRST_LINES, SETUP_KEY, RESTORE_KEY, END_KEYS, RESTORE_STEP, HINT, tooSmallLines, COLORS, COLORS_16, RESET2, DATA_SYMBOLS, HOME_SHAPE, FIRST_SHAPE, WIDE, WORD_TOP, WORD_BOTTOM, WORD_WIDTH, ROMAJI, BIG_MARK, SMALL_MARK, LOCKUP_GAP, LOCKUP_WIDTH, Screen, setupLine, randomKatakana, MARK_TONES, PUBLIC_STEP, stackHeight;
|
|
147989
|
+
var MIN_COLUMNS, WIDE_COLUMNS, WIDE_WIDTH, LEFT_X, LEFT_WIDTH, PANEL_X, PANEL_WIDTH, TOP, BAND_MS, BAND_CHANCE, KATAKANA, FONT, AGENT_KEY, HELP_KEY, QUIT_KEY, KEY_HELP, lettersOf, PANELS, ALL_PIECES, KEYS_LINE, FIRST_LINES, SETUP_KEY, RESTORE_KEY, END_KEYS, RESTORE_STEP, HINT, tooSmallLines, COLORS, COLORS_16, RESET2, DATA_SYMBOLS, HOME_SHAPE, FIRST_SHAPE, WIDE, WORD_TOP, WORD_BOTTOM, WORD_WIDTH, ROMAJI, BIG_MARK, SMALL_MARK, LOCKUP_GAP, LOCKUP_WIDTH, Screen, setupLine, randomKatakana, MARK_TONES, PUBLIC_STEP, stackHeight, LAUNCHER_POLL_MS, LAUNCHER_AT_LOAD, PARENT_AT_LOAD;
|
|
147896
147990
|
var init_homeScreen = __esm({
|
|
147897
147991
|
"wallet/src/cli/homeScreen.mjs"() {
|
|
147898
147992
|
"use strict";
|
|
147899
147993
|
init_homeMark();
|
|
147994
|
+
init_homeJob();
|
|
147900
147995
|
MIN_COLUMNS = 80;
|
|
147901
147996
|
WIDE_COLUMNS = 120;
|
|
147902
147997
|
WIDE_WIDTH = 119;
|
|
@@ -148057,6 +148152,9 @@ var init_homeScreen = __esm({
|
|
|
148057
148152
|
"at-most": "your private balance is at its most (5 USDC)."
|
|
148058
148153
|
};
|
|
148059
148154
|
stackHeight = (blocks) => blocks.reduce((sum2, block) => sum2 + block.height, 0) + blocks.length - 1;
|
|
148155
|
+
LAUNCHER_POLL_MS = 250;
|
|
148156
|
+
LAUNCHER_AT_LOAD = /^[0-9]+$/.test(process.env[LAUNCHER_PID_ENV] ?? "") ? Number(process.env[LAUNCHER_PID_ENV]) : process.ppid;
|
|
148157
|
+
PARENT_AT_LOAD = process.ppid;
|
|
148060
148158
|
}
|
|
148061
148159
|
});
|
|
148062
148160
|
|
|
@@ -148767,9 +148865,11 @@ async function runChat({ io, values, deps = {} }) {
|
|
|
148767
148865
|
return typeof deps.balanceLine === "function" ? deps.balanceLine(parts) : `${balanceWords(parts)}.`;
|
|
148768
148866
|
};
|
|
148769
148867
|
const entryOf = (id) => catalog.models.find((entry) => entry.id === id) ?? models.find((entry) => entry.id === id);
|
|
148868
|
+
const fullTokensOf = (id) => defaultMaxTokens(id, liveOf(id) ?? models.find((entry) => entry.id === id));
|
|
148770
148869
|
const tokensFor = (id, messages, limit) => {
|
|
148771
148870
|
try {
|
|
148772
|
-
|
|
148871
|
+
const full = fullTokensOf(id);
|
|
148872
|
+
return BigInt(inference.ceilingAtomic({ model: id, messages, maxTokens: full, liveEntry: liveOf(id) })) <= limit ? full : CHAT_SHORT_TOKENS;
|
|
148773
148873
|
} catch {
|
|
148774
148874
|
return CHAT_SHORT_TOKENS;
|
|
148775
148875
|
}
|
|
@@ -148778,7 +148878,7 @@ async function runChat({ io, values, deps = {} }) {
|
|
|
148778
148878
|
let maxTokens = tokensFor(id, [{ role: "user", content: "x" }], turnLimit());
|
|
148779
148879
|
const messages = SHORT_QUESTION;
|
|
148780
148880
|
const ceilingAtomic2 = BigInt(inference.ceilingAtomic({ model: id, messages, maxTokens, liveEntry: liveOf(id) }));
|
|
148781
|
-
if (ceilingAtomic2 > caps.answer && maxTokens !==
|
|
148881
|
+
if (ceilingAtomic2 > caps.answer && maxTokens !== fullTokensOf(id)) maxTokens = fullTokensOf(id);
|
|
148782
148882
|
return priceOf2({ model: id, messages, maxTokens });
|
|
148783
148883
|
};
|
|
148784
148884
|
const priceText = answerPriceWords;
|
|
@@ -148874,7 +148974,7 @@ async function runChat({ io, values, deps = {} }) {
|
|
|
148874
148974
|
"Private: each answer is paid from your private balance, and the chain does not show which wallet paid. Your words go out only through Tor, so the AI provider and the company that runs the model never see your IP address. They do see your words and the answers.",
|
|
148875
148975
|
// payAndFetch opts.memoryOnly (floatPay.mjs MEMORY ONLY): the payment record holds amounts, ids and hashes only.
|
|
148876
148976
|
"Memory only: the chat writes no chat file and no log, and the wallet writes no copy of the conversation, not even encrypted: its payment records keep only the amounts. The conversation is gone when the chat ends. Let an answer arrive before you end the chat: if the chat ends while an answer is on its way, that answer is gone, and a payment already sent may not come back.",
|
|
148877
|
-
`Cost: each answer pays the AI provider's price for up to ${CHAT_MAX_TOKENS} tokens (${CHAT_SHORT_TOKENS} for a model whose longer answer is above your limit) plus the 0.001 USDC Shinjuku fee, up front, so a short answer costs as much as a long one; what an answer does not use is not refunded. With ${state2.model}, ${lowFirst(costLine2(state2.model))}. ` + (state2.mode === "talk" ? "Each question sends the whole conversation, so a long chat costs more (/new starts again)." : "In this mode each question goes alone, so each costs about the same."),
|
|
148977
|
+
`Cost: each answer pays the AI provider's price for up to ${CHAT_MAX_TOKENS} tokens (${CHAT_SHORT_TOKENS} for a costly model, or one whose longer answer is above your limit) plus the 0.001 USDC Shinjuku fee, up front, so a short answer costs as much as a long one; what an answer does not use is not refunded. With ${state2.model}, ${lowFirst(costLine2(state2.model))}. ` + (state2.mode === "talk" ? "Each question sends the whole conversation, so a long chat costs more (/new starts again)." : "In this mode each question goes alone, so each costs about the same."),
|
|
148878
148978
|
`Mode: ${modeName()}. One question at a time sends each question alone and names each payment; a conversation lets the AI remember the chat and shows the running total. /mode 1 or /mode 2 changes it.`,
|
|
148879
148979
|
caps.answer >= NO_CAP && caps.chat >= NO_CAP ? `Limits: none${capsSourceText(caps)}` : `Limits: ${capWords(caps.answer)} an answer and ${capWords(caps.chat)} for this chat${capsSourceText(caps)}` + (caps.limits.maxSessionAtomic === void 0 ? "" : ` Your limit of ${usdcWords(caps.limits.maxSessionAtomic)} in any 24 hours counts every payment from this wallet.`),
|
|
148880
148980
|
`Commands: /new starts a new conversation, /mode changes the mode, /cost shows what this chat paid, /balance shows your private balance, /model picks another model of the same AI company (/model <id> names one), /provider picks another AI company and then its model (${now.models.length ? `${now.models.length} models served now` : "none served right now"}), /help shows this, /exit (or /quit, Ctrl+D) ends the chat${state2.pending ? ", /retry finishes the unfinished answer" : ""}.`
|
|
@@ -156037,7 +156137,7 @@ async function addFunds(values, deps) {
|
|
|
156037
156137
|
plan,
|
|
156038
156138
|
save: save2,
|
|
156039
156139
|
proxyArgs: proxy.args,
|
|
156040
|
-
childEnv: { ...proxy.env, [PASSPHRASE_ENV]: passphrase2, [RPC_ENV2]: rpcUrl, [STEP_VERBOSE_ENV]: ctx.verbose ? "1" : "0" },
|
|
156140
|
+
childEnv: { ...proxy.env, [PASSPHRASE_ENV]: passphrase2, [RPC_ENV2]: rpcUrl, ...relayOriginsEnv(), [STEP_VERBOSE_ENV]: ctx.verbose ? "1" : "0" },
|
|
156041
156141
|
// A1: a quiet terminal run names no plan id and no stage (funds-status and --verbose do).
|
|
156042
156142
|
say: (stage, text3) => io.err(ctx.quiet ? `add-funds: ${text3.replace(STEP_WORDS, "")}
|
|
156043
156143
|
` : `add-funds ${plan.fundsId} [${stage}] ${text3}
|
|
@@ -158434,16 +158534,21 @@ var CURL_SHORT_FLAGS = Object.freeze({ "-X": "--method", "-H": "--header", "-d":
|
|
|
158434
158534
|
function curlArgs(command, args) {
|
|
158435
158535
|
const known = new Map(command.flags.map((entry) => [entry.name, entry]));
|
|
158436
158536
|
const out = [];
|
|
158537
|
+
let afterJsonData = false;
|
|
158437
158538
|
for (let index = 0; index < args.length; index += 1) {
|
|
158438
158539
|
const token = args[index];
|
|
158439
158540
|
const name = CURL_SHORT_FLAGS[token] ?? token;
|
|
158440
158541
|
if (!name.startsWith("-")) {
|
|
158542
|
+
if (afterJsonData && out.includes("--url")) throw new PublicFailure(CURL_JSON_ARGUMENT_REFUSAL);
|
|
158543
|
+
afterJsonData = false;
|
|
158441
158544
|
out.push("--url", token);
|
|
158442
158545
|
continue;
|
|
158443
158546
|
}
|
|
158547
|
+
afterJsonData = false;
|
|
158444
158548
|
out.push(name);
|
|
158445
158549
|
if (known.has(name) && !known.get(name).boolean && index + 1 < args.length) {
|
|
158446
158550
|
out.push(args[index + 1]);
|
|
158551
|
+
afterJsonData = name === "--data" && /^\s*[[{]/.test(args[index + 1]);
|
|
158447
158552
|
index += 1;
|
|
158448
158553
|
}
|
|
158449
158554
|
}
|
|
@@ -158481,13 +158586,34 @@ function validateCurl(values, env) {
|
|
|
158481
158586
|
}
|
|
158482
158587
|
function curlBody(values) {
|
|
158483
158588
|
const file = values.get("--data-file") ?? (values.get("--data")?.startsWith("@") ? values.get("--data").slice(1) : void 0);
|
|
158484
|
-
|
|
158589
|
+
let body;
|
|
158590
|
+
if (file === void 0) body = values.get("--data");
|
|
158591
|
+
else {
|
|
158592
|
+
try {
|
|
158593
|
+
body = readFileSync(resolve41(file));
|
|
158594
|
+
} catch {
|
|
158595
|
+
throw new PublicFailure("fetch_options_invalid: the body file (--data-file, or -d @file) could not be read; pass a file you can read. Nothing was sent");
|
|
158596
|
+
}
|
|
158597
|
+
}
|
|
158598
|
+
curlJsonBody(values, body, file !== void 0);
|
|
158599
|
+
return body;
|
|
158600
|
+
}
|
|
158601
|
+
function curlJsonBody(values, body, fromFile) {
|
|
158602
|
+
if (body === void 0) return;
|
|
158603
|
+
const type = (values.get("--header") ?? []).find((line) => line.slice(0, line.indexOf(":")).trim().toLowerCase() === "content-type");
|
|
158604
|
+
const typeValue = type === void 0 ? void 0 : type.slice(type.indexOf(":") + 1).trim().toLowerCase();
|
|
158605
|
+
const jsonType = typeValue !== void 0 && /^application\/(?:[\w.+-]+\+)?json\b/.test(typeValue);
|
|
158606
|
+
const text3 = Buffer.isBuffer(body) ? body.toString("utf8") : String(body);
|
|
158607
|
+
const asJson = fromFile ? jsonType : typeValue === void 0 ? /^\s*[[{]/.test(text3) : jsonType;
|
|
158608
|
+
if (!asJson) return;
|
|
158485
158609
|
try {
|
|
158486
|
-
|
|
158610
|
+
JSON.parse(text3.replace(/^/, ""));
|
|
158611
|
+
return;
|
|
158487
158612
|
} catch {
|
|
158488
|
-
throw new PublicFailure("fetch_options_invalid: the body file (--data-file, or -d @file) could not be read; pass a file you can read. Nothing was sent");
|
|
158489
158613
|
}
|
|
158614
|
+
throw new PublicFailure(fromFile ? "fetch_options_invalid: the body file is not valid JSON, so it was not sent; nothing was paid. Fix the file (every name and text in double quotes) and run the same command again" : CURL_JSON_ARGUMENT_REFUSAL);
|
|
158490
158615
|
}
|
|
158616
|
+
var CURL_JSON_ARGUMENT_REFUSAL = "fetch_options_invalid: the body is not valid JSON, so it was not sent; nothing was paid. PowerShell removes the double quotes inside a JSON argument: save the JSON in a file and pass it as -d @<file> (or --data-file <file>), then run the command again";
|
|
158491
158617
|
function curlFailure(error) {
|
|
158492
158618
|
if (error instanceof SpendRefusalError && knownErrorCode(error.error)) {
|
|
158493
158619
|
return new PublicFailure(`${error.error}: ${error.detail}`, { cause: error });
|
|
@@ -160264,7 +160390,7 @@ function startKeepWarm(options, env = process.env) {
|
|
|
160264
160390
|
...proxy.env,
|
|
160265
160391
|
[PASSPHRASE_ENV3]: options.passphrase,
|
|
160266
160392
|
[KEEP_WARM_PARENT_ENV]: "1",
|
|
160267
|
-
...options.rpcUrl ? { [RPC_ENV3]: options.rpcUrl } : {}
|
|
160393
|
+
...options.rpcUrl ? { [RPC_ENV3]: options.rpcUrl, ...relayOriginsEnv() } : {}
|
|
160268
160394
|
},
|
|
160269
160395
|
stdio: ["pipe", "ignore", "pipe"],
|
|
160270
160396
|
windowsHide: true
|