shinjuku-shield 0.3.113 → 0.3.115
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 +477 -232
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.115. 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.115
|
|
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.115 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.115 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.115", "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": "148b3f5279bf4b0914aa076c617b9fd51956480a57058dfee4492c208fd72e7a",
|
|
5
|
+
"bytes": 8348544,
|
|
6
|
+
"sourceCommit": "8b4f9050d3ae61ecdd0082ee931761cc2b812f62",
|
|
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-27T18:51:07.036Z"
|
|
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.115",
|
|
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": "148b3f52",
|
|
7
|
+
"shinjukuSha256": "148b3f5279bf4b0914aa076c617b9fd51956480a57058dfee4492c208fd72e7a",
|
|
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
|
@@ -67216,7 +67216,7 @@ var init_errorCodes = __esm({
|
|
|
67216
67216
|
"float_paid_finishing",
|
|
67217
67217
|
"refund_pending",
|
|
67218
67218
|
// Float record field values, not errors (floatPay.mjs): broadcastRefusal "answer_invalid" (leg 1's answer could not be
|
|
67219
|
-
// used) and the refund outcomes returnArrivedFloatRefundBudgets writes and
|
|
67219
|
+
// used) and the refund outcomes returnArrivedFloatRefundBudgets writes and readFloatRefundOutcomes returns.
|
|
67220
67220
|
"answer_invalid",
|
|
67221
67221
|
"refund_arrived",
|
|
67222
67222
|
"refund_not_seen",
|
|
@@ -102584,7 +102584,14 @@ function returnArrivedFloatRefundBudgets(store, snapshot) {
|
|
|
102584
102584
|
}
|
|
102585
102585
|
}
|
|
102586
102586
|
}
|
|
102587
|
-
function
|
|
102587
|
+
function floatSellerHost(record) {
|
|
102588
|
+
try {
|
|
102589
|
+
return new URL(String(record?.url)).hostname || void 0;
|
|
102590
|
+
} catch {
|
|
102591
|
+
return void 0;
|
|
102592
|
+
}
|
|
102593
|
+
}
|
|
102594
|
+
function readFloatRefundOutcomes(store) {
|
|
102588
102595
|
const outcomes = [];
|
|
102589
102596
|
let names;
|
|
102590
102597
|
try {
|
|
@@ -102598,13 +102605,32 @@ function takeFloatRefundOutcomes(store) {
|
|
|
102598
102605
|
const record = store.readWal(name);
|
|
102599
102606
|
if (record?.schema !== FLOAT_PAYMENT_SCHEMA2 || floatRecordState(record) !== "refund_pending") continue;
|
|
102600
102607
|
if (record.refundOutcome === void 0 || record.refundOutcomeShown !== false) continue;
|
|
102601
|
-
|
|
102602
|
-
outcomes.push({ floatId: record.floatId, paidAtomic: record.paidAtomic, outcome: record.refundOutcome, atMs: record.refundOutcomeAtMs });
|
|
102608
|
+
outcomes.push({ floatId: record.floatId, paidAtomic: record.paidAtomic, host: floatSellerHost(record), outcome: record.refundOutcome, atMs: record.refundOutcomeAtMs });
|
|
102603
102609
|
} catch {
|
|
102604
102610
|
}
|
|
102605
102611
|
}
|
|
102606
102612
|
return outcomes;
|
|
102607
102613
|
}
|
|
102614
|
+
function markFloatRefundOutcomesShown(store, shown) {
|
|
102615
|
+
const wanted = new Map(shown.map(({ floatId, outcome }) => [floatId, outcome]));
|
|
102616
|
+
if (!wanted.size) return;
|
|
102617
|
+
let names;
|
|
102618
|
+
try {
|
|
102619
|
+
names = store.listWal();
|
|
102620
|
+
} catch {
|
|
102621
|
+
return;
|
|
102622
|
+
}
|
|
102623
|
+
for (const name of names) {
|
|
102624
|
+
if (!name.startsWith(FLOAT_PAYMENT_WAL_PREFIX)) continue;
|
|
102625
|
+
try {
|
|
102626
|
+
const record = store.readWal(name);
|
|
102627
|
+
if (record?.schema !== FLOAT_PAYMENT_SCHEMA2 || record.refundOutcomeShown !== false) continue;
|
|
102628
|
+
if (!wanted.has(record.floatId) || wanted.get(record.floatId) !== record.refundOutcome) continue;
|
|
102629
|
+
store.writeWal(name, { ...record, refundOutcomeShown: true });
|
|
102630
|
+
} catch {
|
|
102631
|
+
}
|
|
102632
|
+
}
|
|
102633
|
+
}
|
|
102608
102634
|
function dropOldMemoryAnswers(now) {
|
|
102609
102635
|
for (const [key, entry] of memoryAnswers) if (now >= entry.atMs + FLOAT_KEEP_BYTES_MS) memoryAnswers.delete(key);
|
|
102610
102636
|
}
|
|
@@ -105922,8 +105948,10 @@ function fillsOnTheWayAtomic(store) {
|
|
|
105922
105948
|
}
|
|
105923
105949
|
function refundOf(record) {
|
|
105924
105950
|
const inner = String(record.innerRequestId ?? "");
|
|
105951
|
+
const seller = floatSellerHost(record);
|
|
105925
105952
|
return {
|
|
105926
105953
|
...inner.endsWith(":float") ? { requestId: inner.slice(0, -":float".length) } : { floatId: record.floatId ?? null },
|
|
105954
|
+
...seller ? { seller } : {},
|
|
105927
105955
|
refundAtomic: String(record.paidAtomic)
|
|
105928
105956
|
};
|
|
105929
105957
|
}
|
|
@@ -119360,7 +119388,7 @@ function withEarlyAnswer(tool, {
|
|
|
119360
119388
|
if (open4) {
|
|
119361
119389
|
log(`MCP_PAY_SECOND_REFUSED requestId=${requestId} open=${open4[0]}`);
|
|
119362
119390
|
return { text: JSON.stringify({
|
|
119363
|
-
say: `
|
|
119391
|
+
say: `Nothing was paid for this request: a payment for this ${words2 === PAY_WORDS ? "URL" : "call"} is still open with ${words2.who}. Do not pay again; asking for its result pays nothing more.`,
|
|
119364
119392
|
ok: false,
|
|
119365
119393
|
error: "mcp_payment_still_open",
|
|
119366
119394
|
requestId,
|
|
@@ -119423,7 +119451,7 @@ function withEarlyAnswer(tool, {
|
|
|
119423
119451
|
log(`MCP_PAY_EARLY_ANSWER requestId=${requestId} waited=${secondsWaited}s`);
|
|
119424
119452
|
entry.toldWaiting = true;
|
|
119425
119453
|
const next = `The payment was sent to ${words2.who} (price + fee left the balance), and ${words2.who} ${words2.busyNext}. Do not pay again: call ${tool.name} again with request_id "${requestId}" and ${words2.same} for the result (that call waits up to ${Math.round(earlyAnswerMs / 1e3)} s for it); it never pays twice. A new request_id for the same request is refused while this one is open. The later call's answer says how it ended: ${words2.who}'s answer, or what happened to the payment.`;
|
|
119426
|
-
const say3 = sellerWorkingSeconds < JUST_REACHED_SECONDS ? `Sent to ${words2.who}; the request just reached it. Do not pay again
|
|
119454
|
+
const say3 = sellerWorkingSeconds < JUST_REACHED_SECONDS ? `Sent to ${words2.who}; the request just reached it. Do not pay again; asking for the result pays nothing more.` : `Sent to ${words2.who}; it has not answered yet. Do not pay again; asking for the result pays nothing more.`;
|
|
119427
119455
|
return { text: JSON.stringify({ say: say3, ok: true, paid: false, pending: true, stage: "seller_working", requestId, secondsWaited, sellerWorkingSeconds, next }, null, 2) };
|
|
119428
119456
|
} };
|
|
119429
119457
|
}
|
|
@@ -119622,7 +119650,7 @@ function refusalSay(a, tool, again, npmVersion) {
|
|
|
119622
119650
|
return `Nothing changed: this address was made for ${amount ? `${amount} USDC` : "a fixed amount"}, and its amount never changes. Read next for what to do.`;
|
|
119623
119651
|
}
|
|
119624
119652
|
if (code2 === "mcp_balance_unknown") return "Nothing was moved yet: the wallet is still reading its private balance. Try again in a minute.";
|
|
119625
|
-
if (code2 === "mcp_payment_still_open") return "
|
|
119653
|
+
if (code2 === "mcp_payment_still_open") return "Nothing was paid for this request: a payment for it is still open. Do not pay again; asking for its result pays nothing more.";
|
|
119626
119654
|
if (code2 === "mcp_setup_restart_needed") return "The wallet is set up, but it must reconnect once. Follow the steps below, then try again. Nothing was paid.";
|
|
119627
119655
|
if (code2 === "mcp_restart_needed") return "Nothing was paid. Restart this app, then try again.";
|
|
119628
119656
|
if (code2 === "p03_merchant_respend_value_held_by_private_send") {
|
|
@@ -120326,8 +120354,7 @@ function withKeepIdNote(output2) {
|
|
|
120326
120354
|
return output2;
|
|
120327
120355
|
}
|
|
120328
120356
|
if (!parsed2 || typeof parsed2 !== "object" || Array.isArray(parsed2) || typeof parsed2.next !== "string" || parsed2.next.includes(KEEP_ID_NOTE)) return output2;
|
|
120329
|
-
|
|
120330
|
-
if (!ids.some((id) => parsed2.next.includes(id)) && !/request_id "[^"]+"/.test(parsed2.next)) return output2;
|
|
120357
|
+
if (!/"(?:requestId|newRequestId)"\s*:\s*"[^"]{4,}"/.test(block.text) && !/request_id "[^"]+"/.test(parsed2.next)) return output2;
|
|
120331
120358
|
return withFirstText(output2, block, { ...parsed2, next: `${parsed2.next.replace(/[.\s]+$/, "")}. ${KEEP_ID_NOTE}` });
|
|
120332
120359
|
}
|
|
120333
120360
|
function plainFields(parsed2, toolName) {
|
|
@@ -125398,8 +125425,9 @@ async function sellerTokenAccountExists(connection, asset, payTo) {
|
|
|
125398
125425
|
}
|
|
125399
125426
|
function refundOutcomeText(outcome) {
|
|
125400
125427
|
const amount = ATOMIC_TEXT.test(String(outcome?.paidAtomic ?? "")) ? `${usdcText3(outcome.paidAtomic)} USDC` : "a Shinjuku payment";
|
|
125401
|
-
|
|
125402
|
-
return `The refund of ${amount}
|
|
125428
|
+
const payment = typeof outcome?.host === "string" && /^[a-z0-9.-]{1,253}$/i.test(outcome.host) ? ` for the payment to ${outcome.host}` : "";
|
|
125429
|
+
if (outcome?.outcome === "refund_arrived") return `The refund of ${amount}${payment} arrived.`;
|
|
125430
|
+
return `The refund of ${amount}${payment} could not be matched in your balance (this balance read cannot tell refunds apart); if it came back, balanceAtomic counts it already.`;
|
|
125403
125431
|
}
|
|
125404
125432
|
function floatRefusal(error) {
|
|
125405
125433
|
const code2 = String(error?.message ?? "").split(/[\s:;(]/, 1)[0];
|
|
@@ -125836,9 +125864,35 @@ async function checkUnshieldRecipient({ connection, mint, owner }) {
|
|
|
125836
125864
|
throw new Error("mcp_unshield_to_invalid: the USDC holder at this address is for another token or another owner, so it cannot take this payment; nothing was paid");
|
|
125837
125865
|
}
|
|
125838
125866
|
}
|
|
125867
|
+
async function walkBeforeLease(session, exitProofTools) {
|
|
125868
|
+
try {
|
|
125869
|
+
const store = session.openStore();
|
|
125870
|
+
let marks = walletHistoryHomeMarks(store);
|
|
125871
|
+
if (marks === void 0) {
|
|
125872
|
+
await new Promise((resolve35) => {
|
|
125873
|
+
setTimeout(resolve35, HOME_MARKS_SETTLED_MS2 + 10);
|
|
125874
|
+
});
|
|
125875
|
+
marks = walletHistoryHomeMarks(store);
|
|
125876
|
+
}
|
|
125877
|
+
if (marks === void 0) return void 0;
|
|
125878
|
+
const history = await loadWalletP03History({
|
|
125879
|
+
store,
|
|
125880
|
+
connection: connectSplit(session.connection, session.historyUrl),
|
|
125881
|
+
programId: session.programId,
|
|
125882
|
+
pool: store.state.pool,
|
|
125883
|
+
deploymentIdentity: exitProofTools.deploymentIdentity,
|
|
125884
|
+
share: { notBeforeMs: Date.now(), marks }
|
|
125885
|
+
});
|
|
125886
|
+
return { marks, pool: String(store.state.pool), history };
|
|
125887
|
+
} catch {
|
|
125888
|
+
return void 0;
|
|
125889
|
+
}
|
|
125890
|
+
}
|
|
125839
125891
|
async function runUnshield({
|
|
125840
125892
|
session,
|
|
125841
|
-
|
|
125893
|
+
lease,
|
|
125894
|
+
before = () => void 0,
|
|
125895
|
+
prepare = (store) => store,
|
|
125842
125896
|
unshieldId,
|
|
125843
125897
|
amountAtomic,
|
|
125844
125898
|
recipientOwner,
|
|
@@ -125848,11 +125902,13 @@ async function runUnshield({
|
|
|
125848
125902
|
onStage,
|
|
125849
125903
|
selfPayStep = selfPay,
|
|
125850
125904
|
onAnswered,
|
|
125851
|
-
onCheckPending
|
|
125905
|
+
onCheckPending,
|
|
125906
|
+
onExited = () => {
|
|
125907
|
+
},
|
|
125908
|
+
walked,
|
|
125909
|
+
finalityWaits = 0
|
|
125852
125910
|
}) {
|
|
125853
125911
|
const owner = new import_web3132.PublicKey(recipientOwner);
|
|
125854
|
-
const mint = new import_web3132.PublicKey(store.state.asset);
|
|
125855
|
-
const recipient = getAssociatedTokenAddressSync(mint, owner, true, TOKEN_PROGRAM_ID);
|
|
125856
125912
|
let timing;
|
|
125857
125913
|
try {
|
|
125858
125914
|
timing = typeof session.timing === "function" ? session.timing() : void 0;
|
|
@@ -125866,141 +125922,226 @@ async function runUnshield({
|
|
|
125866
125922
|
}
|
|
125867
125923
|
};
|
|
125868
125924
|
const scoped = (prefix, fn) => phaseScopeActive() || timing === void 0 ? fn() : withPhaseScope(mark, prefix, fn);
|
|
125869
|
-
|
|
125870
|
-
|
|
125871
|
-
|
|
125872
|
-
|
|
125873
|
-
|
|
125874
|
-
|
|
125875
|
-
|
|
125925
|
+
let current;
|
|
125926
|
+
const use = (store) => {
|
|
125927
|
+
current = store;
|
|
125928
|
+
};
|
|
125929
|
+
let nextWalk = walked;
|
|
125930
|
+
const walkNext = (report) => {
|
|
125931
|
+
nextWalk = report;
|
|
125932
|
+
};
|
|
125933
|
+
const walk = (deploymentIdentity) => () => {
|
|
125934
|
+
if (nextWalk !== void 0) {
|
|
125935
|
+
const report = nextWalk;
|
|
125936
|
+
nextWalk = void 0;
|
|
125937
|
+
mark("unshield-walk-before-lease");
|
|
125938
|
+
return Promise.resolve(report);
|
|
125939
|
+
}
|
|
125940
|
+
return scoped("unshield-walk", () => loadWalletP03History({
|
|
125941
|
+
store: current,
|
|
125942
|
+
connection: connectSplit(session.connection, session.historyUrl),
|
|
125943
|
+
programId: session.programId,
|
|
125944
|
+
pool: current.state.pool,
|
|
125945
|
+
deploymentIdentity
|
|
125946
|
+
}));
|
|
125947
|
+
};
|
|
125876
125948
|
const name = `self-pay-${unshieldId}`;
|
|
125877
|
-
|
|
125878
|
-
|
|
125879
|
-
const
|
|
125880
|
-
if (
|
|
125881
|
-
|
|
125882
|
-
|
|
125883
|
-
|
|
125884
|
-
|
|
125885
|
-
|
|
125886
|
-
|
|
125887
|
-
|
|
125888
|
-
|
|
125889
|
-
|
|
125890
|
-
|
|
125949
|
+
const start = await lease(async (opened) => {
|
|
125950
|
+
mark("unshield-lease-self-pay");
|
|
125951
|
+
const stop3 = await before(opened);
|
|
125952
|
+
if (stop3 !== void 0) return { stop: stop3 };
|
|
125953
|
+
const store = await prepare(opened);
|
|
125954
|
+
use(store);
|
|
125955
|
+
const mint = new import_web3132.PublicKey(store.state.asset);
|
|
125956
|
+
const recipient = getAssociatedTokenAddressSync(mint, owner, true, TOKEN_PROGRAM_ID);
|
|
125957
|
+
let record = store.readWal(name);
|
|
125958
|
+
if (record && record.mode === void 0 && !selfPayMayHaveSigned(store, unshieldId)) {
|
|
125959
|
+
const note = chooseDirectExitNote(store, amountAtomic, unshieldId);
|
|
125960
|
+
if (note) {
|
|
125961
|
+
record = {
|
|
125962
|
+
...record,
|
|
125963
|
+
mode: DIRECT_EXIT_MODE,
|
|
125964
|
+
noteCommitment: BigInt(note.commitment).toString(),
|
|
125965
|
+
memoDigest: note.digest,
|
|
125966
|
+
noteValueAtomic: String(note.valueAtomic),
|
|
125967
|
+
exitAmountAtomic: String(amountAtomic),
|
|
125968
|
+
exitRecipient: recipient.toBase58()
|
|
125969
|
+
};
|
|
125970
|
+
store.writeWal(name, record);
|
|
125971
|
+
}
|
|
125891
125972
|
}
|
|
125892
|
-
|
|
125893
|
-
|
|
125894
|
-
|
|
125895
|
-
|
|
125973
|
+
if (record?.mode === DIRECT_EXIT_MODE) {
|
|
125974
|
+
return runDirectExit({
|
|
125975
|
+
session,
|
|
125976
|
+
store,
|
|
125977
|
+
name,
|
|
125978
|
+
pool: store.state.pool,
|
|
125979
|
+
unshieldId,
|
|
125980
|
+
amountAtomic,
|
|
125981
|
+
record,
|
|
125982
|
+
owner,
|
|
125983
|
+
mint,
|
|
125984
|
+
recipient,
|
|
125985
|
+
exitProofTools,
|
|
125986
|
+
facilitatorOrigin: facilitatorOrigin2,
|
|
125987
|
+
onStage,
|
|
125988
|
+
walk,
|
|
125989
|
+
use,
|
|
125990
|
+
mark,
|
|
125991
|
+
scoped,
|
|
125992
|
+
onAnswered
|
|
125993
|
+
});
|
|
125994
|
+
}
|
|
125995
|
+
if (record?.mode !== void 0) throw new Error("mcp_unshield_failed: this unshield's record names an exit mode this version does not know; nothing new was signed. Update the wallet");
|
|
125996
|
+
if (!selfPayMayHaveSigned(store, unshieldId)) {
|
|
125997
|
+
await checkUnshieldRecipient({ connection: session.connection, mint, owner });
|
|
125998
|
+
}
|
|
125999
|
+
const payerTools = session.proofTools;
|
|
126000
|
+
onStage("self-pay");
|
|
126001
|
+
mark("unshield-self-pay");
|
|
126002
|
+
const paid = await selfPayStep({
|
|
125896
126003
|
store,
|
|
125897
|
-
|
|
126004
|
+
connection: session.connection,
|
|
126005
|
+
programId: session.programId,
|
|
126006
|
+
proofTools: payerTools,
|
|
126007
|
+
profile,
|
|
125898
126008
|
amountAtomic,
|
|
125899
|
-
|
|
125900
|
-
|
|
125901
|
-
|
|
125902
|
-
|
|
125903
|
-
|
|
125904
|
-
|
|
125905
|
-
|
|
125906
|
-
|
|
125907
|
-
|
|
125908
|
-
|
|
125909
|
-
|
|
125910
|
-
|
|
126009
|
+
unshieldId,
|
|
126010
|
+
facilitatorBaseUrl: serviceUrl(facilitatorOrigin2, "/api/x402").href,
|
|
126011
|
+
memoServiceUrl: serviceBase(facilitatorOrigin2),
|
|
126012
|
+
// An owner unshield: the self-payment pays this wallet itself, so it does not use the wallet-file payment budget.
|
|
126013
|
+
ownerUnshield: true,
|
|
126014
|
+
// The self-payment waits for the next anchor itself (bounded, like x402_pay), instead of refusing.
|
|
126015
|
+
deps: { payDeps: { timing: session.timing(), walkHistory: walk(payerTools.deploymentIdentity), waitForAnchor: true } }
|
|
126016
|
+
});
|
|
126017
|
+
const payment = store.readWal(`${RESOURCE_PAYMENT_WAL_PREFIX2}${sha256Hex2(Buffer.from(selfPayRequestId(unshieldId), "utf8"))}`);
|
|
126018
|
+
if (!payment?.memoDigest || !paid.noteCommitment) throw new Error("mcp_unshield_failed: the self-payment record is incomplete; call wallet_unshield again with the same request_id");
|
|
126019
|
+
mark("unshield-paid");
|
|
126020
|
+
return { paid, memoDigest: payment.memoDigest, recipient, pool: store.state.pool };
|
|
126021
|
+
});
|
|
126022
|
+
if (start.stop !== void 0) return start.stop;
|
|
126023
|
+
let { tried, exitOf } = start;
|
|
126024
|
+
if (tried === void 0) {
|
|
126025
|
+
const { paid, memoDigest, recipient } = start;
|
|
126026
|
+
exitOf = (store) => runRecoveredP03NoteExit({
|
|
126027
|
+
store,
|
|
126028
|
+
connection: session.connection,
|
|
126029
|
+
programId: session.programId,
|
|
126030
|
+
serviceUrl: facilitatorOrigin2,
|
|
126031
|
+
digests: [memoDigest],
|
|
126032
|
+
recipientTokenAccount: recipient.toBase58(),
|
|
126033
|
+
proofTools: exitProofTools,
|
|
126034
|
+
noteCommitment: paid.noteCommitment,
|
|
126035
|
+
recipientOwner: owner.toBase58(),
|
|
126036
|
+
allowForeignRecipient: true,
|
|
126037
|
+
relaySubmit: facilitatorExitRelay(facilitatorOrigin2),
|
|
126038
|
+
requestAnchor: markedAnchorRequest(facilitatorAnchor(facilitatorOrigin2)),
|
|
126039
|
+
answerAtRelay: true,
|
|
126040
|
+
deps: { walkHistory: walk(exitProofTools.deploymentIdentity) }
|
|
125911
126041
|
});
|
|
126042
|
+
onStage("exit");
|
|
126043
|
+
mark("unshield-exit");
|
|
126044
|
+
tried = await exitTries({ session, lease, name, pool: start.pool, use, mark, scoped, exitOf, answer: { selfPayTransaction: paid.transaction ?? null }, onAnswered });
|
|
125912
126045
|
}
|
|
125913
|
-
|
|
125914
|
-
|
|
125915
|
-
|
|
125916
|
-
|
|
125917
|
-
|
|
125918
|
-
|
|
125919
|
-
|
|
125920
|
-
|
|
125921
|
-
|
|
125922
|
-
|
|
125923
|
-
|
|
125924
|
-
|
|
125925
|
-
|
|
125926
|
-
|
|
125927
|
-
unshieldId,
|
|
125928
|
-
facilitatorBaseUrl: serviceUrl(facilitatorOrigin2, "/api/x402").href,
|
|
125929
|
-
memoServiceUrl: serviceBase(facilitatorOrigin2),
|
|
125930
|
-
// An owner unshield: the self-payment pays this wallet itself, so it does not use the wallet-file payment budget.
|
|
125931
|
-
ownerUnshield: true,
|
|
125932
|
-
// The self-payment waits for the next anchor itself (bounded, like x402_pay), instead of refusing.
|
|
125933
|
-
deps: { payDeps: { timing: session.timing(), walkHistory: walk(payerTools.deploymentIdentity), waitForAnchor: true } }
|
|
125934
|
-
});
|
|
125935
|
-
const payment = store.readWal(`${RESOURCE_PAYMENT_WAL_PREFIX2}${sha256Hex2(Buffer.from(selfPayRequestId(unshieldId), "utf8"))}`);
|
|
125936
|
-
if (!payment?.memoDigest || !paid.noteCommitment) throw new Error("mcp_unshield_failed: the self-payment record is incomplete; call wallet_unshield again with the same request_id");
|
|
125937
|
-
mark("unshield-paid");
|
|
125938
|
-
onStage("exit");
|
|
125939
|
-
mark("unshield-exit");
|
|
125940
|
-
const exit = await scoped("unshield-exit", () => exitWhenAnchored(() => runRecoveredP03NoteExit({
|
|
125941
|
-
store,
|
|
125942
|
-
connection: session.connection,
|
|
125943
|
-
programId: session.programId,
|
|
125944
|
-
serviceUrl: facilitatorOrigin2,
|
|
125945
|
-
digests: [payment.memoDigest],
|
|
125946
|
-
recipientTokenAccount: recipient.toBase58(),
|
|
125947
|
-
proofTools: exitProofTools,
|
|
125948
|
-
noteCommitment: paid.noteCommitment,
|
|
125949
|
-
recipientOwner: owner.toBase58(),
|
|
125950
|
-
allowForeignRecipient: true,
|
|
125951
|
-
relaySubmit: facilitatorExitRelay(facilitatorOrigin2),
|
|
125952
|
-
requestAnchor: markedAnchorRequest(facilitatorAnchor(facilitatorOrigin2)),
|
|
125953
|
-
answerAtRelay: true,
|
|
125954
|
-
deps: { walkHistory: walk(exitProofTools.deploymentIdentity) }
|
|
125955
|
-
}), { ring: { connection: session.connection, pool: store.state.pool } }));
|
|
125956
|
-
const answer = { selfPayTransaction: paid.transaction ?? null, exitTransaction: exit.signature ?? null };
|
|
125957
|
-
if (exit.settled === false && !await finishAnsweredExit({ session, store, name, exit, answer, onAnswered, onCheckPending, mark, scoped })) return answer;
|
|
125958
|
-
mark("unshield-exited");
|
|
125959
|
-
const exited = store.readWal(`self-pay-${unshieldId}`);
|
|
125960
|
-
store.writeWal(`self-pay-${unshieldId}`, { ...exited, state: "exited", exitTransaction: exit.signature, exitedAtMs: exited?.exitedAtMs ?? exited?.exitAnsweredAtMs ?? Date.now() });
|
|
125961
|
-
return answer;
|
|
126046
|
+
return exitFinish({
|
|
126047
|
+
lease,
|
|
126048
|
+
name,
|
|
126049
|
+
use,
|
|
126050
|
+
mark,
|
|
126051
|
+
scoped,
|
|
126052
|
+
exitOf,
|
|
126053
|
+
tried,
|
|
126054
|
+
onCheckPending,
|
|
126055
|
+
onExited,
|
|
126056
|
+
finalityWaits,
|
|
126057
|
+
walkNext,
|
|
126058
|
+
...finalityWaits > 0 ? { preWalk: () => walkBeforeLease(session, exitProofTools) } : {}
|
|
126059
|
+
});
|
|
125962
126060
|
}
|
|
125963
126061
|
function sentAtMs(record) {
|
|
125964
126062
|
return Number.isSafeInteger(record?.exitAnsweredAtMs) ? record.exitAnsweredAtMs : record?.exitedAtMs;
|
|
125965
126063
|
}
|
|
125966
|
-
async function
|
|
125967
|
-
|
|
125968
|
-
|
|
125969
|
-
|
|
125970
|
-
|
|
125971
|
-
|
|
125972
|
-
|
|
125973
|
-
|
|
125974
|
-
|
|
125975
|
-
|
|
125976
|
-
|
|
125977
|
-
|
|
125978
|
-
|
|
125979
|
-
|
|
125980
|
-
|
|
125981
|
-
|
|
125982
|
-
|
|
125983
|
-
|
|
125984
|
-
|
|
125985
|
-
|
|
125986
|
-
|
|
125987
|
-
|
|
125988
|
-
|
|
125989
|
-
|
|
125990
|
-
|
|
125991
|
-
|
|
126064
|
+
async function exitTries({ session, lease, name, pool: pool2, use, mark, scoped, exitOf, answer: shown, changeAtomic, onAnswered }) {
|
|
126065
|
+
const answers = typeof onAnswered === "function";
|
|
126066
|
+
return scoped("unshield-exit", () => exitWhenAnchored(() => lease(async (store) => {
|
|
126067
|
+
mark("unshield-lease-exit");
|
|
126068
|
+
use(store);
|
|
126069
|
+
const exit = await exitOf(store);
|
|
126070
|
+
const answer = { ...shown, exitTransaction: exit.signature ?? null };
|
|
126071
|
+
const early = exit.settled === false && answers;
|
|
126072
|
+
if (early) {
|
|
126073
|
+
const record = store.readWal(name);
|
|
126074
|
+
store.writeWal(name, {
|
|
126075
|
+
...record,
|
|
126076
|
+
exitTransaction: exit.signature,
|
|
126077
|
+
exitAnsweredAtMs: record?.exitAnsweredAtMs ?? Date.now(),
|
|
126078
|
+
...changeAtomic !== void 0 ? { changeAtomic } : {}
|
|
126079
|
+
});
|
|
126080
|
+
try {
|
|
126081
|
+
await refreshWallet({ session, store, history: exit.preExitHistory });
|
|
126082
|
+
} catch {
|
|
126083
|
+
mark("unshield-exit-snapshot-failed");
|
|
126084
|
+
}
|
|
126085
|
+
mark("unshield-exit-answered");
|
|
126086
|
+
try {
|
|
126087
|
+
onAnswered(answer);
|
|
126088
|
+
} catch {
|
|
126089
|
+
}
|
|
126090
|
+
}
|
|
126091
|
+
return { answer, signature: exit.signature, settled: exit.settled !== false, early };
|
|
126092
|
+
}), { ring: { connection: session.connection, pool: pool2 } }));
|
|
126093
|
+
}
|
|
126094
|
+
async function exitFinish({ lease, name, use, mark, scoped, exitOf, tried, onCheckPending, onExited, finalityWaits = 0, preWalk, walkNext }) {
|
|
126095
|
+
const checkPending = (store, error) => {
|
|
125992
126096
|
mark("unshield-exit-check-pending");
|
|
125993
|
-
store.writeWal(name, { ...store.readWal(name), exitCheckPendingAtMs: Date.now() });
|
|
126097
|
+
if (store) store.writeWal(name, { ...store.readWal(name), exitCheckPendingAtMs: Date.now() });
|
|
125994
126098
|
try {
|
|
125995
126099
|
onCheckPending?.(error);
|
|
125996
126100
|
} catch {
|
|
125997
126101
|
}
|
|
125998
|
-
|
|
126102
|
+
};
|
|
126103
|
+
try {
|
|
126104
|
+
for (let waits = 0; ; waits += 1) {
|
|
126105
|
+
const early = !tried.settled && typeof preWalk === "function" ? await preWalk() : void 0;
|
|
126106
|
+
const notFinal = await lease(async (store) => {
|
|
126107
|
+
mark("unshield-lease-finish");
|
|
126108
|
+
use(store);
|
|
126109
|
+
if (!tried.settled) {
|
|
126110
|
+
walkNext?.(walkStillCurrent(store, early));
|
|
126111
|
+
try {
|
|
126112
|
+
await scoped("unshield-exit", () => exitOf(store));
|
|
126113
|
+
} catch (error) {
|
|
126114
|
+
if (waits < finalityWaits && NOT_FINAL_YET.test(String(error?.message ?? ""))) return true;
|
|
126115
|
+
if (!tried.early) throw error;
|
|
126116
|
+
checkPending(store, error);
|
|
126117
|
+
return false;
|
|
126118
|
+
} finally {
|
|
126119
|
+
walkNext?.(void 0);
|
|
126120
|
+
}
|
|
126121
|
+
}
|
|
126122
|
+
mark("unshield-exited");
|
|
126123
|
+
const exited = store.readWal(name);
|
|
126124
|
+
store.writeWal(name, { ...exited, state: "exited", exitTransaction: tried.signature, exitedAtMs: exited?.exitedAtMs ?? exited?.exitAnsweredAtMs ?? Date.now() });
|
|
126125
|
+
onExited();
|
|
126126
|
+
return false;
|
|
126127
|
+
});
|
|
126128
|
+
if (!notFinal) break;
|
|
126129
|
+
mark("unshield-finish-finality-wait");
|
|
126130
|
+
await new Promise((resolve35) => {
|
|
126131
|
+
setTimeout(resolve35, FINISH_FINALITY_WAIT_MS);
|
|
126132
|
+
});
|
|
126133
|
+
}
|
|
126134
|
+
} catch (error) {
|
|
126135
|
+
if (!tried.early) throw error;
|
|
126136
|
+
checkPending(void 0, error);
|
|
125999
126137
|
}
|
|
126138
|
+
return tried.answer;
|
|
126000
126139
|
}
|
|
126001
126140
|
async function runDirectExit({
|
|
126002
126141
|
session,
|
|
126003
126142
|
store,
|
|
126143
|
+
name,
|
|
126144
|
+
pool: pool2,
|
|
126004
126145
|
unshieldId,
|
|
126005
126146
|
amountAtomic,
|
|
126006
126147
|
record,
|
|
@@ -126011,13 +126152,11 @@ async function runDirectExit({
|
|
|
126011
126152
|
facilitatorOrigin: facilitatorOrigin2,
|
|
126012
126153
|
onStage,
|
|
126013
126154
|
walk,
|
|
126014
|
-
|
|
126015
|
-
|
|
126016
|
-
scoped
|
|
126017
|
-
onAnswered
|
|
126018
|
-
onCheckPending
|
|
126155
|
+
use,
|
|
126156
|
+
mark,
|
|
126157
|
+
scoped,
|
|
126158
|
+
onAnswered
|
|
126019
126159
|
}) {
|
|
126020
|
-
const name = `self-pay-${unshieldId}`;
|
|
126021
126160
|
if (record.amountAtomic !== String(amountAtomic) || record.exitAmountAtomic !== String(amountAtomic)) {
|
|
126022
126161
|
throw new Error("mcp_request_id_reused: this unshield's direct exit is bound to another amount; nothing new was signed");
|
|
126023
126162
|
}
|
|
@@ -126030,45 +126169,54 @@ async function runDirectExit({
|
|
|
126030
126169
|
if (!selfPayMayHaveSigned(store, unshieldId)) await checkUnshieldRecipient({ connection: session.connection, mint, owner });
|
|
126031
126170
|
onStage("exit");
|
|
126032
126171
|
mark("unshield-exit");
|
|
126033
|
-
const proveExit = async (request) => {
|
|
126034
|
-
const proved = await proveRecoveredP03NoteExit({ request, tools: exitProofTools });
|
|
126035
|
-
const now = store.readWal(name);
|
|
126036
|
-
if (now?.mode === DIRECT_EXIT_MODE && now.state === "started") store.writeWal(name, { ...now, state: "paid" });
|
|
126037
|
-
return proved;
|
|
126038
|
-
};
|
|
126039
126172
|
const exitAmountAtomic = record.exitAmountAtomic === record.noteValueAtomic ? void 0 : record.exitAmountAtomic;
|
|
126040
|
-
|
|
126041
|
-
|
|
126042
|
-
|
|
126043
|
-
|
|
126044
|
-
|
|
126045
|
-
|
|
126046
|
-
|
|
126047
|
-
|
|
126048
|
-
|
|
126049
|
-
|
|
126050
|
-
|
|
126051
|
-
|
|
126052
|
-
|
|
126053
|
-
|
|
126054
|
-
|
|
126055
|
-
|
|
126056
|
-
|
|
126057
|
-
|
|
126058
|
-
|
|
126059
|
-
|
|
126060
|
-
|
|
126173
|
+
const changeAtomic = exitAmountAtomic === void 0 ? void 0 : (BigInt(record.noteValueAtomic) - BigInt(record.exitAmountAtomic)).toString();
|
|
126174
|
+
const exitOf = (opened) => runRecoveredP03NoteExit({
|
|
126175
|
+
store: opened,
|
|
126176
|
+
connection: session.connection,
|
|
126177
|
+
programId: session.programId,
|
|
126178
|
+
serviceUrl: facilitatorOrigin2,
|
|
126179
|
+
digests: [record.memoDigest],
|
|
126180
|
+
recipientTokenAccount: recipient.toBase58(),
|
|
126181
|
+
proofTools: exitProofTools,
|
|
126182
|
+
noteCommitment: record.noteCommitment,
|
|
126183
|
+
exitAmountAtomic,
|
|
126184
|
+
recipientOwner: owner.toBase58(),
|
|
126185
|
+
allowForeignRecipient: true,
|
|
126186
|
+
relaySubmit: facilitatorExitRelay(facilitatorOrigin2),
|
|
126187
|
+
requestAnchor: markedAnchorRequest(facilitatorAnchor(facilitatorOrigin2)),
|
|
126188
|
+
answerAtRelay: true,
|
|
126189
|
+
deps: {
|
|
126190
|
+
walkHistory: walk(exitProofTools.deploymentIdentity),
|
|
126191
|
+
// The record reads "paid" once the proof exists, before the library stores it and before any relay call: from then
|
|
126192
|
+
// on the part may have reached the relay (cancel and the private send's own records see that), and the note is held.
|
|
126193
|
+
proveExit: async (request) => {
|
|
126194
|
+
const proved = await proveRecoveredP03NoteExit({ request, tools: exitProofTools });
|
|
126195
|
+
const now = opened.readWal(name);
|
|
126196
|
+
if (now?.mode === DIRECT_EXIT_MODE && now.state === "started") opened.writeWal(name, { ...now, state: "paid" });
|
|
126197
|
+
return proved;
|
|
126198
|
+
}
|
|
126199
|
+
}
|
|
126200
|
+
}).catch((error) => {
|
|
126201
|
+
if (/requested recovered note is not uniquely spendable/.test(String(error?.message)) && opened.readWal(name)?.state === "started" && !opened.readWal(directExitWalName(record)) && !selfPayMayHaveSigned(opened, unshieldId)) {
|
|
126061
126202
|
throw new Error("mcp_unshield_received_payment_gone: the received payment this unshield chose is no longer spendable (another spend took it, or the wallet's last chain read was old); nothing was signed, and this request_id cannot pass");
|
|
126062
126203
|
}
|
|
126063
126204
|
throw error;
|
|
126064
|
-
}
|
|
126065
|
-
const
|
|
126066
|
-
|
|
126067
|
-
|
|
126068
|
-
|
|
126069
|
-
|
|
126070
|
-
|
|
126071
|
-
|
|
126205
|
+
});
|
|
126206
|
+
const tried = await exitTries({
|
|
126207
|
+
session,
|
|
126208
|
+
lease: (task) => task(store),
|
|
126209
|
+
name,
|
|
126210
|
+
pool: pool2,
|
|
126211
|
+
use,
|
|
126212
|
+
mark,
|
|
126213
|
+
scoped,
|
|
126214
|
+
exitOf,
|
|
126215
|
+
answer: { selfPayTransaction: null },
|
|
126216
|
+
changeAtomic,
|
|
126217
|
+
onAnswered
|
|
126218
|
+
});
|
|
126219
|
+
return { tried, exitOf };
|
|
126072
126220
|
}
|
|
126073
126221
|
function balanceFields(parts) {
|
|
126074
126222
|
if (!parts) return null;
|
|
@@ -126389,8 +126537,37 @@ function createWalletTools({
|
|
|
126389
126537
|
...history ? { history } : {},
|
|
126390
126538
|
...share ? { share } : {}
|
|
126391
126539
|
});
|
|
126392
|
-
const
|
|
126393
|
-
const takeRefundNotices = () =>
|
|
126540
|
+
const shownRefunds = /* @__PURE__ */ new Set();
|
|
126541
|
+
const takeRefundNotices = (store) => {
|
|
126542
|
+
let outcomes;
|
|
126543
|
+
try {
|
|
126544
|
+
outcomes = readFloatRefundOutcomes(store ?? session.openStore());
|
|
126545
|
+
} catch {
|
|
126546
|
+
return {};
|
|
126547
|
+
}
|
|
126548
|
+
const fresh = outcomes.filter(({ floatId, outcome }) => !shownRefunds.has(`${floatId}:${outcome}`));
|
|
126549
|
+
if (!fresh.length) return {};
|
|
126550
|
+
for (const { floatId, outcome } of fresh) shownRefunds.add(`${floatId}:${outcome}`);
|
|
126551
|
+
underLease((leased) => markFloatRefundOutcomesShown(leased, fresh)).catch(() => {
|
|
126552
|
+
});
|
|
126553
|
+
return { refundNotices: fresh.map(refundOutcomeText) };
|
|
126554
|
+
};
|
|
126555
|
+
const withRefundNotices = (answer, store) => {
|
|
126556
|
+
let value2;
|
|
126557
|
+
try {
|
|
126558
|
+
value2 = JSON.parse(answer.text);
|
|
126559
|
+
} catch {
|
|
126560
|
+
return answer;
|
|
126561
|
+
}
|
|
126562
|
+
if (!value2 || typeof value2 !== "object" || Array.isArray(value2)) return answer;
|
|
126563
|
+
const notices = takeRefundNotices(store);
|
|
126564
|
+
if (!notices.refundNotices) return answer;
|
|
126565
|
+
return json3({
|
|
126566
|
+
...value2,
|
|
126567
|
+
...notices,
|
|
126568
|
+
...typeof value2.next === "string" ? { next: `${value2.next.replace(/[.\s]+$/, "")}. Tell the user each refundNotices line` } : {}
|
|
126569
|
+
});
|
|
126570
|
+
};
|
|
126394
126571
|
let lastWriterEndedAt = 0;
|
|
126395
126572
|
let paysInFlight = 0;
|
|
126396
126573
|
let payJoinWaiting = 0;
|
|
@@ -126829,7 +127006,6 @@ function createWalletTools({
|
|
|
126829
127006
|
if (early !== void 0 && !same2) log("MCP_REFRESH_WALK_AGAIN");
|
|
126830
127007
|
const share = early !== void 0 && !same2 ? { notBeforeMs: Date.now() } : void 0;
|
|
126831
127008
|
let result2 = await refreshStep(store, same2 ? early.history : void 0, share);
|
|
126832
|
-
refundNotices.push(...takeFloatRefundOutcomes(store).map(refundOutcomeText));
|
|
126833
127009
|
let marksAfter = walletHomeMarks(session.walletPath);
|
|
126834
127010
|
const settled = (marks) => marks !== void 0 && marks.readAtMs - marks.newestMs >= HOME_MARKS_SETTLED_MS2;
|
|
126835
127011
|
if (background && settled(marksBefore) && marksAfter !== void 0 && marksAfter.marks !== marksBefore.marks && paysInFlight === 0) {
|
|
@@ -127311,8 +127487,12 @@ ${canonical5}`;
|
|
|
127311
127487
|
};
|
|
127312
127488
|
for (const [phase, at, outcome] of gateTimes) mark(phase, at, outcome);
|
|
127313
127489
|
let earlyBalance;
|
|
127490
|
+
let earlyCorrection;
|
|
127314
127491
|
const payTiming = (phase, outcome, at) => {
|
|
127315
|
-
if (phase === "seller-sent")
|
|
127492
|
+
if (phase === "seller-sent") {
|
|
127493
|
+
sellerSentAt.set(requestId, Date.now());
|
|
127494
|
+
earlyCorrection ??= startFloatCorrection();
|
|
127495
|
+
}
|
|
127316
127496
|
if (timing === void 0) return;
|
|
127317
127497
|
timing(phase, outcome, at);
|
|
127318
127498
|
if (phase === "seller-sent" && earlyBalance === void 0) earlyBalance = earlyResultBalance(requestId);
|
|
@@ -127422,11 +127602,10 @@ ${canonical5}`;
|
|
|
127422
127602
|
await waitWithProgress(retry.waitMs, progress3, "waiting to try the payment again; nothing was paid");
|
|
127423
127603
|
continue;
|
|
127424
127604
|
}
|
|
127425
|
-
await correctFloatRecordsNow();
|
|
127605
|
+
await correctFloatRecordsNow(void 0, earlyCorrection);
|
|
127426
127606
|
const failed = payFailure(error, requestId, "x402_pay", join39);
|
|
127427
127607
|
const ready = readyInSecondsOf(error, code2);
|
|
127428
|
-
|
|
127429
|
-
return Object.keys(extra).length ? json3({ ...JSON.parse(failed.text), ...extra }) : failed;
|
|
127608
|
+
return withRefundNotices(ready !== void 0 ? json3({ ...JSON.parse(failed.text), readyInSeconds: ready }) : failed);
|
|
127430
127609
|
}
|
|
127431
127610
|
}
|
|
127432
127611
|
const { bytes: bytes2, truncated } = await readBody(response);
|
|
@@ -127478,7 +127657,7 @@ ${canonical5}`;
|
|
|
127478
127657
|
mark("mcp-result-float");
|
|
127479
127658
|
const floatPaid = float?.state === "receipt";
|
|
127480
127659
|
const amounts = floatPaid ? { priceAtomic: float.priceAtomic, feeAtomic: float.feeAtomic, amountAtomic: float.paidAtomic } : { priceAtomic: receipt.amountAtomic ?? null, feeAtomic: "0", amountAtomic: receipt.amountAtomic ?? null };
|
|
127481
|
-
if (paidStore && await correctFloatRecordsNow(paidStore) > 0) {
|
|
127660
|
+
if (paidStore && await correctFloatRecordsNow(paidStore, earlyCorrection) > 0) {
|
|
127482
127661
|
earlyBalance = void 0;
|
|
127483
127662
|
try {
|
|
127484
127663
|
paidStore = session.openStore();
|
|
@@ -127503,6 +127682,7 @@ ${canonical5}`;
|
|
|
127503
127682
|
}
|
|
127504
127683
|
mark("mcp-result");
|
|
127505
127684
|
const shinjukuTransaction = floatPaid ? leg1Transaction(paidStore, float, requestId) : null;
|
|
127685
|
+
const notices = takeRefundNotices(paidStore);
|
|
127506
127686
|
return answerResult(paidAnswerContent({
|
|
127507
127687
|
status: response.status,
|
|
127508
127688
|
headers: response.headers,
|
|
@@ -127521,8 +127701,8 @@ ${canonical5}`;
|
|
|
127521
127701
|
// Leg 1 (this wallet's private payment to Shinjuku, a pool transaction): the seller may return no settle signature.
|
|
127522
127702
|
...floatPaid ? { via: "shinjuku", shinjukuTransaction } : {},
|
|
127523
127703
|
...balanceAnswer(one),
|
|
127524
|
-
...
|
|
127525
|
-
next: receipt.replayed === true ? "this request id was already paid: the stored receipt came back and nothing new was paid" : floatPaid ? "paid through Shinjuku (privately: the chain shows Shinjuku paying the seller, not this wallet); tell the user the price (priceAtomic), the fee (feeAtomic), the total (amountAtomic), and the transaction (the seller's settle transaction; null when the seller returned none)" + (shinjukuTransaction ? ". shinjukuTransaction is this wallet's private payment to Shinjuku" : ". shinjukuTransaction (this wallet's private payment to Shinjuku) is not recorded yet; wallet_receipts shows it once it settles") + ". wallet_balance shows the new balance" : "paid; tell the user what was paid (amountAtomic, transaction). wallet_receipts lists this payment, wallet_balance shows the new balance"
|
|
127704
|
+
...notices,
|
|
127705
|
+
next: (receipt.replayed === true ? "this request id was already paid: the stored receipt came back and nothing new was paid" : floatPaid ? "paid through Shinjuku (privately: the chain shows Shinjuku paying the seller, not this wallet); tell the user the price (priceAtomic), the fee (feeAtomic), the total (amountAtomic), and the transaction (the seller's settle transaction; null when the seller returned none)" + (shinjukuTransaction ? ". shinjukuTransaction is this wallet's private payment to Shinjuku" : ". shinjukuTransaction (this wallet's private payment to Shinjuku) is not recorded yet; wallet_receipts shows it once it settles") + ". wallet_balance shows the new balance" : "paid; tell the user what was paid (amountAtomic, transaction). wallet_receipts lists this payment, wallet_balance shows the new balance") + (notices.refundNotices ? ". Tell the user each refundNotices line" : "")
|
|
127526
127706
|
}, "x402_pay")
|
|
127527
127707
|
}));
|
|
127528
127708
|
}
|
|
@@ -128669,7 +128849,21 @@ ${canonical5}`;
|
|
|
128669
128849
|
}
|
|
128670
128850
|
return names;
|
|
128671
128851
|
}
|
|
128672
|
-
async function correctFloatRecords(store, names, untilMs) {
|
|
128852
|
+
async function correctFloatRecords(store, names, untilMs, started = floatCorrectionReads(store, names)) {
|
|
128853
|
+
const { states, proven, settled } = started;
|
|
128854
|
+
if (settled === void 0) return { states, written: 0 };
|
|
128855
|
+
const until = (ms) => new Promise((resolve35) => {
|
|
128856
|
+
const timer = setTimeout(resolve35, Math.max(0, ms - Date.now()));
|
|
128857
|
+
timer.unref?.();
|
|
128858
|
+
});
|
|
128859
|
+
await Promise.race([settled, until(untilMs)]);
|
|
128860
|
+
if (!proven.length) return { states, written: 0 };
|
|
128861
|
+
const writing = underLease((leased) => Date.now() >= untilMs ? 0 : writeProven(leased, proven));
|
|
128862
|
+
const written = await Promise.race([writing.catch(() => 0), until(untilMs).then(() => 0)]);
|
|
128863
|
+
if (written > 0) log(`MCP_FLOAT_RECORDS_CORRECTED records=${written}`);
|
|
128864
|
+
return { states, written };
|
|
128865
|
+
}
|
|
128866
|
+
function floatCorrectionReads(store, names) {
|
|
128673
128867
|
const now = Date.now();
|
|
128674
128868
|
const due = [];
|
|
128675
128869
|
const transfers = [];
|
|
@@ -128695,11 +128889,11 @@ ${canonical5}`;
|
|
|
128695
128889
|
}
|
|
128696
128890
|
const states = new Map(finalRefundStates);
|
|
128697
128891
|
for (const [floatId, transaction] of finalTransfers) states.set(floatId, { floatState: "final", transaction });
|
|
128698
|
-
|
|
128892
|
+
const proven = [];
|
|
128893
|
+
if (!due.length && !transfers.length) return { states, proven, settled: void 0 };
|
|
128699
128894
|
due.sort((left, right) => floatEndedAtMs(right.record) - floatEndedAtMs(left.record));
|
|
128700
128895
|
transfers.sort((left, right) => floatAnsweredAtMs(right.record) - floatAnsweredAtMs(left.record));
|
|
128701
128896
|
const fetchImpl = ops.fetch ?? fetch;
|
|
128702
|
-
const proven = [];
|
|
128703
128897
|
const reads = due.slice(0, REFUND_STATUS_READS).map(({ name, record }) => readFloatTransferState(record, fetchImpl).then((read) => {
|
|
128704
128898
|
const state = floatRecordState(record);
|
|
128705
128899
|
if (state === "submitted" && read?.state === "landed" || read?.state === "final") {
|
|
@@ -128727,26 +128921,24 @@ ${canonical5}`;
|
|
|
128727
128921
|
proven.push({ name, from: record.state, transaction: read.transaction, fill: true });
|
|
128728
128922
|
}));
|
|
128729
128923
|
}
|
|
128730
|
-
|
|
128731
|
-
const timer = setTimeout(resolve35, Math.max(0, ms - Date.now()));
|
|
128732
|
-
timer.unref?.();
|
|
128733
|
-
});
|
|
128734
|
-
await Promise.race([Promise.all(reads).catch(() => {
|
|
128735
|
-
}), until(untilMs)]);
|
|
128736
|
-
if (!proven.length) return { states, written: 0 };
|
|
128737
|
-
const writing = underLease((leased) => Date.now() >= untilMs ? 0 : writeProven(leased, proven));
|
|
128738
|
-
const written = await Promise.race([writing.catch(() => 0), until(untilMs).then(() => 0)]);
|
|
128739
|
-
if (written > 0) log(`MCP_FLOAT_RECORDS_CORRECTED records=${written}`);
|
|
128740
|
-
return { states, written };
|
|
128924
|
+
return { states, proven, settled: Promise.all(reads).then(() => void 0, () => void 0) };
|
|
128741
128925
|
}
|
|
128742
|
-
async function correctFloatRecordsNow(store) {
|
|
128926
|
+
async function correctFloatRecordsNow(store, started) {
|
|
128743
128927
|
try {
|
|
128744
128928
|
const open4 = store ?? session.openStore();
|
|
128745
|
-
return (await correctFloatRecords(open4,
|
|
128929
|
+
return (await correctFloatRecords(open4, void 0, Date.now() + FLOAT_CORRECT_WAIT_MS, started ?? floatCorrectionReads(open4, staleRefundNames(open4)))).written;
|
|
128746
128930
|
} catch {
|
|
128747
128931
|
return 0;
|
|
128748
128932
|
}
|
|
128749
128933
|
}
|
|
128934
|
+
function startFloatCorrection() {
|
|
128935
|
+
try {
|
|
128936
|
+
const open4 = session.openStore();
|
|
128937
|
+
return floatCorrectionReads(open4, staleRefundNames(open4));
|
|
128938
|
+
} catch {
|
|
128939
|
+
return void 0;
|
|
128940
|
+
}
|
|
128941
|
+
}
|
|
128750
128942
|
function writeProven(store, proven) {
|
|
128751
128943
|
let written = 0;
|
|
128752
128944
|
for (const { name, from, verdict, transaction, refundDueAtMs, fill } of proven) {
|
|
@@ -131113,13 +131305,13 @@ ${canonical5}`;
|
|
|
131113
131305
|
}
|
|
131114
131306
|
return session.openStore();
|
|
131115
131307
|
}
|
|
131116
|
-
async function unshieldPart(
|
|
131117
|
-
const
|
|
131118
|
-
|
|
131308
|
+
async function unshieldPart(job, unshieldId, amountAtomic, onStage, { before, onAnswered, firstLease = underLease, yieldMs = UNSHIELD_WINDOW_YIELD_MS } = {}) {
|
|
131309
|
+
const name = `self-pay-${unshieldId}`;
|
|
131310
|
+
let windows = 0;
|
|
131119
131311
|
let backup;
|
|
131312
|
+
const finishing = { running: true, atMs: Date.now() };
|
|
131120
131313
|
const result = await (ops.unshield ?? runUnshield)({
|
|
131121
131314
|
session,
|
|
131122
|
-
store,
|
|
131123
131315
|
unshieldId,
|
|
131124
131316
|
amountAtomic,
|
|
131125
131317
|
recipientOwner: job.to,
|
|
@@ -131127,24 +131319,44 @@ ${canonical5}`;
|
|
|
131127
131319
|
profile: money.profile,
|
|
131128
131320
|
facilitatorOrigin: money.facilitatorOrigin,
|
|
131129
131321
|
onStage,
|
|
131322
|
+
finalityWaits: FINISH_FINALITY_WAITS,
|
|
131323
|
+
lease: (task) => windows++ === 0 ? firstLease(task) : new Promise((resolve35) => {
|
|
131324
|
+
setTimeout(resolve35, yieldMs);
|
|
131325
|
+
}).then(() => withLockRetry(() => underLease(task))),
|
|
131326
|
+
before,
|
|
131327
|
+
prepare: async (opened) => {
|
|
131328
|
+
const store = await refreshStaleBeforeUnshield(opened, onStage);
|
|
131329
|
+
bindUnshieldRecipient(store, unshieldId, amountAtomic, job.to, unshieldId === moneyId(job.requestId) ? job.requestId : void 0);
|
|
131330
|
+
return store;
|
|
131331
|
+
},
|
|
131130
131332
|
...ops.selfPay ? { selfPayStep: ops.selfPay } : {},
|
|
131131
131333
|
...typeof onAnswered === "function" ? { onAnswered: (answer) => {
|
|
131334
|
+
answeredExitTries.set(name, finishing);
|
|
131132
131335
|
backup = backupNow(session.openStore());
|
|
131133
131336
|
onAnswered({ ...answer, ...backup });
|
|
131134
131337
|
} } : {},
|
|
131135
131338
|
onCheckPending: (error) => {
|
|
131136
131339
|
log(`MCP_UNSHIELD_CHECK_PENDING requestId=${job.requestId} cause=${JSON.stringify(String(error?.message ?? error ?? "").split("\n", 1)[0].slice(0, 240))}`);
|
|
131137
|
-
answeredExitTries.set(
|
|
131340
|
+
answeredExitTries.set(name, { running: false, atMs: Date.now() });
|
|
131138
131341
|
armAnsweredExitRetry();
|
|
131342
|
+
},
|
|
131343
|
+
onExited: () => {
|
|
131344
|
+
backup ??= backupNow(session.openStore());
|
|
131139
131345
|
}
|
|
131346
|
+
}).finally(() => {
|
|
131347
|
+
if (answeredExitTries.get(name) === finishing) answeredExitTries.delete(name);
|
|
131140
131348
|
});
|
|
131141
|
-
return { ...result, ...backup
|
|
131349
|
+
return backup === void 0 ? result : { ...result, ...backup };
|
|
131142
131350
|
}
|
|
131143
131351
|
function runUnshieldJob(job, onStage) {
|
|
131144
131352
|
if (isSplitSend(job)) return runPrivateSendJob(job, onStage);
|
|
131145
|
-
return onOwnTorTag(() =>
|
|
131146
|
-
|
|
131147
|
-
|
|
131353
|
+
return onOwnTorTag(() => unshieldPart(job, moneyId(job.requestId), job.amountAtomic, onStage, {
|
|
131354
|
+
// A new one (no self-payment yet) never takes value an open private send still owes; a started one continues.
|
|
131355
|
+
before: async (opened) => {
|
|
131356
|
+
if (!opened.readWal(`self-pay-${moneyId(job.requestId)}`)) await assertNotPromisedFresh(opened, job.amountAtomic);
|
|
131357
|
+
},
|
|
131358
|
+
onAnswered: (answer) => answerUnshieldEarly(job, answer),
|
|
131359
|
+
yieldMs: 0
|
|
131148
131360
|
}));
|
|
131149
131361
|
}
|
|
131150
131362
|
function answerUnshieldEarly(job, answer) {
|
|
@@ -131201,17 +131413,21 @@ ${canonical5}`;
|
|
|
131201
131413
|
// A wait never keeps this server alive by itself: at stdin end the send runner takes the send (handOffSends).
|
|
131202
131414
|
sleep: sendSleep,
|
|
131203
131415
|
stopped: () => sendsHandedOff,
|
|
131204
|
-
// Each part on one tag of its own (runShieldJob).
|
|
131205
|
-
runPart: ({ part, index, total }) => onOwnTorTag(
|
|
131206
|
-
|
|
131207
|
-
|
|
131208
|
-
|
|
131209
|
-
|
|
131416
|
+
// Each part on one tag of its own (runShieldJob), in lease windows (unshieldPart).
|
|
131417
|
+
runPart: ({ part, index, total }) => onOwnTorTag(async () => {
|
|
131418
|
+
const result = await unshieldPart(job, part.unshieldId, part.amountAtomic, (stage) => onStage(`payment ${index}/${total}: ${stage}`), {
|
|
131419
|
+
before: (opened) => {
|
|
131420
|
+
store = opened;
|
|
131421
|
+
if (partCancelled(opened, sendId, part)) return { cancelled: true };
|
|
131422
|
+
if (partState(opened, part).state === "exited") return {};
|
|
131423
|
+
return void 0;
|
|
131424
|
+
}
|
|
131425
|
+
});
|
|
131210
131426
|
if (result.backupPath !== void 0) backup = { backupPath: result.backupPath };
|
|
131211
131427
|
if (result.backupError !== void 0) backup = { ...backup, backupError: result.backupError };
|
|
131212
131428
|
store = session.openStore();
|
|
131213
131429
|
return result;
|
|
131214
|
-
})
|
|
131430
|
+
}),
|
|
131215
131431
|
// The plan's last write, under the lease like every other.
|
|
131216
131432
|
finish: () => underLease((opened) => {
|
|
131217
131433
|
store = opened;
|
|
@@ -131665,12 +131881,14 @@ ${canonical5}`;
|
|
|
131665
131881
|
answeredExitTries.set(name, attempt);
|
|
131666
131882
|
const unshieldId = name.slice("self-pay-".length);
|
|
131667
131883
|
log(`MCP_UNSHIELD_CHECK_RESUME unshieldId=${unshieldId}`);
|
|
131668
|
-
|
|
131884
|
+
const tryFinish = (waits) => walkBeforeLease(session, money.exitProofTools).then((early) => underLease((opened) => {
|
|
131669
131885
|
const current = opened.readWal(name);
|
|
131670
131886
|
if (current?.state === "exited" || current?.exitUnconfirmed === true || typeof current?.exitTransaction !== "string") return void 0;
|
|
131887
|
+
const walked = walkStillCurrent(opened, early);
|
|
131888
|
+
if (early !== void 0 && walked === void 0) log(`MCP_UNSHIELD_CHECK_WALK_UNDER_LEASE unshieldId=${unshieldId}`);
|
|
131671
131889
|
return (ops.unshield ?? runUnshield)({
|
|
131672
131890
|
session,
|
|
131673
|
-
|
|
131891
|
+
lease: (task) => task(opened),
|
|
131674
131892
|
unshieldId,
|
|
131675
131893
|
amountAtomic: current.amountAtomic,
|
|
131676
131894
|
recipientOwner: current.mcpTo,
|
|
@@ -131679,16 +131897,31 @@ ${canonical5}`;
|
|
|
131679
131897
|
facilitatorOrigin: money.facilitatorOrigin,
|
|
131680
131898
|
onStage: () => {
|
|
131681
131899
|
},
|
|
131682
|
-
...ops.selfPay ? { selfPayStep: ops.selfPay } : {}
|
|
131900
|
+
...ops.selfPay ? { selfPayStep: ops.selfPay } : {},
|
|
131901
|
+
...walked !== void 0 ? { walked } : {}
|
|
131902
|
+
});
|
|
131903
|
+
}, { orClosed: ANSWERED_EXIT_CLOSED })).catch(async (error) => {
|
|
131904
|
+
let answeredAt;
|
|
131905
|
+
try {
|
|
131906
|
+
answeredAt = session.openStore().readWal(name)?.exitAnsweredAtMs;
|
|
131907
|
+
} catch {
|
|
131908
|
+
answeredAt = void 0;
|
|
131909
|
+
}
|
|
131910
|
+
if (waits >= FINISH_FINALITY_WAITS || finalityClosed || session.closed === true || !NOT_FINAL_YET.test(String(error?.message ?? "")) || !Number.isSafeInteger(answeredAt) || Date.now() - answeredAt > FINISH_FINALITY_RECENT_MS) throw error;
|
|
131911
|
+
log(`MCP_UNSHIELD_CHECK_FINALITY_WAIT unshieldId=${unshieldId} wait=${waits + 1}`);
|
|
131912
|
+
await new Promise((resolve35) => {
|
|
131913
|
+
setTimeout(resolve35, FINISH_FINALITY_WAIT_MS);
|
|
131683
131914
|
});
|
|
131684
|
-
|
|
131915
|
+
return tryFinish(waits + 1);
|
|
131916
|
+
});
|
|
131917
|
+
onOwnTorTag(() => tryFinish(0)).then((result) => {
|
|
131685
131918
|
if (result === ANSWERED_EXIT_CLOSED) return;
|
|
131686
131919
|
const now = session.openStore().readWal(name);
|
|
131687
131920
|
log(now?.state === "exited" ? `MCP_UNSHIELD_CHECK_DONE unshieldId=${unshieldId}` : `MCP_UNSHIELD_CHECK_PENDING unshieldId=${unshieldId}`);
|
|
131688
131921
|
if (now?.state === "exited") refreshAtFinality();
|
|
131689
131922
|
}, (error) => {
|
|
131690
131923
|
const cause = String(error?.message ?? error ?? "").split("\n", 1)[0];
|
|
131691
|
-
attempt.provenUnspent =
|
|
131924
|
+
attempt.provenUnspent = NOT_FINAL_YET.test(cause);
|
|
131692
131925
|
log(`MCP_UNSHIELD_CHECK_PENDING unshieldId=${unshieldId} cause=${JSON.stringify(cause.slice(0, 240))}`);
|
|
131693
131926
|
}).then(() => underLease((opened) => {
|
|
131694
131927
|
const now = opened.readWal(name);
|
|
@@ -132598,21 +132831,27 @@ ${canonical5}`;
|
|
|
132598
132831
|
}),
|
|
132599
132832
|
sleep: sendSleep,
|
|
132600
132833
|
stopped: () => sendsHandedOff,
|
|
132601
|
-
// Each part on one tag of its own (runShieldJob)
|
|
132602
|
-
|
|
132603
|
-
|
|
132604
|
-
if (partCancelled(opened, plan.sendId, part)) return { cancelled: true };
|
|
132605
|
-
if (partState(opened, part).state === "exited") return {};
|
|
132834
|
+
// Each part on one tag of its own (runShieldJob), in lease windows (unshieldPart); window 1 waits for this server's
|
|
132835
|
+
// own lease holders, as before.
|
|
132836
|
+
runPart: ({ part, index, total }) => onOwnTorTag(async () => {
|
|
132606
132837
|
const result = await unshieldPart(
|
|
132607
|
-
opened,
|
|
132608
132838
|
job,
|
|
132609
132839
|
part.unshieldId,
|
|
132610
132840
|
part.amountAtomic,
|
|
132611
|
-
(stage) => log(`MCP_TRANSFER_SEND_STAGE requestId=${plan.id} part=${index}/${total} stage=${stage}`)
|
|
132841
|
+
(stage) => log(`MCP_TRANSFER_SEND_STAGE requestId=${plan.id} part=${index}/${total} stage=${stage}`),
|
|
132842
|
+
{
|
|
132843
|
+
firstLease: (task) => withLockRetry(() => underLease(task)),
|
|
132844
|
+
before: (opened) => {
|
|
132845
|
+
store = opened;
|
|
132846
|
+
if (partCancelled(opened, plan.sendId, part)) return { cancelled: true };
|
|
132847
|
+
if (partState(opened, part).state === "exited") return {};
|
|
132848
|
+
return void 0;
|
|
132849
|
+
}
|
|
132850
|
+
}
|
|
132612
132851
|
);
|
|
132613
132852
|
store = session.openStore();
|
|
132614
132853
|
return result;
|
|
132615
|
-
})
|
|
132854
|
+
}),
|
|
132616
132855
|
finish: () => underLease((opened) => {
|
|
132617
132856
|
store = opened;
|
|
132618
132857
|
return finishPrivateSend(opened, plan.sendId);
|
|
@@ -133580,7 +133819,7 @@ ${canonical5}`;
|
|
|
133580
133819
|
{ requestId, paid: false, ...facts }
|
|
133581
133820
|
);
|
|
133582
133821
|
}
|
|
133583
|
-
return inferenceRefusal(error, { requestId, ...facts }) ?? payFailure(error, requestId, "inference_chat");
|
|
133822
|
+
return withRefundNotices(inferenceRefusal(error, { requestId, ...facts }) ?? payFailure(error, requestId, "inference_chat"));
|
|
133584
133823
|
}
|
|
133585
133824
|
}
|
|
133586
133825
|
const receipt = result.receipt ?? {};
|
|
@@ -133629,7 +133868,7 @@ ${canonical5}`;
|
|
|
133629
133868
|
const larger = moreTokens(args.max_tokens);
|
|
133630
133869
|
const paidText = usdcText3(paidAtomic ?? "");
|
|
133631
133870
|
log(`MCP_INFERENCE_OUT_OF_TOKENS requestId=${requestId} maxTokens=${args.max_tokens}`);
|
|
133632
|
-
return json3(sayFirst(
|
|
133871
|
+
return withRefundNotices(json3(sayFirst(
|
|
133633
133872
|
{
|
|
133634
133873
|
ok: false,
|
|
133635
133874
|
error: "inference_out_of_tokens",
|
|
@@ -133639,13 +133878,13 @@ ${canonical5}`;
|
|
|
133639
133878
|
next: receipt.replayed === true ? `this request id was already paid and its stored answer is empty; nothing new was paid. For an answer, call inference_chat with a NEW request_id and max_tokens ${larger}; it pays again` : `Tell the user: the model ran out of tokens before it answered, and this call paid ${paidText ? `${paidText} USDC` : "(see paidAtomic)"}. For an answer, call inference_chat again with a NEW request_id and max_tokens ${larger}; it pays again. The same request_id returns this same empty answer`
|
|
133640
133879
|
},
|
|
133641
133880
|
"inference_chat"
|
|
133642
|
-
));
|
|
133881
|
+
)), paidStore);
|
|
133643
133882
|
}
|
|
133644
|
-
return json3(sayFirst({
|
|
133883
|
+
return withRefundNotices(json3(sayFirst({
|
|
133645
133884
|
ok: true,
|
|
133646
133885
|
...paidFields,
|
|
133647
133886
|
next: receipt.replayed === true ? "this request id was already paid: the stored answer came back and nothing new was paid" : "answered; give the user content, and tell them what was paid: paidAtomic (the AI provider's price, at most ceilingAtomic, plus Shinjuku's fee feeAtomic when via is shinjuku; what is not used is not refunded). wallet_balance shows the new balance"
|
|
133648
|
-
}, "inference_chat"));
|
|
133887
|
+
}, "inference_chat")), paidStore);
|
|
133649
133888
|
}
|
|
133650
133889
|
};
|
|
133651
133890
|
const addFunds2 = createAddFundsTool({
|
|
@@ -134477,7 +134716,7 @@ function createSetupTools({
|
|
|
134477
134716
|
doneTool: sayOnRefusal(doneTool)
|
|
134478
134717
|
};
|
|
134479
134718
|
}
|
|
134480
|
-
var import_web3132, shownCaps, RELEASE_RETRY_MS, STAGE_WORDS, stageWords, INTERNAL_BALANCE_DETAIL, shownBreakdown, sessionLeftShown, TOKEN_UNIT_TOOLS, RESOURCE_PAYMENT_WAL_PREFIX2, POOL_LAYOUT_CODE, POOL_LAYOUT_UPDATE, USEPOD_VIA_INFERENCE_CHAT, SEND_RUNS_ON, DEPOSIT_RUNS_ON, CLI_FUNDS_PLAN_PREFIX, CLI_FUNDS_SCHEMA, SELF_PAY_ORIGIN3, REQUEST_ID4, POSITIVE_ATOMIC6, PRIVATE_HOST3, FORBIDDEN_HEADERS3, MAX_BODY_BYTES2, PREVIEW_TIMEOUT_MS, PREVIEW_SELLER_READ_MS, CALL_BUDGET_MS, budgetLeft, PAY_ANSWER_MARGIN_MS, MONEY_FIRST_ANSWER_MS, BALANCE_AFTER_LANDING_MS, JOIN_CALL_MAX_MS, JOIN_NUDGE_QUIET_MS, JOIN_STEP_MS, sleep2, PROGRESS_EVERY_MS2, READ_BUDGET_MS, UNPAID_TOR_TRY_MS, UNPAID_CLEAR_MS, READ_BUDGET_TOOLS, FLOAT_BUSY_CODES, RETRY_MARGIN_MS, ASK_PAY_CODES, runningNpmVersion, terminalCommand2, capPlaceWords, CAP_NAMES, capName, capRaiseText, runningLimits, payCapFlag, cheaperSellerText, limitNext, SAFE_TEXT, MCP_TOOL_ALIASES, POOL_SWITCH_WHY, POOL_SWITCH_NEXT, SWITCH_STATES, quietSwitch, switchKey, ATOMIC_TEXT, movedTo, FLOAT_ID, ANSWERED_EXIT_RETRY_MS, ANSWERED_EXIT_UNCONFIRMED_MS, ANSWERED_EXIT_RETRY_WINDOW_MS, ANSWERED_EXIT_CLOSED, switchAmount, switchEta, switchRows, OWNER_CAP_CODES, JOIN_END_MCP, JOIN_END_TERMINAL_LIBRARY, JOIN_RETRY_BACKOFF_MS, WALLET_CAP_FIX, MCP_CAP_FIX, capFix, ownerOnlyNext, mcpNext, CONFIDENTIAL_RETIRED, json3, answerResult, discoverTool, LAUNCH_CAP_CODES, dayCapKind, refuse12, newRequestIdFor, payCapName, publicOffer, FLOAT_PAID_CODES, FLOAT_PRIVATE_LEG, MONEY_ID2, toRecordId, linkKindOf, moneyId, REFUSED_CODES, refusedCodeOf, PLAIN_REASONS, INSUFFICIENT_CODE, insufficientCause, INSUFFICIENT_REASONS, reasonOf, plainReason, KEPT_SEND_TRIES, shownId, isSplitSend, sendPartId, PROMISED_NEXT, partFailReason, sendAnswerOf, PUBLIC_READ_TIMEOUT_MS, RECIPIENT_CHECK_TIMEOUT_MS, withTimeout, ownKey, readFailure, OWN_KEY_TOKENS_MAX, tokenAmountText, elsewhereId, AGENT_ID_SCHEMA, agentIdName, minutesText2, ageWords2, DEPOSIT_SENT_STATES, depositLanded, usdcText3, walkWalletHistory, REFRESH_LEASE_WALK_MS, HOME_MARKS_SETTLED_MS2, AUTO_BACKUPS_KEPT, AUTO_BACKUP_NAME, AUTO_BACKUP_VERIFIED, FRONTED_SETTLE_MARGIN_SLOTS, BALANCE_REFRESH_WAIT_MS, BALANCE_REFRESH_GRACE_MS, BALANCE_REFRESH_LONG_MS, INBOUND_REFRESH_AGE_MS, changeFields, balanceAnswer, CAP_BALANCE_WAIT_MS, CAP_BALANCE_RETRY_MS, REFRESH_RETRY_MS, FINALITY_POLL_MS, FINALITY_WAIT_MS, FINALITY_REFRESH_LIMIT_MS, POOL_WATCH_MS, POOL_WATCH_POLL_MS, EARLY_BALANCE_DELAY_MS, FINALITY_SETTLE_WINDOW_SLOTS, PUBLIC_READ_ANSWER_MS, LINK_READ_ANSWER_MS, OWN_READS_AHEAD_MS, FLOAT_CORRECT_WAIT_MS, SWITCH_WAIT_MS, UNSHIELD_TO_NO_USDC_DETAIL, UNSHIELD_TO_INVALID_NEXT, INFERENCE_MIN_MAX_TOKENS, ELICIT_TIMEOUT_MS, ELICIT_UNSHOWN_MS, elicitUnshown, POLL_SECONDS2, TRANSFER_CHANGE_READ_MS, TEMP_CLEAN_DELAY_MS, KEPT_ON_DISK, MAX_SHIELDED_BALANCE_ATOMIC, receiveGenerator, MCP_TOOL_NAMES, MCP_HIDDEN_TOOL_NAMES, setupTerminalNext, SETUP_RUNNING_SAY, ACCEPTED_NEXT, SETUP_RUNNING_NEXT, SETUP_ANSWER_WAIT_MS, SETUP_CONFIRMING_SAY, SETUP_CONFIRMING_NEXT, PRIVATE_INFERENCE_WHY, RESTART_STEPS, TOR_BROWSER_PORT, SETUP_TOR_TITLE, SETUP_TOR_WHY;
|
|
134719
|
+
var import_web3132, shownCaps, RELEASE_RETRY_MS, STAGE_WORDS, stageWords, INTERNAL_BALANCE_DETAIL, shownBreakdown, sessionLeftShown, TOKEN_UNIT_TOOLS, RESOURCE_PAYMENT_WAL_PREFIX2, POOL_LAYOUT_CODE, POOL_LAYOUT_UPDATE, USEPOD_VIA_INFERENCE_CHAT, SEND_RUNS_ON, DEPOSIT_RUNS_ON, CLI_FUNDS_PLAN_PREFIX, CLI_FUNDS_SCHEMA, SELF_PAY_ORIGIN3, REQUEST_ID4, POSITIVE_ATOMIC6, PRIVATE_HOST3, FORBIDDEN_HEADERS3, MAX_BODY_BYTES2, PREVIEW_TIMEOUT_MS, PREVIEW_SELLER_READ_MS, CALL_BUDGET_MS, budgetLeft, PAY_ANSWER_MARGIN_MS, MONEY_FIRST_ANSWER_MS, BALANCE_AFTER_LANDING_MS, JOIN_CALL_MAX_MS, JOIN_NUDGE_QUIET_MS, JOIN_STEP_MS, sleep2, PROGRESS_EVERY_MS2, READ_BUDGET_MS, UNPAID_TOR_TRY_MS, UNPAID_CLEAR_MS, READ_BUDGET_TOOLS, FLOAT_BUSY_CODES, RETRY_MARGIN_MS, ASK_PAY_CODES, runningNpmVersion, terminalCommand2, capPlaceWords, CAP_NAMES, capName, capRaiseText, runningLimits, payCapFlag, cheaperSellerText, limitNext, SAFE_TEXT, MCP_TOOL_ALIASES, POOL_SWITCH_WHY, POOL_SWITCH_NEXT, SWITCH_STATES, quietSwitch, switchKey, ATOMIC_TEXT, movedTo, FLOAT_ID, ANSWERED_EXIT_RETRY_MS, ANSWERED_EXIT_UNCONFIRMED_MS, ANSWERED_EXIT_RETRY_WINDOW_MS, ANSWERED_EXIT_CLOSED, switchAmount, switchEta, switchRows, OWNER_CAP_CODES, JOIN_END_MCP, JOIN_END_TERMINAL_LIBRARY, JOIN_RETRY_BACKOFF_MS, WALLET_CAP_FIX, MCP_CAP_FIX, capFix, ownerOnlyNext, mcpNext, CONFIDENTIAL_RETIRED, json3, answerResult, discoverTool, LAUNCH_CAP_CODES, dayCapKind, refuse12, newRequestIdFor, payCapName, publicOffer, FLOAT_PAID_CODES, FLOAT_PRIVATE_LEG, MONEY_ID2, toRecordId, linkKindOf, moneyId, REFUSED_CODES, refusedCodeOf, PLAIN_REASONS, INSUFFICIENT_CODE, insufficientCause, INSUFFICIENT_REASONS, reasonOf, plainReason, KEPT_SEND_TRIES, shownId, isSplitSend, sendPartId, PROMISED_NEXT, partFailReason, sendAnswerOf, PUBLIC_READ_TIMEOUT_MS, RECIPIENT_CHECK_TIMEOUT_MS, withTimeout, ownKey, readFailure, OWN_KEY_TOKENS_MAX, tokenAmountText, elsewhereId, AGENT_ID_SCHEMA, agentIdName, minutesText2, ageWords2, DEPOSIT_SENT_STATES, depositLanded, usdcText3, walkWalletHistory, REFRESH_LEASE_WALK_MS, HOME_MARKS_SETTLED_MS2, AUTO_BACKUPS_KEPT, AUTO_BACKUP_NAME, AUTO_BACKUP_VERIFIED, FRONTED_SETTLE_MARGIN_SLOTS, UNSHIELD_WINDOW_YIELD_MS, NOT_FINAL_YET, FINISH_FINALITY_WAIT_MS, FINISH_FINALITY_WAITS, FINISH_FINALITY_RECENT_MS, walkStillCurrent, BALANCE_REFRESH_WAIT_MS, BALANCE_REFRESH_GRACE_MS, BALANCE_REFRESH_LONG_MS, INBOUND_REFRESH_AGE_MS, changeFields, balanceAnswer, CAP_BALANCE_WAIT_MS, CAP_BALANCE_RETRY_MS, REFRESH_RETRY_MS, FINALITY_POLL_MS, FINALITY_WAIT_MS, FINALITY_REFRESH_LIMIT_MS, POOL_WATCH_MS, POOL_WATCH_POLL_MS, EARLY_BALANCE_DELAY_MS, FINALITY_SETTLE_WINDOW_SLOTS, PUBLIC_READ_ANSWER_MS, LINK_READ_ANSWER_MS, OWN_READS_AHEAD_MS, FLOAT_CORRECT_WAIT_MS, SWITCH_WAIT_MS, UNSHIELD_TO_NO_USDC_DETAIL, UNSHIELD_TO_INVALID_NEXT, INFERENCE_MIN_MAX_TOKENS, ELICIT_TIMEOUT_MS, ELICIT_UNSHOWN_MS, elicitUnshown, POLL_SECONDS2, TRANSFER_CHANGE_READ_MS, TEMP_CLEAN_DELAY_MS, KEPT_ON_DISK, MAX_SHIELDED_BALANCE_ATOMIC, receiveGenerator, MCP_TOOL_NAMES, MCP_HIDDEN_TOOL_NAMES, setupTerminalNext, SETUP_RUNNING_SAY, ACCEPTED_NEXT, SETUP_RUNNING_NEXT, SETUP_ANSWER_WAIT_MS, SETUP_CONFIRMING_SAY, SETUP_CONFIRMING_NEXT, PRIVATE_INFERENCE_WHY, RESTART_STEPS, TOR_BROWSER_PORT, SETUP_TOR_TITLE, SETUP_TOR_WHY;
|
|
134481
134720
|
var init_tools = __esm({
|
|
134482
134721
|
"wallet/src/mcp/tools.mjs"() {
|
|
134483
134722
|
"use strict";
|
|
@@ -134904,6 +135143,12 @@ var init_tools = __esm({
|
|
|
134904
135143
|
AUTO_BACKUP_NAME = /^\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}-\d{3}Z(-\d+)?$/;
|
|
134905
135144
|
AUTO_BACKUP_VERIFIED = ".verified";
|
|
134906
135145
|
FRONTED_SETTLE_MARGIN_SLOTS = 20;
|
|
135146
|
+
UNSHIELD_WINDOW_YIELD_MS = 1500;
|
|
135147
|
+
NOT_FINAL_YET = /confirmed note-exit is not finalized spent/;
|
|
135148
|
+
FINISH_FINALITY_WAIT_MS = 4e3;
|
|
135149
|
+
FINISH_FINALITY_WAITS = 8;
|
|
135150
|
+
FINISH_FINALITY_RECENT_MS = 6e4;
|
|
135151
|
+
walkStillCurrent = (store, early) => early !== void 0 && early.pool === String(store.state.pool) && walletHistoryHomeMarks(store) === early.marks ? early.history : void 0;
|
|
134907
135152
|
BALANCE_REFRESH_WAIT_MS = 2e4;
|
|
134908
135153
|
BALANCE_REFRESH_GRACE_MS = 2e3;
|
|
134909
135154
|
BALANCE_REFRESH_LONG_MS = 6e4;
|