shinjuku-shielded 0.3.185 → 0.3.186
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 +214 -15
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.186. 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.186 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.186 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.186", "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.186", "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": "80d2ed100a8e4a1f0c3926c4572c20f71ed5c333ff510dd0e291065480fe2d98",
|
|
5
|
+
"bytes": 9360488,
|
|
6
|
+
"sourceCommit": "cb04124afb5e7deb6c6e7132dcb0175a1bc0eb2c",
|
|
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-06T17:
|
|
1041
|
+
"publishedAt": "2026-11-06T17:55:56.110Z"
|
|
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.186",
|
|
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": "80d2ed10",
|
|
7
|
+
"shinjukuSha256": "80d2ed100a8e4a1f0c3926c4572c20f71ed5c333ff510dd0e291065480fe2d98",
|
|
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
|
@@ -48786,6 +48786,15 @@ function torOwnCircuitInit(lane, init = {}) {
|
|
|
48786
48786
|
const made = torLaneInit(lane, init);
|
|
48787
48787
|
return made !== init && made?.dispatcher !== void 0 ? made : void 0;
|
|
48788
48788
|
}
|
|
48789
|
+
function freshTorCircuitProxy() {
|
|
48790
|
+
if (!inTorRun() || runEnded()) return void 0;
|
|
48791
|
+
try {
|
|
48792
|
+
if (globalThis[GLOBAL_DISPATCHER4]?.constructor?.name !== "EnvHttpProxyAgent") return void 0;
|
|
48793
|
+
return withRunTag(`http://${new URL(process.env[MARK].split(" ")[1]).host}`);
|
|
48794
|
+
} catch {
|
|
48795
|
+
return void 0;
|
|
48796
|
+
}
|
|
48797
|
+
}
|
|
48789
48798
|
function onCurrentCircuit(init) {
|
|
48790
48799
|
const lane = laneOfDispatcher.get(init?.dispatcher);
|
|
48791
48800
|
return lane === void 0 || laneDispatchers.get(lane) === init.dispatcher ? init : torLaneInit(lane, init);
|
|
@@ -104928,7 +104937,7 @@ function floatOutcomeWords(code2, error, t) {
|
|
|
104928
104937
|
const why = code2 === "p03_float_paid_finishing_retry_same_request" ? `Shinjuku is still signing the transfer to ${p.the}` : error?.transferLanded === true ? `Shinjuku's transfer to ${p.the} landed (${p.the} has the payment), and ${answer}` : `${answer}. Not known yet whether ${p.the} takes it`;
|
|
104929
104938
|
return [
|
|
104930
104939
|
code2,
|
|
104931
|
-
`PAID ${totalText(error)} to Shinjuku (${t.privateLeg}); ${why}`,
|
|
104940
|
+
`PAID ${totalText(error)} to Shinjuku (${t.privateLeg}); ${why}${stallResentWords(p, error)}`,
|
|
104932
104941
|
`${t.again}: it resends the same payment and never pays twice`
|
|
104933
104942
|
];
|
|
104934
104943
|
}
|
|
@@ -104998,7 +105007,7 @@ function floatOutcomeWords(code2, error, t) {
|
|
|
104998
105007
|
case "p03_float_seller_unanswered_paid_retry_same_request":
|
|
104999
105008
|
return [
|
|
105000
105009
|
code2,
|
|
105001
|
-
`PAID ${totalText(error)}: the transfer to ${p.the} landed${withTransaction(error)}, but ${p.the} did not answer` + (typeof error?.httpStatus === "number" ? ` (it answered HTTP ${error.httpStatus}${typeof error?.sellerReason === "string" ? `: ${JSON.stringify(error.sellerReason)}` : ""})` : ""),
|
|
105010
|
+
`PAID ${totalText(error)}: the transfer to ${p.the} landed${withTransaction(error)}, but ${p.the} did not answer` + (typeof error?.httpStatus === "number" ? ` (it answered HTTP ${error.httpStatus}${typeof error?.sellerReason === "string" ? `: ${JSON.stringify(error.sellerReason)}` : ""})` : "") + stallResentWords(p, error),
|
|
105002
105011
|
`${t.again}: it resends the same proof of payment and never pays twice`
|
|
105003
105012
|
];
|
|
105004
105013
|
case "p03_float_seller_kept_payment": {
|
|
@@ -105098,6 +105107,12 @@ function floatOutcomeWords(code2, error, t) {
|
|
|
105098
105107
|
return void 0;
|
|
105099
105108
|
}
|
|
105100
105109
|
}
|
|
105110
|
+
function stallResentWords(p, error) {
|
|
105111
|
+
return error?.stallResent === true ? `; the Tor connection to ${p?.the ?? "the seller"} stalled, so the wallet sent this same payment once more on a new Tor route: it is still one payment, not a second one` : "";
|
|
105112
|
+
}
|
|
105113
|
+
function stallResentLine(payee = "the seller") {
|
|
105114
|
+
return `The Tor connection to ${payee} stalled, so the wallet sent this same payment once more on a new Tor route: it is still one payment, not a second one.`;
|
|
105115
|
+
}
|
|
105101
105116
|
var ATOMIC4, TRANSFER_DEAD_WORDS, payeeOf, floatSellerCanBeFixed, withoutProviderText, floatSeller4xx, answeredInstead, floatStillSettling, floatChargeTooLate, amountText, withTransaction, PAID_SELLER_FAILED_CODE, stillWants, AI_SERVER_WRONG, QUOTE_REFUSED_WHY;
|
|
105102
105117
|
var init_floatWords = __esm({
|
|
105103
105118
|
"wallet/src/pay/floatWords.mjs"() {
|
|
@@ -106112,6 +106127,138 @@ function sellerAnswerInit(url, init, ms) {
|
|
|
106112
106127
|
if (target() === void 0) return init;
|
|
106113
106128
|
return { ...init, dispatcher: { dispatch: (options, handler) => target().dispatch({ ...options, headersTimeout: ms, bodyTimeout: ms }, handler) } };
|
|
106114
106129
|
}
|
|
106130
|
+
async function sendWatchingStall(fetchImpl, url, init, waitMs, { mark = () => {
|
|
106131
|
+
}, onResend = () => {
|
|
106132
|
+
}, resentBefore = false } = {}) {
|
|
106133
|
+
const global2 = globalThis[GLOBAL_DISPATCHER5];
|
|
106134
|
+
const proxy = process.env.HTTPS_PROXY;
|
|
106135
|
+
const watched = !resentBefore && inTorRun() && init.dispatcher === void 0 && routeDispatcherOf(url) === void 0 && global2?.constructor?.name === "EnvHttpProxyAgent" && typeof proxy === "string" && proxy !== "";
|
|
106136
|
+
if (!watched) return { response: await fetchImpl(url, sellerAnswerInit(url, init, waitMs)), stallResent: false };
|
|
106137
|
+
const sameCircuit = () => {
|
|
106138
|
+
try {
|
|
106139
|
+
return proxyDispatcher(global2.constructor, proxy);
|
|
106140
|
+
} catch {
|
|
106141
|
+
return void 0;
|
|
106142
|
+
}
|
|
106143
|
+
};
|
|
106144
|
+
const first = new AbortController();
|
|
106145
|
+
let ended2 = false;
|
|
106146
|
+
let timer;
|
|
106147
|
+
let checkStop;
|
|
106148
|
+
const stalled = new Promise((resolve43) => {
|
|
106149
|
+
let misses = 0;
|
|
106150
|
+
const check = async () => {
|
|
106151
|
+
const startedAtMs = Date.now();
|
|
106152
|
+
mark("seller-stall-check");
|
|
106153
|
+
checkStop = new AbortController();
|
|
106154
|
+
const dispatcher = sameCircuit();
|
|
106155
|
+
let alive2 = false;
|
|
106156
|
+
try {
|
|
106157
|
+
if (dispatcher === void 0) throw new Error("no dispatcher");
|
|
106158
|
+
const answer = await fetchImpl(new URL(url).origin, {
|
|
106159
|
+
method: "HEAD",
|
|
106160
|
+
redirect: "manual",
|
|
106161
|
+
dispatcher,
|
|
106162
|
+
signal: AbortSignal.any([AbortSignal.timeout(SELLER_STALL_CHECK_TIMEOUT_MS), checkStop.signal, ...init.signal ? [init.signal] : []])
|
|
106163
|
+
});
|
|
106164
|
+
alive2 = true;
|
|
106165
|
+
answer.body?.cancel?.().catch?.(() => {
|
|
106166
|
+
});
|
|
106167
|
+
} catch {
|
|
106168
|
+
alive2 = false;
|
|
106169
|
+
}
|
|
106170
|
+
dispatcher?.destroy().catch(() => {
|
|
106171
|
+
});
|
|
106172
|
+
if (ended2) return;
|
|
106173
|
+
misses = alive2 ? 0 : misses + 1;
|
|
106174
|
+
mark("seller-stall-check-done", alive2 ? "answered" : `missed_${misses}`);
|
|
106175
|
+
if (misses >= SELLER_STALL_MISSES) {
|
|
106176
|
+
resolve43(true);
|
|
106177
|
+
return;
|
|
106178
|
+
}
|
|
106179
|
+
timer = setTimeout(check, Math.max(0, startedAtMs + SELLER_STALL_CHECK_EVERY_MS - Date.now()));
|
|
106180
|
+
};
|
|
106181
|
+
timer = setTimeout(check, SELLER_STALL_CHECK_AFTER_MS);
|
|
106182
|
+
});
|
|
106183
|
+
const firstSend = fetchImpl(url, sellerAnswerInit(url, { ...init, signal: AbortSignal.any([...init.signal ? [init.signal] : [], first.signal]) }, waitMs)).then((response) => ({ response }), (error) => ({ error }));
|
|
106184
|
+
let outcome;
|
|
106185
|
+
try {
|
|
106186
|
+
outcome = await Promise.race([firstSend, stalled.then(() => ({ stalled: true }))]);
|
|
106187
|
+
} finally {
|
|
106188
|
+
ended2 = true;
|
|
106189
|
+
clearTimeout(timer);
|
|
106190
|
+
checkStop?.abort();
|
|
106191
|
+
}
|
|
106192
|
+
if (outcome.stalled !== true) {
|
|
106193
|
+
if (outcome.error !== void 0) throw outcome.error;
|
|
106194
|
+
return { response: outcome.response, stallResent: false };
|
|
106195
|
+
}
|
|
106196
|
+
const replacementProxy = freshTorCircuitProxy();
|
|
106197
|
+
let fresh;
|
|
106198
|
+
try {
|
|
106199
|
+
fresh = replacementProxy === void 0 ? void 0 : proxyDispatcher(global2.constructor, replacementProxy);
|
|
106200
|
+
} catch {
|
|
106201
|
+
fresh = void 0;
|
|
106202
|
+
}
|
|
106203
|
+
if (fresh === void 0) {
|
|
106204
|
+
const kept3 = await firstSend;
|
|
106205
|
+
if (kept3.error !== void 0) throw kept3.error;
|
|
106206
|
+
return { response: kept3.response, stallResent: false };
|
|
106207
|
+
}
|
|
106208
|
+
onResend(replacementProxy);
|
|
106209
|
+
mark("seller-stall-resend");
|
|
106210
|
+
const second = new AbortController();
|
|
106211
|
+
const resend = fetchImpl(url, sellerAnswerInit(url, {
|
|
106212
|
+
...init,
|
|
106213
|
+
dispatcher: fresh,
|
|
106214
|
+
signal: AbortSignal.any([...init.signal ? [init.signal] : [], second.signal])
|
|
106215
|
+
}, waitMs)).then((response) => ({ response, from: "resend" }), (error) => ({ error, from: "resend" }));
|
|
106216
|
+
const whole = (side) => side.then((one) => one.error !== void 0 ? one : wholeAnswer(one.response).then((response) => ({ response, from: one.from }), (error) => ({ error, from: one.from })));
|
|
106217
|
+
const firstWhole = whole(firstSend.then((one) => ({ ...one, from: "first" })));
|
|
106218
|
+
const resendWhole = whole(resend);
|
|
106219
|
+
const ok = (one) => one.response !== void 0 && one.response.status >= 200 && one.response.status <= 299;
|
|
106220
|
+
try {
|
|
106221
|
+
const earlier = await Promise.race([firstWhole, resendWhole]);
|
|
106222
|
+
let winner = earlier;
|
|
106223
|
+
if (!ok(earlier)) {
|
|
106224
|
+
const other = await (earlier.from === "first" ? resendWhole : firstWhole);
|
|
106225
|
+
winner = ok(other) ? other : earlier.response !== void 0 ? earlier : other.response !== void 0 ? other : void 0;
|
|
106226
|
+
if (winner === void 0) {
|
|
106227
|
+
if (init.signal?.aborted) throw init.signal.reason;
|
|
106228
|
+
throw (earlier.from === "resend" ? earlier : other).error;
|
|
106229
|
+
}
|
|
106230
|
+
}
|
|
106231
|
+
(winner.from === "first" ? second : first).abort();
|
|
106232
|
+
mark("seller-stall-answer", winner.from);
|
|
106233
|
+
return { response: winner.response, stallResent: true, replacementProxy };
|
|
106234
|
+
} finally {
|
|
106235
|
+
fresh.close().catch(() => {
|
|
106236
|
+
});
|
|
106237
|
+
}
|
|
106238
|
+
}
|
|
106239
|
+
async function wholeAnswer(response) {
|
|
106240
|
+
const nullBody = [101, 103, 204, 205, 304].includes(response.status);
|
|
106241
|
+
if (!response.body || nullBody) {
|
|
106242
|
+
await response.body?.cancel?.().catch?.(() => {
|
|
106243
|
+
});
|
|
106244
|
+
return new Response(null, { status: response.status, statusText: response.statusText, headers: response.headers });
|
|
106245
|
+
}
|
|
106246
|
+
const reader = response.body.getReader();
|
|
106247
|
+
const chunks = [];
|
|
106248
|
+
let size = 0;
|
|
106249
|
+
while (size <= RESULT_LIMIT_BYTES) {
|
|
106250
|
+
const { done, value: value2 } = await reader.read();
|
|
106251
|
+
if (done) break;
|
|
106252
|
+
size += value2.byteLength;
|
|
106253
|
+
chunks.push(Buffer.from(value2));
|
|
106254
|
+
}
|
|
106255
|
+
if (size > RESULT_LIMIT_BYTES) await reader.cancel().catch(() => {
|
|
106256
|
+
});
|
|
106257
|
+
return new Response(
|
|
106258
|
+
Buffer.concat(chunks).subarray(0, RESULT_LIMIT_BYTES + 1),
|
|
106259
|
+
{ status: response.status, statusText: response.statusText, headers: response.headers }
|
|
106260
|
+
);
|
|
106261
|
+
}
|
|
106115
106262
|
async function sellerRefusalText(response) {
|
|
106116
106263
|
let text3 = "";
|
|
106117
106264
|
let reader;
|
|
@@ -106167,9 +106314,10 @@ function x402HeaderText(response, name, field4) {
|
|
|
106167
106314
|
const value2 = x402Header(response, name)?.[field4];
|
|
106168
106315
|
return typeof value2 === "string" && value2.trim() !== "" ? value2 : void 0;
|
|
106169
106316
|
}
|
|
106170
|
-
function newConnectionDispatcher() {
|
|
106317
|
+
function newConnectionDispatcher(stallProxy) {
|
|
106171
106318
|
try {
|
|
106172
106319
|
const Dispatcher = globalThis[GLOBAL_DISPATCHER5]?.constructor;
|
|
106320
|
+
if (stallProxy !== void 0) return Dispatcher?.name === "EnvHttpProxyAgent" ? proxyDispatcher(Dispatcher, stallProxy) : void 0;
|
|
106173
106321
|
if (Dispatcher?.name === "Agent") return new Dispatcher();
|
|
106174
106322
|
const proxy = String(process.env.SHINJUKU_WALLET_PROXIED ?? "").startsWith("tor ") ? process.env.HTTPS_PROXY : void 0;
|
|
106175
106323
|
return Dispatcher?.name === "EnvHttpProxyAgent" && proxy ? proxyDispatcher(Dispatcher, proxy) : void 0;
|
|
@@ -107518,6 +107666,10 @@ async function payViaFloat({
|
|
|
107518
107666
|
for (const dispatcher of resendDispatchers) dispatcher.close().catch(() => {
|
|
107519
107667
|
});
|
|
107520
107668
|
}
|
|
107669
|
+
function stallResent() {
|
|
107670
|
+
record = { ...record, sellerStallResent: true };
|
|
107671
|
+
store.writeWal(walName2, record);
|
|
107672
|
+
}
|
|
107521
107673
|
function unanswered2(error) {
|
|
107522
107674
|
if (wasKept) keptAgain();
|
|
107523
107675
|
const verdict = watch.verdict();
|
|
@@ -107535,6 +107687,7 @@ async function payViaFloat({
|
|
|
107535
107687
|
refundPendingAnswer(record);
|
|
107536
107688
|
}
|
|
107537
107689
|
if (verdict?.state === "cancelled") byVerdict(verdict, {}, { cause: error });
|
|
107690
|
+
const resentNow = record.sellerStallResent === true ? { stallResent: true } : {};
|
|
107538
107691
|
if (verdict?.state === "final") {
|
|
107539
107692
|
fail22("p03_float_seller_unanswered_paid_retry_same_request", {
|
|
107540
107693
|
cause: error,
|
|
@@ -107542,7 +107695,8 @@ async function payViaFloat({
|
|
|
107542
107695
|
...verdict.transaction ? { transaction: verdict.transaction } : {},
|
|
107543
107696
|
paidAtomic: record.paidAtomic,
|
|
107544
107697
|
priceAtomic: record.priceAtomic,
|
|
107545
|
-
feeAtomic: record.feeAtomic
|
|
107698
|
+
feeAtomic: record.feeAtomic,
|
|
107699
|
+
...resentNow
|
|
107546
107700
|
});
|
|
107547
107701
|
}
|
|
107548
107702
|
fail22("p03_float_seller_unanswered_retry_same_request", {
|
|
@@ -107551,7 +107705,8 @@ async function payViaFloat({
|
|
|
107551
107705
|
paidAtomic: record.paidAtomic,
|
|
107552
107706
|
priceAtomic: record.priceAtomic,
|
|
107553
107707
|
feeAtomic: record.feeAtomic,
|
|
107554
|
-
...verdict?.state === "landed" ? { transferLanded: true } : {}
|
|
107708
|
+
...verdict?.state === "landed" ? { transferLanded: true } : {},
|
|
107709
|
+
...resentNow
|
|
107555
107710
|
});
|
|
107556
107711
|
}
|
|
107557
107712
|
async function finalAfterLanded() {
|
|
@@ -107578,6 +107733,7 @@ async function payViaFloat({
|
|
|
107578
107733
|
let resendUntilMs;
|
|
107579
107734
|
let answeredAtMs;
|
|
107580
107735
|
let dispatcher;
|
|
107736
|
+
let stallProxy;
|
|
107581
107737
|
const waitMs = sellerWaitMs(record);
|
|
107582
107738
|
const sellerTimeout = AbortSignal.timeout(waitMs);
|
|
107583
107739
|
const stopResends = () => Date.now() > resendUntilMs || ["landed", "dead", "final", "cancelled"].includes(watch.verdict()?.state);
|
|
@@ -107591,7 +107747,16 @@ async function payViaFloat({
|
|
|
107591
107747
|
};
|
|
107592
107748
|
const socketWatch = resend === 0 ? watchRequestSocket(record.url) : void 0;
|
|
107593
107749
|
try {
|
|
107594
|
-
response = await
|
|
107750
|
+
({ response } = await sendWatchingStall(
|
|
107751
|
+
fetchImpl,
|
|
107752
|
+
record.url,
|
|
107753
|
+
dispatcher === void 0 ? keepAliveInit(init) : { ...init, dispatcher },
|
|
107754
|
+
waitMs,
|
|
107755
|
+
{ mark, resentBefore: record.sellerStallResent === true, onResend: (proxy) => {
|
|
107756
|
+
stallProxy ??= proxy;
|
|
107757
|
+
stallResent();
|
|
107758
|
+
} }
|
|
107759
|
+
));
|
|
107595
107760
|
} catch (error) {
|
|
107596
107761
|
unanswered2(error);
|
|
107597
107762
|
} finally {
|
|
@@ -107604,7 +107769,7 @@ async function payViaFloat({
|
|
|
107604
107769
|
mark(resend === 0 ? "seller-answered" : `seller-answered-resend-${resend}`);
|
|
107605
107770
|
resendUntilMs ??= Date.now() + FEE_PAYER_RESEND_MS;
|
|
107606
107771
|
if (wasKept || resend >= FEE_PAYER_RESENDS || stopResends() || !(feePayerRotated(response, accepted) || feePayerNotManaged(response))) break;
|
|
107607
|
-
dispatcher = newConnectionDispatcher();
|
|
107772
|
+
dispatcher = newConnectionDispatcher(stallProxy);
|
|
107608
107773
|
if (dispatcher === void 0) break;
|
|
107609
107774
|
resendDispatchers.push(dispatcher);
|
|
107610
107775
|
await drainBody(response);
|
|
@@ -107877,6 +108042,8 @@ async function selfBroadcastLeg({ store, walName: walName2, record, sendRequest,
|
|
|
107877
108042
|
fail22("p03_float_seller_kept_payment", landed);
|
|
107878
108043
|
}
|
|
107879
108044
|
let unanswered2 = 0;
|
|
108045
|
+
let stallProxy;
|
|
108046
|
+
let stallDeadline;
|
|
107880
108047
|
const resendUnanswered = async () => {
|
|
107881
108048
|
const wait2 = SELF_BROADCAST_UNANSWERED_RESEND_MS[unanswered2];
|
|
107882
108049
|
if (wait2 === void 0 || Date.now() + wait2 >= record.selfBroadcast.expiresAtMs) return false;
|
|
@@ -107892,22 +108059,38 @@ async function selfBroadcastLeg({ store, walName: walName2, record, sendRequest,
|
|
|
107892
108059
|
}
|
|
107893
108060
|
mark("seller-sent");
|
|
107894
108061
|
let response;
|
|
108062
|
+
const onStallTag = stallProxy === void 0 ? void 0 : newConnectionDispatcher(stallProxy);
|
|
108063
|
+
const sendDeadline = stallDeadline ?? AbortSignal.timeout(sellerWaitMs(record));
|
|
107895
108064
|
try {
|
|
107896
|
-
response = await fetchImpl
|
|
108065
|
+
({ response } = await sendWatchingStall(fetchImpl, record.url, keepAliveInit({
|
|
107897
108066
|
method: sendRequest.method,
|
|
107898
108067
|
headers: { ...Object.fromEntries(sendRequest.headers), "PAYMENT-SIGNATURE": header },
|
|
107899
108068
|
...sendRequest.method === "POST" ? { body: Buffer.from(sendRequest.bodyBase64, "base64") } : {},
|
|
107900
108069
|
redirect: "error",
|
|
107901
|
-
signal:
|
|
107902
|
-
|
|
108070
|
+
signal: sendDeadline,
|
|
108071
|
+
...onStallTag !== void 0 ? { dispatcher: onStallTag } : {}
|
|
108072
|
+
}), sellerWaitMs(record), { mark, resentBefore: record.sellerStallResent === true, onResend: (proxy) => {
|
|
108073
|
+
stallProxy ??= proxy;
|
|
108074
|
+
stallDeadline ??= sendDeadline;
|
|
108075
|
+
record = { ...record, sellerStallResent: true };
|
|
108076
|
+
store.writeWal(walName2, record);
|
|
108077
|
+
} }));
|
|
107903
108078
|
} catch (error) {
|
|
108079
|
+
onStallTag?.close().catch(() => {
|
|
108080
|
+
});
|
|
107904
108081
|
const timedOut = error?.name === "TimeoutError" || error?.cause?.name === "TimeoutError";
|
|
107905
108082
|
if (!timedOut && !proxyRefusedConnection(error) && await resendUnanswered()) {
|
|
107906
108083
|
attempt -= 1;
|
|
107907
108084
|
continue;
|
|
107908
108085
|
}
|
|
107909
|
-
fail22("p03_float_seller_unanswered_paid_retry_same_request", {
|
|
108086
|
+
fail22("p03_float_seller_unanswered_paid_retry_same_request", {
|
|
108087
|
+
cause: error,
|
|
108088
|
+
...landed,
|
|
108089
|
+
...record.sellerStallResent === true ? { stallResent: true } : {}
|
|
108090
|
+
});
|
|
107910
108091
|
}
|
|
108092
|
+
onStallTag?.close().catch(() => {
|
|
108093
|
+
});
|
|
107911
108094
|
mark("seller-answered");
|
|
107912
108095
|
if (response.ok && response.status !== 202) {
|
|
107913
108096
|
let settled;
|
|
@@ -108019,6 +108202,9 @@ function paidResult(record, replayed) {
|
|
|
108019
108202
|
replayed,
|
|
108020
108203
|
scheme: "exact",
|
|
108021
108204
|
status: record.status ?? 200,
|
|
108205
|
+
// AB32: the paid request went once more on a new Tor circuit after a stall (sendWatchingStall); every paid line says
|
|
108206
|
+
// it is still one payment (Codex round 1 on aa3927fc item 3).
|
|
108207
|
+
...!replayed && record.sellerStallResent === true ? { stallResent: true } : {},
|
|
108022
108208
|
// A record written before headers were kept has none.
|
|
108023
108209
|
sellerHeaders: Array.isArray(record.sellerHeaders) ? record.sellerHeaders : [],
|
|
108024
108210
|
receipt: { ...record.receipt, float: { floatId: record.floatId, settleTransaction: record.floatSettleTransaction ?? null } },
|
|
@@ -108030,7 +108216,7 @@ function paidResult(record, replayed) {
|
|
|
108030
108216
|
float: { floatId: record.floatId }
|
|
108031
108217
|
};
|
|
108032
108218
|
}
|
|
108033
|
-
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;
|
|
108219
|
+
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, SELLER_STALL_CHECK_AFTER_MS, SELLER_STALL_CHECK_EVERY_MS, SELLER_STALL_CHECK_TIMEOUT_MS, SELLER_STALL_MISSES, RESULT_LIMIT_BYTES, 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;
|
|
108034
108220
|
var init_floatPay = __esm({
|
|
108035
108221
|
"wallet/src/pay/floatPay.mjs"() {
|
|
108036
108222
|
"use strict";
|
|
@@ -108078,6 +108264,11 @@ var init_floatPay = __esm({
|
|
|
108078
108264
|
FINISHING_LIMIT_MS = 6e4;
|
|
108079
108265
|
SELLER_TIMEOUT_MS = 12e4;
|
|
108080
108266
|
SELLER_TIMEOUT_ABSURD_SECONDS = 86400;
|
|
108267
|
+
SELLER_STALL_CHECK_AFTER_MS = 3e4;
|
|
108268
|
+
SELLER_STALL_CHECK_EVERY_MS = 3e4;
|
|
108269
|
+
SELLER_STALL_CHECK_TIMEOUT_MS = 15e3;
|
|
108270
|
+
SELLER_STALL_MISSES = 2;
|
|
108271
|
+
RESULT_LIMIT_BYTES = 1024 * 1024;
|
|
108081
108272
|
FLOAT_STATUS_START_MS = 45e3;
|
|
108082
108273
|
FLOAT_STATUS_POLL_MS = 5e3;
|
|
108083
108274
|
FLOAT_STATUS_TIMEOUT_MS = 5e3;
|
|
@@ -114454,7 +114645,9 @@ async function paidCall({ session, target, method, headers, body, cap, maxPrice,
|
|
|
114454
114645
|
amountAtomic: amountAtomic ?? null,
|
|
114455
114646
|
requestId,
|
|
114456
114647
|
replayed: result.replayed === true,
|
|
114457
|
-
receiptFinality: result.receiptFinality ?? null
|
|
114648
|
+
receiptFinality: result.receiptFinality ?? null,
|
|
114649
|
+
// AB32 (pay/floatPay.mjs sendWatchingStall): the paid request went once more on a new Tor circuit; still one payment.
|
|
114650
|
+
...result.stallResent === true ? { stallResent: true } : {}
|
|
114458
114651
|
};
|
|
114459
114652
|
const status = Number.isInteger(result.status) && result.status >= 200 && result.status <= 299 ? result.status : 200;
|
|
114460
114653
|
return new Response(
|
|
@@ -134744,7 +134937,7 @@ ${canonical5}`;
|
|
|
134744
134937
|
...floatPaid ? { via: "shinjuku", shinjukuTransaction } : {},
|
|
134745
134938
|
...balanceAnswer(one),
|
|
134746
134939
|
...notices,
|
|
134747
|
-
next: (unpaid ? "nothing was paid: this request id's payment never landed (the pool's public history proves it), and the answer it got came back again; nothing new was paid. Tell the user nothing was paid for it" : receipt.replayed === true ? "this request id was already paid: the stored receipt came back and nothing new was paid" : floatPaid ? floatPaidNext({ transaction: unpaid ? null : transaction, shinjukuTransaction }) : "paid; tell the user what was paid (amountAtomic, transaction). wallet_receipts lists this payment, wallet_balance shows the new balance") + noticesStep(notices)
|
|
134940
|
+
next: (unpaid ? "nothing was paid: this request id's payment never landed (the pool's public history proves it), and the answer it got came back again; nothing new was paid. Tell the user nothing was paid for it" : receipt.replayed === true ? "this request id was already paid: the stored receipt came back and nothing new was paid" : floatPaid ? floatPaidNext({ transaction: unpaid ? null : transaction, shinjukuTransaction }) + (receipt.stallResent === true || float?.sellerStallResent === true ? `. Tell the user too: ${stallResentLine()}` : "") : "paid; tell the user what was paid (amountAtomic, transaction). wallet_receipts lists this payment, wallet_balance shows the new balance") + noticesStep(notices)
|
|
134748
134941
|
}, "pay_for_service")
|
|
134749
134942
|
}));
|
|
134750
134943
|
}
|
|
@@ -135056,6 +135249,8 @@ ${canonical5}`;
|
|
|
135056
135249
|
...!ambiguous && floatSellerCanBeFixed(error) ? { sellerFixable: true } : {},
|
|
135057
135250
|
...error?.transferLanded === true ? { transferLanded: true } : {},
|
|
135058
135251
|
...error?.resent === true ? { resent: true } : {},
|
|
135252
|
+
// AB32: this payment went once more on a new Tor circuit after a stall (floatPay.mjs sendWatchingStall).
|
|
135253
|
+
...error?.stallResent === true ? { stallResent: true } : {},
|
|
135059
135254
|
...error?.pruned === true ? { pruned: true } : {},
|
|
135060
135255
|
...typeof error?.floatCode === "string" ? { floatCode: error.floatCode } : {},
|
|
135061
135256
|
// AB164: the seller's own code beside its error after it took the payment (floatWords.mjs PAID_SELLER_FAILED_CODE).
|
|
@@ -149470,6 +149665,7 @@ The next question uses it${state2.mode === "talk" ? ", with the conversation so
|
|
|
149470
149665
|
else if (plainPaid && reader?.terminal && unsureAtomic() === 0n && !dayRoom2) {
|
|
149471
149666
|
if (cut2) say2(cut2.trim());
|
|
149472
149667
|
} else say2(`${cut2}${paidText}. ${tail}`);
|
|
149668
|
+
if (plainPaid && result.receipt?.stallResent === true) say2(stallResentLine("the AI provider"));
|
|
149473
149669
|
if (state2.mode === "each" && !state2.eachHinted) {
|
|
149474
149670
|
state2.eachHinted = true;
|
|
149475
149671
|
say2(paint([["Each question goes alone: the AI does not see your earlier questions. For follow-ups, /mode 2 picks a conversation.", "mute"]], color));
|
|
@@ -159225,7 +159421,8 @@ async function curlOutput(response, values, deps, requestId) {
|
|
|
159225
159421
|
const person = values.get(PERSON_LINK);
|
|
159226
159422
|
const said = (text4) => person ? personWords(text4, { homeJob: person.homeJob }) : text4;
|
|
159227
159423
|
io.err(said(unpaid ? `the same answer as before; nothing was paid: the earlier payment for request-id ${requestId} never went through
|
|
159228
|
-
` : paid ? `paid ${usdcOr(paid.amountAtomic)} from your private balance${route} (the chain does not show who paid); request-id ${requestId}${paid.replayed ? " (replayed: this request was paid before; nothing new was paid)" : ""}
|
|
159424
|
+
` : paid ? `paid ${usdcOr(paid.amountAtomic)} from your private balance${route} (the chain does not show who paid); request-id ${requestId}${paid.replayed ? " (replayed: this request was paid before; nothing new was paid)" : ""}${paid.stallResent === true && !paid.replayed ? `
|
|
159425
|
+
${stallResentLine()}` : ""}
|
|
159229
159426
|
` : `free (no 402): HTTP ${response.status}; nothing was paid
|
|
159230
159427
|
`));
|
|
159231
159428
|
if (values.has("--out")) {
|
|
@@ -159672,6 +159869,8 @@ function inferOutput(result, { values, io, model: model2, quiet, requestId, held
|
|
|
159672
159869
|
`);
|
|
159673
159870
|
if (plainPaid) {
|
|
159674
159871
|
io.err(`${paidLine(BigInt(result.paidAtomic), { color: brandColor(process.stderr, process.env) })}${quiet ? "" : ` request-id ${result.requestId ?? requestId}`}${stopped}
|
|
159872
|
+
`);
|
|
159873
|
+
if (result.receipt?.stallResent === true) io.err(`${stallResentLine("the AI provider")}
|
|
159675
159874
|
`);
|
|
159676
159875
|
}
|
|
159677
159876
|
}
|