shinjuku-shielded 0.3.72 → 0.3.74
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/manifest.json +4 -4
- package/package.json +3 -3
- package/shinjuku-wallet.mjs +632 -100
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": "bf5ad0c16095110ed0258b16525e55dc743dbaa36b6ba0e0738d4ab9c185ce90",
|
|
5
|
+
"bytes": 12226842,
|
|
6
|
+
"sourceCommit": "48cab6600f17f6d97cd27fcb657eaf344c1257ef",
|
|
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",
|
|
@@ -1282,5 +1282,5 @@
|
|
|
1282
1282
|
"version": "1.8.0"
|
|
1283
1283
|
}
|
|
1284
1284
|
],
|
|
1285
|
-
"publishedAt": "2026-10-
|
|
1285
|
+
"publishedAt": "2026-10-22T19:31:45.493Z"
|
|
1286
1286
|
}
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "shinjuku-shielded",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.74",
|
|
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": "bf5ad0c1",
|
|
7
|
+
"shinjukuSha256": "bf5ad0c16095110ed0258b16525e55dc743dbaa36b6ba0e0738d4ab9c185ce90",
|
|
8
8
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
9
9
|
"author": "Shinjuku Shielded",
|
|
10
10
|
"homepage": "https://github.com/ShinjukuStaition/shinjuku-mcp#readme",
|
package/shinjuku-wallet.mjs
CHANGED
|
@@ -42600,6 +42600,11 @@ var init_rpcDefault = __esm({
|
|
|
42600
42600
|
});
|
|
42601
42601
|
|
|
42602
42602
|
// wallet/src/net/facilitatorOnion.mjs
|
|
42603
|
+
function takeSiteOnionRaces() {
|
|
42604
|
+
if (siteRacesTaken) return Promise.resolve([]);
|
|
42605
|
+
siteRacesTaken = true;
|
|
42606
|
+
return Promise.all(siteRaces);
|
|
42607
|
+
}
|
|
42603
42608
|
function onionInit(init = {}) {
|
|
42604
42609
|
if (init.dispatcher) return init;
|
|
42605
42610
|
try {
|
|
@@ -42637,7 +42642,8 @@ function raceOnions(onions, {
|
|
|
42637
42642
|
onNone,
|
|
42638
42643
|
spares = [],
|
|
42639
42644
|
spareAfterMs = SPARE_AFTER_MS,
|
|
42640
|
-
onSpares
|
|
42645
|
+
onSpares,
|
|
42646
|
+
onProbe
|
|
42641
42647
|
} = {}) {
|
|
42642
42648
|
const controller = new AbortController();
|
|
42643
42649
|
const signal = AbortSignal.any([controller.signal, AbortSignal.timeout(timeoutMs)]);
|
|
@@ -42667,9 +42673,22 @@ function raceOnions(onions, {
|
|
|
42667
42673
|
if (!controller.signal.aborted) onNone?.();
|
|
42668
42674
|
settle(onions[0]);
|
|
42669
42675
|
};
|
|
42676
|
+
const told = (onion, event) => {
|
|
42677
|
+
try {
|
|
42678
|
+
onProbe?.(onion, event);
|
|
42679
|
+
} catch {
|
|
42680
|
+
}
|
|
42681
|
+
};
|
|
42670
42682
|
const start = (onion) => {
|
|
42671
42683
|
open3 += 1;
|
|
42672
|
-
|
|
42684
|
+
told(onion, "start");
|
|
42685
|
+
probe(onion).then((won) => {
|
|
42686
|
+
told(onion, "answered");
|
|
42687
|
+
settle(won);
|
|
42688
|
+
}, () => {
|
|
42689
|
+
told(onion, controller.signal.aborted ? "stopped" : signal.aborted ? "timeout" : "failed");
|
|
42690
|
+
failed();
|
|
42691
|
+
});
|
|
42673
42692
|
};
|
|
42674
42693
|
startSpares = (cause) => {
|
|
42675
42694
|
if (sparesStarted || done || signal.aborted) return;
|
|
@@ -42790,6 +42809,33 @@ async function routeFacilitatorsOverOnion(argv2, {
|
|
|
42790
42809
|
const race = (group, onions, options) => {
|
|
42791
42810
|
let unanswered2 = false;
|
|
42792
42811
|
const onNone = options.onNone;
|
|
42812
|
+
const first = firstRaces.has(group.label) ? void 0 : { startedAt: Date.now() };
|
|
42813
|
+
if (first) firstRaces.set(group.label, first);
|
|
42814
|
+
let site;
|
|
42815
|
+
let ended;
|
|
42816
|
+
if (first && !group.path) {
|
|
42817
|
+
site = { startedAt: first.startedAt, probes: [] };
|
|
42818
|
+
siteRaces.push(new Promise((resolve38) => {
|
|
42819
|
+
ended = resolve38;
|
|
42820
|
+
}));
|
|
42821
|
+
const pinned = group.onions.length - (group.spares?.length ?? 0);
|
|
42822
|
+
const role = (onion) => {
|
|
42823
|
+
const index = group.onions.indexOf(onion);
|
|
42824
|
+
return index < pinned ? `pinned${index + 1}` : `spare${index - pinned + 1}`;
|
|
42825
|
+
};
|
|
42826
|
+
const note = (entry) => {
|
|
42827
|
+
if (site.endedAt === void 0) site.probes.push({ ...entry, at: Date.now() });
|
|
42828
|
+
};
|
|
42829
|
+
const onSpares = options.onSpares;
|
|
42830
|
+
options = {
|
|
42831
|
+
...options,
|
|
42832
|
+
onProbe: (onion, event) => note({ role: role(onion), event }),
|
|
42833
|
+
...onSpares ? { onSpares: (info) => {
|
|
42834
|
+
note({ role: "spares", event: "join" });
|
|
42835
|
+
onSpares(info);
|
|
42836
|
+
} } : {}
|
|
42837
|
+
};
|
|
42838
|
+
}
|
|
42793
42839
|
const raced = raceOnions(onions, {
|
|
42794
42840
|
fetchImpl,
|
|
42795
42841
|
timeoutMs: raceTimeoutMs,
|
|
@@ -42800,10 +42846,18 @@ async function routeFacilitatorsOverOnion(argv2, {
|
|
|
42800
42846
|
onNone?.();
|
|
42801
42847
|
}
|
|
42802
42848
|
});
|
|
42803
|
-
const first = firstRaces.has(group.label) ? void 0 : { startedAt: Date.now() };
|
|
42804
|
-
if (first) firstRaces.set(group.label, first);
|
|
42805
42849
|
group.pending = raced.winner.then((onion) => {
|
|
42806
42850
|
if (first) Object.assign(first, { endedAt: Date.now(), answered: !unanswered2 });
|
|
42851
|
+
if (site) {
|
|
42852
|
+
const open3 = /* @__PURE__ */ new Set();
|
|
42853
|
+
for (const probe of site.probes) {
|
|
42854
|
+
if (probe.event === "start") open3.add(probe.role);
|
|
42855
|
+
else open3.delete(probe.role);
|
|
42856
|
+
}
|
|
42857
|
+
for (const role of open3) site.probes.push({ role, event: "stopped", at: first.endedAt });
|
|
42858
|
+
Object.assign(site, { endedAt: first.endedAt, answered: !unanswered2 });
|
|
42859
|
+
ended(site);
|
|
42860
|
+
}
|
|
42807
42861
|
group.winner = onion;
|
|
42808
42862
|
group.pending = void 0;
|
|
42809
42863
|
if (!unanswered2 && !raced.stopped) err(`tor: the onion ${hostOf(onion)} of ${group.label} answered first; it serves this run's requests to it
|
|
@@ -42904,18 +42958,18 @@ async function routeFacilitatorsOverOnion(argv2, {
|
|
|
42904
42958
|
}
|
|
42905
42959
|
};
|
|
42906
42960
|
}
|
|
42907
|
-
var SITE_ONIONS, SITE_SPARE_ONIONS, PINNED_FACILITATOR_ONIONS, PINNED_SPARE_ONIONS, HISTORY_ONIONS, PINNED_HISTORY_ONIONS, HISTORY_PROBE_PATH, FACILITATOR_FLAGS, V3_ONION, DISCOVERY_TIMEOUT_MS, WARM_TIMEOUT_MS, RACE_TIMEOUT_MS, ROUTE_WAIT_MS, SPARE_AFTER_MS, SPARE_CAUSE, routedGroups, liveOnions, hostOf, noAnswer, routedOnions, routedOrigins, onionsOfOrigin, routesOverOnion, firstRaces, firstOnionRace, GLOBAL_DISPATCHER, onionDispatchers;
|
|
42961
|
+
var SITE_ONIONS, SITE_SPARE_ONIONS, PINNED_FACILITATOR_ONIONS, PINNED_SPARE_ONIONS, HISTORY_ONIONS, PINNED_HISTORY_ONIONS, HISTORY_PROBE_PATH, FACILITATOR_FLAGS, V3_ONION, DISCOVERY_TIMEOUT_MS, WARM_TIMEOUT_MS, RACE_TIMEOUT_MS, ROUTE_WAIT_MS, SPARE_AFTER_MS, SPARE_CAUSE, routedGroups, liveOnions, hostOf, noAnswer, routedOnions, routedOrigins, onionsOfOrigin, routesOverOnion, firstRaces, siteRaces, siteRacesTaken, firstOnionRace, GLOBAL_DISPATCHER, onionDispatchers;
|
|
42908
42962
|
var init_facilitatorOnion = __esm({
|
|
42909
42963
|
"wallet/src/net/facilitatorOnion.mjs"() {
|
|
42910
42964
|
"use strict";
|
|
42911
42965
|
init_rpcDefault();
|
|
42912
42966
|
SITE_ONIONS = Object.freeze([
|
|
42913
42967
|
"http://2kfhlfuyuwvhmibjrpxqsg4nrbcxasjgjq7kmnfzgfwzptkhhznz3dad.onion",
|
|
42914
|
-
"http://
|
|
42968
|
+
"http://vofhhl336r4bnwn7hid2uvqaa72wx66xkdu2yt4n54xljsxwn2yds6qd.onion"
|
|
42915
42969
|
]);
|
|
42916
42970
|
SITE_SPARE_ONIONS = Object.freeze([
|
|
42917
42971
|
"http://ntr5qkdfgff4gspwderjnqtkzekyhb5a4j76ov4dqncxmcb53gdsmmid.onion",
|
|
42918
|
-
"http://
|
|
42972
|
+
"http://chhgw7nfggqhhjawz54bpsiihdow66s2yvkh6ccnugpcdmhhww6xkkqd.onion"
|
|
42919
42973
|
]);
|
|
42920
42974
|
PINNED_FACILITATOR_ONIONS = Object.freeze({
|
|
42921
42975
|
"https://shinjukustaition.com": SITE_ONIONS,
|
|
@@ -42955,6 +43009,8 @@ var init_facilitatorOnion = __esm({
|
|
|
42955
43009
|
onionsOfOrigin = (origin) => routedOrigins.get(origin) ?? PINNED_FACILITATOR_ONIONS[origin] ?? [];
|
|
42956
43010
|
routesOverOnion = (origin) => routedOrigins.has(origin);
|
|
42957
43011
|
firstRaces = /* @__PURE__ */ new Map();
|
|
43012
|
+
siteRaces = [];
|
|
43013
|
+
siteRacesTaken = false;
|
|
42958
43014
|
firstOnionRace = (origin) => {
|
|
42959
43015
|
const race = firstRaces.get(origin);
|
|
42960
43016
|
return race === void 0 ? void 0 : { ...race };
|
|
@@ -46739,6 +46795,16 @@ function markPhase(phase, outcome) {
|
|
|
46739
46795
|
} catch {
|
|
46740
46796
|
}
|
|
46741
46797
|
}
|
|
46798
|
+
function poolReadOutcome(slot3, moved) {
|
|
46799
|
+
let text3;
|
|
46800
|
+
try {
|
|
46801
|
+
text3 = BigInt(slot3).toString();
|
|
46802
|
+
} catch {
|
|
46803
|
+
return void 0;
|
|
46804
|
+
}
|
|
46805
|
+
if (!/^\d{1,20}$/.test(text3)) return void 0;
|
|
46806
|
+
return `slot${text3}${Number.isSafeInteger(moved) && moved >= 0 ? `_moved${moved}` : ""}`;
|
|
46807
|
+
}
|
|
46742
46808
|
var scope, phaseScopeActive;
|
|
46743
46809
|
var init_phaseTiming = __esm({
|
|
46744
46810
|
"wallet/src/pay/phaseTiming.mjs"() {
|
|
@@ -53881,7 +53947,7 @@ async function refreshedFromSnapshot({ connection, program, poolKey, authenticat
|
|
|
53881
53947
|
if (snapshot.terminal !== authenticated.finalizedPoolSnapshot.terminal || snapshot.currentIndex !== authenticated.finalizedPoolSnapshot.currentIndex || snapshot.currentRoot !== authenticated.finalizedPoolSnapshot.currentRoot || !sameP03PoolPolicy(snapshot, authenticated.finalizedPoolSnapshot.policy) || !sameE1TreeHeader(snapshot, authenticated.finalizedPoolSnapshot.e1Tree, program, poolKey) || paymentSettler !== void 0 && snapshot.paymentSettler?.toBase58() !== paymentSettler) {
|
|
53882
53948
|
throw Object.assign(
|
|
53883
53949
|
new Error("p03_history_refresh_transition_detected"),
|
|
53884
|
-
{ currentIndex: snapshot.currentIndex, snapshotBinding: { programId: b58(program), pool: poolKey.toBase58() } }
|
|
53950
|
+
{ currentIndex: snapshot.currentIndex, snapshotSlot: snapshot.slot, snapshotBinding: { programId: b58(program), pool: poolKey.toBase58() } }
|
|
53885
53951
|
);
|
|
53886
53952
|
}
|
|
53887
53953
|
const priorCoverage = authenticated.deploymentCoverage;
|
|
@@ -54131,7 +54197,8 @@ async function readFinalizedPoolSliced(connection, program, pool2) {
|
|
|
54131
54197
|
} catch {
|
|
54132
54198
|
snapshot = void 0;
|
|
54133
54199
|
}
|
|
54134
|
-
|
|
54200
|
+
if (snapshot === void 0) markPhase("pool-sliced-fallback-answer");
|
|
54201
|
+
else markPhase("pool-sliced", poolReadOutcome(snapshot.slot));
|
|
54135
54202
|
return snapshot;
|
|
54136
54203
|
}
|
|
54137
54204
|
async function readFinalizedPoolForRefresh(connection, program, pool2) {
|
|
@@ -57150,6 +57217,16 @@ function rewriteFoldRoots(pool2, cache, next) {
|
|
|
57150
57217
|
})().catch(() => {
|
|
57151
57218
|
});
|
|
57152
57219
|
}
|
|
57220
|
+
function dropCompactCacheRecords(pool2, cache) {
|
|
57221
|
+
if (cache === void 0 || cache === null) return Promise.resolve();
|
|
57222
|
+
return (async () => {
|
|
57223
|
+
const current = await cache.load();
|
|
57224
|
+
if (!current || current.pool !== pool2) return;
|
|
57225
|
+
const { foldRoots, savedAt, served, ...rest } = current;
|
|
57226
|
+
await cache.save({ ...rest, served: servedWithoutRecords(served) }, { savedAt });
|
|
57227
|
+
})().catch(() => {
|
|
57228
|
+
});
|
|
57229
|
+
}
|
|
57153
57230
|
function markFoldRootsVerified(pool2, cache) {
|
|
57154
57231
|
rewriteFoldRoots(pool2, cache, (foldRoots) => {
|
|
57155
57232
|
const hashed = lastFolds.get(pool2);
|
|
@@ -57224,12 +57301,12 @@ function canonicalAddress(value, label) {
|
|
|
57224
57301
|
}
|
|
57225
57302
|
throw refuse3("p03_compact_history_record_invalid");
|
|
57226
57303
|
}
|
|
57227
|
-
function validateImport(raw, from) {
|
|
57304
|
+
function validateImport(raw, from, size = P03_COMPACT_PAGE) {
|
|
57228
57305
|
const invalid5 = () => refuse3("p03_compact_history_source_answer_invalid");
|
|
57229
57306
|
if (raw === null || typeof raw !== "object" || Array.isArray(raw) || Object.keys(raw).sort().join(",") !== IMPORT_KEYS.join(",")) throw invalid5();
|
|
57230
57307
|
const { afterOrdinal, record, values, signature: signature2, slot: slot3, transactionIndex, instructionIndex } = raw;
|
|
57231
57308
|
if (!isIndex(afterOrdinal) || !isSignature(signature2) || !isIndex(slot3) || !isIndex(transactionIndex) || !isIndex(instructionIndex)) throw invalid5();
|
|
57232
|
-
if (from !== void 0 && !(afterOrdinal > from && afterOrdinal <= from +
|
|
57309
|
+
if (from !== void 0 && !(afterOrdinal > from && afterOrdinal <= from + size || from === 0 && afterOrdinal === 0)) {
|
|
57233
57310
|
throw invalid5();
|
|
57234
57311
|
}
|
|
57235
57312
|
if (!Array.isArray(values) || values.length > IMPORT_MAX_VALUES) throw invalid5();
|
|
@@ -57509,8 +57586,70 @@ function requestCompactFirstPage({ history, pool: pool2, signal }) {
|
|
|
57509
57586
|
return Promise.resolve({ error });
|
|
57510
57587
|
}
|
|
57511
57588
|
}
|
|
57512
|
-
function pageShapeValid(result, pool2, from) {
|
|
57513
|
-
return Boolean(result) && typeof result === "object" && result.pool === pool2 && result.fromOrdinal === from && isIndex(result.total) && isIndex(result.syncedSlot) && Array.isArray(result.records) && result.records.length === Math.max(0, Math.min(result.total, from +
|
|
57589
|
+
function pageShapeValid(result, pool2, from, size = P03_COMPACT_PAGE) {
|
|
57590
|
+
return Boolean(result) && typeof result === "object" && result.pool === pool2 && result.fromOrdinal === from && isIndex(result.total) && isIndex(result.syncedSlot) && Array.isArray(result.records) && result.records.length === Math.max(0, Math.min(result.total, from + size) - from) && Boolean(result.initialization) && isSignature(result.initialization.signature) && isIndex(result.initialization.slot);
|
|
57591
|
+
}
|
|
57592
|
+
function requestTailPage(history, pool2, from, grid) {
|
|
57593
|
+
return Promise.resolve().then(() => history._rpcRequest("getP03Transitions", [pool2, { commitment: "finalized", fromOrdinal: from, toOrdinal: from + grid }])).then((response) => ({ response }), (error) => ({ error }));
|
|
57594
|
+
}
|
|
57595
|
+
function requestCompactTailPage({ history, pool: pool2, currentIndex }) {
|
|
57596
|
+
try {
|
|
57597
|
+
const count2 = Number(BigInt(currentIndex) / SUBTREE_LEAVES3);
|
|
57598
|
+
if (!Number.isSafeInteger(count2) || count2 === 0) return Promise.resolve({ error: new Error("no records") });
|
|
57599
|
+
const source = typeof history === "string" ? connect2(history, "finalized", { timeoutMs: HISTORY_RPC_REQUEST_TIMEOUT_MS }) : history;
|
|
57600
|
+
if (!source || typeof source._rpcRequest !== "function") return Promise.resolve({ error: refuse3("p03_compact_history_connection_invalid") });
|
|
57601
|
+
return requestTailPage(source, new import_web397.PublicKey(pool2).toBase58(), tailFrom(count2, P03_COMPACT_TAIL_GRID), P03_COMPACT_TAIL_GRID);
|
|
57602
|
+
} catch (error) {
|
|
57603
|
+
return Promise.resolve({ error });
|
|
57604
|
+
}
|
|
57605
|
+
}
|
|
57606
|
+
function combineCompactTail(prefix, answer, { pool: pool2, from, count: count2, grid }) {
|
|
57607
|
+
if (answer.error !== void 0) return { miss: "fetch-failed" };
|
|
57608
|
+
const { response } = answer;
|
|
57609
|
+
if (response === null || typeof response !== "object" || "error" in response) return { miss: "fetch-failed" };
|
|
57610
|
+
const result = response.result;
|
|
57611
|
+
if (!pageShapeValid(result, pool2, from, grid)) return { miss: "shape-invalid" };
|
|
57612
|
+
if (result.total < count2) return { miss: "behind" };
|
|
57613
|
+
if (result.initialization.signature !== prefix.initialization.signature || result.initialization.slot !== prefix.initialization.slot) {
|
|
57614
|
+
return { miss: "init-mismatch" };
|
|
57615
|
+
}
|
|
57616
|
+
if (isIndex(prefix.syncedSlot) && result.syncedSlot < prefix.syncedSlot) return { miss: "synced-older" };
|
|
57617
|
+
let tailImports = [];
|
|
57618
|
+
if (result.imports !== void 0) {
|
|
57619
|
+
if (!Array.isArray(result.imports)) return { miss: "import-invalid" };
|
|
57620
|
+
try {
|
|
57621
|
+
for (const entry of result.imports) validateImport(entry, from, grid);
|
|
57622
|
+
} catch {
|
|
57623
|
+
return { miss: "import-invalid" };
|
|
57624
|
+
}
|
|
57625
|
+
tailImports = result.imports;
|
|
57626
|
+
}
|
|
57627
|
+
const cachedImports = Array.isArray(prefix.imports) ? prefix.imports : [];
|
|
57628
|
+
const held = Math.min(prefix.records.length, count2);
|
|
57629
|
+
for (let ordinal = from; ordinal < held; ordinal += 1) {
|
|
57630
|
+
if (!sameJson(prefix.records[ordinal], result.records[ordinal - from])) return { miss: "overlap-mismatch" };
|
|
57631
|
+
}
|
|
57632
|
+
const between = (entry) => entry?.afterOrdinal > from && entry.afterOrdinal < held;
|
|
57633
|
+
if (!sameJson(cachedImports.filter(between), tailImports.filter(between))) return { miss: "overlap-mismatch" };
|
|
57634
|
+
return { page: {
|
|
57635
|
+
records: [...prefix.records.slice(0, from), ...result.records.slice(0, count2 - from)],
|
|
57636
|
+
imports: [...from === 0 ? [] : cachedImports.filter((entry) => entry?.afterOrdinal <= from), ...tailImports],
|
|
57637
|
+
initialization: result.initialization,
|
|
57638
|
+
syncedSlot: result.syncedSlot
|
|
57639
|
+
} };
|
|
57640
|
+
}
|
|
57641
|
+
function comparePageZero(first, prefix, { pool: pool2, from }) {
|
|
57642
|
+
return first.then((answer) => {
|
|
57643
|
+
const result = answer?.response?.result;
|
|
57644
|
+
if (answer?.error !== void 0 || !pageShapeValid(result, pool2, 0)) return "unavailable";
|
|
57645
|
+
const upTo = Math.min(from, result.records.length);
|
|
57646
|
+
for (let ordinal = 0; ordinal < upTo; ordinal += 1) {
|
|
57647
|
+
if (!sameJson(prefix.records[ordinal], result.records[ordinal])) return "mismatch";
|
|
57648
|
+
}
|
|
57649
|
+
const reach = result.total > upTo ? upTo : upTo - 1;
|
|
57650
|
+
const imports = (list) => (Array.isArray(list) ? list : []).filter((entry) => entry?.afterOrdinal <= reach);
|
|
57651
|
+
return sameJson(imports(prefix.imports), imports(result.imports)) ? "match" : "mismatch";
|
|
57652
|
+
}, () => "unavailable");
|
|
57514
57653
|
}
|
|
57515
57654
|
function isCompactPageZeroAnswer(response, pool2) {
|
|
57516
57655
|
if (response === null || typeof response !== "object" || "error" in response) return false;
|
|
@@ -57882,7 +58021,19 @@ async function readCompactP03HistoryNow({
|
|
|
57882
58021
|
// check: they are NOT verified yet. A payment asks the memo service for their memos here
|
|
57883
58022
|
// (payAndFetch.mjs), and uses an answer only for a context the verified report names. Its
|
|
57884
58023
|
// result and any throw are ignored.
|
|
57885
|
-
onList
|
|
58024
|
+
onList,
|
|
58025
|
+
// compactP03HistoryReport: the records of a compact cache that is not warm (cached.served). When the
|
|
58026
|
+
// list is read (no knownSnapshot), these records (or `served`'s, when the pool outgrew them) that pass
|
|
58027
|
+
// the start of the pool's last grid page take that page instead of every page (3b, combineCompactTail);
|
|
58028
|
+
// page 0 still goes out and is read to its end.
|
|
58029
|
+
prefix,
|
|
58030
|
+
// The tail page's size; P03_COMPACT_TAIL_GRID outside tests.
|
|
58031
|
+
tailGrid = P03_COMPACT_TAIL_GRID,
|
|
58032
|
+
// false: no tail request (compactP03HistoryReport's read again after a refused tail hit; it sent its tail already).
|
|
58033
|
+
tail = true,
|
|
58034
|
+
// compactP03HistoryReport: called on a tail hit with { first (page 0's answer promise), snapshot (the pool
|
|
58035
|
+
// account read) }, so a refused list can be read again from that same page 0 and pool read.
|
|
58036
|
+
onTailHit
|
|
57886
58037
|
}) {
|
|
57887
58038
|
const program = new import_web397.PublicKey(programId);
|
|
57888
58039
|
const poolKey = new import_web397.PublicKey(pool2);
|
|
@@ -57909,24 +58060,63 @@ async function readCompactP03HistoryNow({
|
|
|
57909
58060
|
}
|
|
57910
58061
|
}
|
|
57911
58062
|
snapshot ??= await readFinalizedPool(own, program, poolKey, { treeSlices: true });
|
|
57912
|
-
markPhase(knownSnapshot !== void 0 ? "compact-pool-reused" : "compact-pool");
|
|
58063
|
+
markPhase(knownSnapshot !== void 0 ? "compact-pool-reused" : "compact-pool", poolReadOutcome(snapshot.slot));
|
|
57913
58064
|
if (snapshot.terminal) throw refuse3("p03_compact_history_pool_terminal");
|
|
57914
58065
|
if (snapshot.currentIndex % SUBTREE_LEAVES3 !== 0n) throw refuse3("p03_compact_history_snapshot_invalid");
|
|
57915
58066
|
const count2 = Number(snapshot.currentIndex / SUBTREE_LEAVES3);
|
|
57916
58067
|
if (!Number.isSafeInteger(count2)) throw refuse3("p03_compact_history_snapshot_invalid");
|
|
57917
58068
|
const anchors = freezeFinalizedAnchors(snapshot);
|
|
57918
|
-
const readServedPages = () => {
|
|
58069
|
+
const readServedPages = (zero = first) => {
|
|
57919
58070
|
if (reusedFirst !== void 0) markPhase("compact-behind-page0-reused");
|
|
57920
58071
|
if (first === void 0 && preFirst !== void 0) markPhase("compact-page0-handed-over");
|
|
57921
|
-
return readPages(source, poolString, count2,
|
|
58072
|
+
return readPages(source, poolString, count2, zero ?? preFirst, { wakeSlot: snapshot.slot });
|
|
58073
|
+
};
|
|
58074
|
+
let prefixCheck;
|
|
58075
|
+
const readTailOrPages = async () => {
|
|
58076
|
+
if (knownSnapshot !== void 0 || !tail) return readServedPages();
|
|
58077
|
+
const zero = first ?? preFirst ?? requestPage(source, poolString, 0);
|
|
58078
|
+
if (first === void 0 && preFirst === void 0) markPhase("compact-page0-sent");
|
|
58079
|
+
const from = tailFrom(count2, tailGrid);
|
|
58080
|
+
const tailRead = requestTailPage(source, poolString, from, tailGrid);
|
|
58081
|
+
markPhase("compact-tail-sent");
|
|
58082
|
+
const cachedRecords = served ?? prefix;
|
|
58083
|
+
if (!Array.isArray(cachedRecords?.records) || !cachedRecords.initialization) {
|
|
58084
|
+
markPhase("compact-tail-miss-no-cache");
|
|
58085
|
+
return readServedPages(zero);
|
|
58086
|
+
}
|
|
58087
|
+
if (cachedRecords.records.length <= from) {
|
|
58088
|
+
markPhase("compact-tail-miss-k-not-above-from");
|
|
58089
|
+
return readServedPages(zero);
|
|
58090
|
+
}
|
|
58091
|
+
if (await Promise.race([zero.then((answer) => answer.error === void 0), tailRead.then(() => false)])) {
|
|
58092
|
+
markPhase("compact-tail-miss-page0-first");
|
|
58093
|
+
return readServedPages(zero);
|
|
58094
|
+
}
|
|
58095
|
+
const combined = combineCompactTail(cachedRecords, await tailRead, { pool: poolString, from, count: count2, grid: tailGrid });
|
|
58096
|
+
if (combined.miss !== void 0) {
|
|
58097
|
+
markPhase(`compact-tail-miss-${combined.miss}`);
|
|
58098
|
+
return readServedPages(zero);
|
|
58099
|
+
}
|
|
58100
|
+
markPhase("compact-tail-hit");
|
|
58101
|
+
prefixCheck = comparePageZero(zero, cachedRecords, { pool: poolString, from });
|
|
58102
|
+
try {
|
|
58103
|
+
onTailHit?.({ first: zero, snapshot, check: prefixCheck });
|
|
58104
|
+
} catch {
|
|
58105
|
+
}
|
|
58106
|
+
return combined.page;
|
|
57922
58107
|
};
|
|
57923
|
-
const
|
|
58108
|
+
const servedReaches = count2 > 0 && served !== void 0 && Array.isArray(served.records) && served.records.length >= count2 && Boolean(served.initialization);
|
|
58109
|
+
if (servedReaches && knownSnapshot === void 0 && tail && (first !== void 0 || preFirst !== void 0)) {
|
|
58110
|
+
requestTailPage(source, poolString, tailFrom(count2, tailGrid), tailGrid);
|
|
58111
|
+
markPhase("compact-tail-sent-unused");
|
|
58112
|
+
}
|
|
58113
|
+
const page = count2 === 0 ? { records: [], imports: [], initialization: void 0, syncedSlot: void 0 } : servedReaches ? {
|
|
57924
58114
|
records: served.records.slice(0, count2),
|
|
57925
58115
|
imports: Array.isArray(served.imports) ? served.imports : [],
|
|
57926
58116
|
initialization: served.initialization,
|
|
57927
58117
|
syncedSlot: served.syncedSlot,
|
|
57928
58118
|
cached: true
|
|
57929
|
-
} : await
|
|
58119
|
+
} : await readTailOrPages().catch((error) => {
|
|
57930
58120
|
if (error?.compactHistoryRefusal === "p03_compact_history_source_behind") error.behindSnapshot = snapshot;
|
|
57931
58121
|
throw error;
|
|
57932
58122
|
});
|
|
@@ -58085,7 +58275,9 @@ async function readCompactP03HistoryNow({
|
|
|
58085
58275
|
...page.imports.length > 0 ? { imports: page.imports } : {},
|
|
58086
58276
|
initialization: page.initialization,
|
|
58087
58277
|
syncedSlot: page.syncedSlot
|
|
58088
|
-
})
|
|
58278
|
+
}),
|
|
58279
|
+
// 3b, a tail hit only: resolves "match", "mismatch" or "unavailable" when page 0 has come in full (comparePageZero).
|
|
58280
|
+
...prefixCheck !== void 0 ? { prefixCheck } : {}
|
|
58089
58281
|
});
|
|
58090
58282
|
}
|
|
58091
58283
|
function refusalReason(error) {
|
|
@@ -58116,7 +58308,8 @@ async function compactP03HistoryReportRun({
|
|
|
58116
58308
|
knownFirst,
|
|
58117
58309
|
poolPreRead,
|
|
58118
58310
|
firstPreRead,
|
|
58119
|
-
onList
|
|
58311
|
+
onList,
|
|
58312
|
+
tailGrid
|
|
58120
58313
|
}) {
|
|
58121
58314
|
if (deploymentIdentity === void 0) throw new Error("p03_history_deployment_identity_required");
|
|
58122
58315
|
const program = new import_web397.PublicKey(programId);
|
|
@@ -58189,7 +58382,7 @@ async function compactP03HistoryReportRun({
|
|
|
58189
58382
|
};
|
|
58190
58383
|
const preFold = cached ? startCompactPreFold(poolKey.toBase58(), cached) : void 0;
|
|
58191
58384
|
const e1Ahead = cached ? startCompactE1Candidate(program.toBase58(), poolKey.toBase58(), cached, preFold) : void 0;
|
|
58192
|
-
const
|
|
58385
|
+
const readOnce = (extra) => readCompactP03History({
|
|
58193
58386
|
history,
|
|
58194
58387
|
own: connection,
|
|
58195
58388
|
programId,
|
|
@@ -58203,8 +58396,48 @@ async function compactP03HistoryReportRun({
|
|
|
58203
58396
|
...firstPreRead !== void 0 ? { firstPreRead } : {},
|
|
58204
58397
|
...onList !== void 0 ? { onList } : {},
|
|
58205
58398
|
...warm ? { served: cached.served } : {},
|
|
58206
|
-
...cached ? { initialization: cached.initialization } : {}
|
|
58399
|
+
...cached ? { initialization: cached.initialization } : {},
|
|
58400
|
+
...tailGrid !== void 0 ? { tailGrid } : {},
|
|
58401
|
+
...extra
|
|
58207
58402
|
});
|
|
58403
|
+
let pageZeroMismatch = false;
|
|
58404
|
+
let readAgain = false;
|
|
58405
|
+
let replaced = false;
|
|
58406
|
+
let saving;
|
|
58407
|
+
let dropping;
|
|
58408
|
+
const watchPageZero = (check) => check.then((result) => {
|
|
58409
|
+
markPhase(`compact-page0-compare-${result}`);
|
|
58410
|
+
if (result !== "mismatch") return;
|
|
58411
|
+
try {
|
|
58412
|
+
process.stderr.write("history: WARNING the history source's page 0 differs from this wallet's cached records before the pool's last page; the cache's records are replaced or dropped so the next read takes every page\n");
|
|
58413
|
+
} catch {
|
|
58414
|
+
}
|
|
58415
|
+
pageZeroMismatch = true;
|
|
58416
|
+
if (replaced) return;
|
|
58417
|
+
if (!readAgain) lastFolds.delete(poolKey.toBase58());
|
|
58418
|
+
const drop = () => replaced ? void 0 : dropCompactCacheRecords(poolKey.toBase58(), cache);
|
|
58419
|
+
dropping = (saving ?? Promise.resolve()).then(drop, drop);
|
|
58420
|
+
}).catch(() => {
|
|
58421
|
+
});
|
|
58422
|
+
let tailHit;
|
|
58423
|
+
let compact;
|
|
58424
|
+
try {
|
|
58425
|
+
compact = await readOnce(cached ? { ...warm ? {} : { prefix: cached.served }, onTailHit: (hit) => {
|
|
58426
|
+
tailHit = hit;
|
|
58427
|
+
watchPageZero(hit.check);
|
|
58428
|
+
} } : {});
|
|
58429
|
+
} catch (error) {
|
|
58430
|
+
if (tailHit === void 0 || !TAIL_RETRY_REFUSALS.has(error?.compactHistoryRefusal)) throw error;
|
|
58431
|
+
markPhase("compact-tail-refused-page0");
|
|
58432
|
+
readAgain = true;
|
|
58433
|
+
lastFolds.delete(poolKey.toBase58());
|
|
58434
|
+
try {
|
|
58435
|
+
process.stderr.write(`history: WARNING this wallet's cached records with the pool's last page failed a check (${error.compactHistoryRefusal}); reading every page again
|
|
58436
|
+
`);
|
|
58437
|
+
} catch {
|
|
58438
|
+
}
|
|
58439
|
+
compact = await readOnce({ firstPreRead: tailHit.first, poolPreRead: Promise.resolve(tailHit.snapshot), tail: false });
|
|
58440
|
+
}
|
|
58208
58441
|
const initialization = compact.verifiedInitialization;
|
|
58209
58442
|
if (initialization === void 0) throw refuse3("p03_compact_history_pool_empty");
|
|
58210
58443
|
const snapshot = compact.poolSnapshot;
|
|
@@ -58267,8 +58500,9 @@ async function compactP03HistoryReportRun({
|
|
|
58267
58500
|
});
|
|
58268
58501
|
}
|
|
58269
58502
|
if (cache) {
|
|
58503
|
+
if (dropping !== void 0) await dropping;
|
|
58270
58504
|
try {
|
|
58271
|
-
await cache.save({
|
|
58505
|
+
await (saving = Promise.resolve().then(() => cache.save({
|
|
58272
58506
|
programId: program.toBase58(),
|
|
58273
58507
|
pool: poolKey.toBase58(),
|
|
58274
58508
|
snapshot: {
|
|
@@ -58280,10 +58514,12 @@ async function compactP03HistoryReportRun({
|
|
|
58280
58514
|
// pre-fold hashes their roots ahead. Counts only: every root is checked live again.
|
|
58281
58515
|
anchorCounts: [...new Set(compact.finalizedPoolSnapshot.anchors.map((anchor) => Number(anchor.index / SUBTREE_LEAVES3)))]
|
|
58282
58516
|
},
|
|
58283
|
-
served: compact.served,
|
|
58517
|
+
served: pageZeroMismatch && !readAgain ? servedWithoutRecords(compact.served) : compact.served,
|
|
58284
58518
|
initialization,
|
|
58285
58519
|
attestation: attested.attestation
|
|
58286
|
-
})
|
|
58520
|
+
})).then(() => {
|
|
58521
|
+
if (readAgain) replaced = true;
|
|
58522
|
+
}));
|
|
58287
58523
|
} catch {
|
|
58288
58524
|
}
|
|
58289
58525
|
}
|
|
@@ -58304,7 +58540,7 @@ async function tryCompactP03HistoryReport(options) {
|
|
|
58304
58540
|
return { ok: false, reason, ...detail ? { detail } : {}, error };
|
|
58305
58541
|
}
|
|
58306
58542
|
}
|
|
58307
|
-
var import_web397, P03_COMPACT_HISTORY_SOURCE_MODEL, P03_COMPACT_PAGE, P03_COMPACT_SPOT_CHECKS, FIELD_MODULUS5, SUBTREE_LEAVES3, LOCAL_DEPTH2, OUTER_DEPTH2, PRIMARY_PROOF_BYTES2, FIELD_BYTES3, ED25519_SPKI_PREFIX2, VERSION_1_PREFIX2, HEX64, BASE58, REPLAY_STORE_INDEXED2, PROFILES2, MOVE_HEAD_BYTES2, MOVE_INSERTED_VALUES2, refuse3, hash4, bitAt, zeroRootsMemo, lastFolds, PRE_FOLD_SLICE_MS, preFolds, hex64, droppedPools, verifyQuietMs, VERIFY_SLICE_MS, VERIFY_POLL_MS, verifying, unrefTurn, isSignature, isIndex, IMPORT_KEYS, IMPORT_MAX_VALUES, LIST_ATTEMPTS, pageZeroInFlight, OWN_READ_TIMEOUT_MS, BOUNDED_OWN_METHODS, SPOT_HEDGE_AFTER_MS, SPOT_HEDGE_LANE, spotReadId, POOL_HEDGE_AFTER_MS, POOL_HEDGE_LANE, poolReadId, compactReportsRunning, compactHistoryReadsRunning;
|
|
58543
|
+
var import_web397, P03_COMPACT_HISTORY_SOURCE_MODEL, P03_COMPACT_PAGE, P03_COMPACT_SPOT_CHECKS, FIELD_MODULUS5, SUBTREE_LEAVES3, LOCAL_DEPTH2, OUTER_DEPTH2, PRIMARY_PROOF_BYTES2, FIELD_BYTES3, ED25519_SPKI_PREFIX2, VERSION_1_PREFIX2, HEX64, BASE58, REPLAY_STORE_INDEXED2, PROFILES2, MOVE_HEAD_BYTES2, MOVE_INSERTED_VALUES2, refuse3, hash4, bitAt, zeroRootsMemo, lastFolds, PRE_FOLD_SLICE_MS, preFolds, hex64, droppedPools, servedWithoutRecords, verifyQuietMs, VERIFY_SLICE_MS, VERIFY_POLL_MS, verifying, unrefTurn, isSignature, isIndex, IMPORT_KEYS, IMPORT_MAX_VALUES, LIST_ATTEMPTS, pageZeroInFlight, OWN_READ_TIMEOUT_MS, BOUNDED_OWN_METHODS, P03_COMPACT_TAIL_GRID, TAIL_RETRY_REFUSALS, tailFrom, sameJson, SPOT_HEDGE_AFTER_MS, SPOT_HEDGE_LANE, spotReadId, POOL_HEDGE_AFTER_MS, POOL_HEDGE_LANE, poolReadId, compactReportsRunning, compactHistoryReadsRunning;
|
|
58308
58544
|
var init_compact = __esm({
|
|
58309
58545
|
"wallet/src/history/compact.mjs"() {
|
|
58310
58546
|
"use strict";
|
|
@@ -58421,6 +58657,11 @@ var init_compact = __esm({
|
|
|
58421
58657
|
preFolds = /* @__PURE__ */ new Map();
|
|
58422
58658
|
hex64 = (value) => value.toString(16).padStart(64, "0");
|
|
58423
58659
|
droppedPools = /* @__PURE__ */ new Set();
|
|
58660
|
+
servedWithoutRecords = (served) => ({
|
|
58661
|
+
records: [],
|
|
58662
|
+
initialization: served.initialization,
|
|
58663
|
+
...served.syncedSlot !== void 0 ? { syncedSlot: served.syncedSlot } : {}
|
|
58664
|
+
});
|
|
58424
58665
|
verifyQuietMs = 3e3;
|
|
58425
58666
|
VERIFY_SLICE_MS = 20;
|
|
58426
58667
|
VERIFY_POLL_MS = 250;
|
|
@@ -58437,6 +58678,17 @@ var init_compact = __esm({
|
|
|
58437
58678
|
pageZeroInFlight = /* @__PURE__ */ new Map();
|
|
58438
58679
|
OWN_READ_TIMEOUT_MS = HISTORY_RPC_REQUEST_TIMEOUT_MS;
|
|
58439
58680
|
BOUNDED_OWN_METHODS = /* @__PURE__ */ new Set(["getAccountInfo", "getAccountInfoAndContext", "getMultipleAccountsInfo", "getMultipleAccountsInfoAndContext"]);
|
|
58681
|
+
P03_COMPACT_TAIL_GRID = 512;
|
|
58682
|
+
TAIL_RETRY_REFUSALS = /* @__PURE__ */ new Set([
|
|
58683
|
+
"p03_compact_history_root_mismatch",
|
|
58684
|
+
"p03_compact_history_kind_count_mismatch",
|
|
58685
|
+
"p03_compact_history_record_order_invalid",
|
|
58686
|
+
"p03_compact_history_record_invalid",
|
|
58687
|
+
"p03_compact_history_record_after_snapshot",
|
|
58688
|
+
"p03_compact_history_source_answer_invalid"
|
|
58689
|
+
]);
|
|
58690
|
+
tailFrom = (count2, grid) => Math.floor((count2 - 1) / grid) * grid;
|
|
58691
|
+
sameJson = (left, right) => JSON.stringify(left) === JSON.stringify(right);
|
|
58440
58692
|
SPOT_HEDGE_AFTER_MS = 4e3;
|
|
58441
58693
|
SPOT_HEDGE_LANE = "spot-hedge";
|
|
58442
58694
|
spotReadId = 0;
|
|
@@ -59241,7 +59493,7 @@ async function walkWalletP03HistoryNow({ store, connection: given, programId, po
|
|
|
59241
59493
|
} else if (earlier !== void 0) {
|
|
59242
59494
|
markPhase("refresh-start");
|
|
59243
59495
|
let slicedPreRead;
|
|
59244
|
-
let
|
|
59496
|
+
let page0Asked = false;
|
|
59245
59497
|
let page0Answered = false;
|
|
59246
59498
|
if (compactNext) {
|
|
59247
59499
|
const started = startCompactPoolSnapshot({ connection, programId, pool: pool2 });
|
|
@@ -59249,8 +59501,8 @@ async function walkWalletP03HistoryNow({ store, connection: given, programId, po
|
|
|
59249
59501
|
poolPreRead = started.full;
|
|
59250
59502
|
markPhase("compact-pool-prestarted");
|
|
59251
59503
|
if (inTorRun() || Date.now() - remembered.at > PAGE0_PREREAD_AFTER_MS) {
|
|
59252
|
-
|
|
59253
|
-
firstPreRead = requestCompactFirstPage({ history: connection.historyRpcSource, pool: pool2
|
|
59504
|
+
page0Asked = true;
|
|
59505
|
+
firstPreRead = requestCompactFirstPage({ history: connection.historyRpcSource, pool: pool2 });
|
|
59254
59506
|
firstPreRead.then(() => {
|
|
59255
59507
|
page0Answered = true;
|
|
59256
59508
|
});
|
|
@@ -59278,19 +59530,23 @@ async function walkWalletP03HistoryNow({ store, connection: given, programId, po
|
|
|
59278
59530
|
})();
|
|
59279
59531
|
try {
|
|
59280
59532
|
const refreshed = await refreshing;
|
|
59281
|
-
markPhase("walk-refreshed");
|
|
59282
|
-
if (
|
|
59283
|
-
markPhase(page0Answered ? "compact-page0-answered-before-hit" : "compact-page0-
|
|
59284
|
-
|
|
59533
|
+
markPhase("walk-refreshed", poolReadOutcome(refreshed?.finalizedPoolSnapshot?.slot));
|
|
59534
|
+
if (page0Asked) {
|
|
59535
|
+
markPhase(page0Answered ? "compact-page0-answered-before-hit" : "compact-page0-read-on-after-hit");
|
|
59536
|
+
const currentIndex = refreshed?.finalizedPoolSnapshot?.currentIndex;
|
|
59537
|
+
if (typeof currentIndex === "bigint" && currentIndex > 0n) {
|
|
59538
|
+
requestCompactTailPage({ history: connection.historyRpcSource, pool: pool2, currentIndex });
|
|
59539
|
+
markPhase("compact-tail-sent-on-hit");
|
|
59540
|
+
}
|
|
59285
59541
|
}
|
|
59286
59542
|
rememberRunReport(runKey, refreshed);
|
|
59287
59543
|
writeStderr("history: the pool made no transition since this run's last walk; that history was moved to the current pool account " + (fromSliced ? "(your own RPC read the pool account and the program's deployment account in one request)\n" : "(your own RPC read the pool account and the program's deployment account; the history source answered one signature read)\n"));
|
|
59288
59544
|
return refreshed;
|
|
59289
59545
|
} catch (error) {
|
|
59290
|
-
|
|
59291
|
-
|
|
59292
|
-
|
|
59293
|
-
|
|
59546
|
+
const moved = error?.message === "p03_history_refresh_transition_detected" && typeof error.currentIndex === "bigint" && error.snapshotBinding?.programId === String(programId) && error.snapshotBinding?.pool === String(pool2);
|
|
59547
|
+
const earlierIndex = earlier.finalizedPoolSnapshot?.currentIndex;
|
|
59548
|
+
markPhase("refresh-missed", moved ? poolReadOutcome(error.snapshotSlot, typeof earlierIndex === "bigint" ? Number((error.currentIndex - earlierIndex) / SUBTREE_LEAVES4) : void 0) : void 0);
|
|
59549
|
+
if (moved) movedIndex = error.currentIndex;
|
|
59294
59550
|
floor?.reset();
|
|
59295
59551
|
if (strict) floor?.strict();
|
|
59296
59552
|
}
|
|
@@ -73866,6 +74122,10 @@ async function runRecoveredP03NoteExit({
|
|
|
73866
74122
|
photonUrl,
|
|
73867
74123
|
// Parsed --recovered-note-file (recoveredNotesFromFile): notes the walk cannot find.
|
|
73868
74124
|
recoveredNoteFile,
|
|
74125
|
+
// Relay path only (realSpeed3 2026-10-22, mcp55 Part 1): return once the relay answered (it answers only after the
|
|
74126
|
+
// exit is finalized) and the "confirmed" record holds the signature, with `settled: false` and `finish`, the post-exit
|
|
74127
|
+
// walk and postcondition below. The caller runs `finish` after its own answer; a rerun of this exit resumes the same way.
|
|
74128
|
+
answerAtRelay = false,
|
|
73869
74129
|
deps = {}
|
|
73870
74130
|
}) {
|
|
73871
74131
|
const state = store.state;
|
|
@@ -74295,39 +74555,46 @@ async function runRecoveredP03NoteExit({
|
|
|
74295
74555
|
}
|
|
74296
74556
|
wal = { ...wal, state: "confirmed", signature: signature2 };
|
|
74297
74557
|
store.writeWal(walName2, wal);
|
|
74298
|
-
|
|
74299
|
-
|
|
74300
|
-
|
|
74301
|
-
|
|
74302
|
-
|
|
74303
|
-
|
|
74558
|
+
const preExitHistory = history;
|
|
74559
|
+
const finish = async () => {
|
|
74560
|
+
for (let attempt = 1; ; attempt += 1) {
|
|
74561
|
+
history = await walkHistory();
|
|
74562
|
+
markPhase("exit-post-walk");
|
|
74563
|
+
poolState2 = await readPool2(connection, pool2, "finalized");
|
|
74564
|
+
if (!poolState2 || !poolState2.owner.equals(chainProgramId) || poolState2.version !== 3) {
|
|
74565
|
+
throw new Error("finalized note-exit pool postcondition invalid");
|
|
74566
|
+
}
|
|
74567
|
+
if (attempt >= 4 || history.finalizedPoolSnapshot.currentIndex === poolState2.currentIndex && history.finalizedPoolSnapshot.currentRoot === poolState2.currentRoot) break;
|
|
74304
74568
|
}
|
|
74305
|
-
|
|
74306
|
-
|
|
74307
|
-
|
|
74308
|
-
|
|
74309
|
-
|
|
74310
|
-
|
|
74311
|
-
|
|
74312
|
-
|
|
74313
|
-
|
|
74314
|
-
|
|
74315
|
-
|
|
74569
|
+
await prepareFold(history);
|
|
74570
|
+
const spentPath = buildRecoveryPath({
|
|
74571
|
+
history,
|
|
74572
|
+
recoveredOutput: recoveredForPath,
|
|
74573
|
+
circuitSource: p03CircuitSource,
|
|
74574
|
+
anchor: recoveryPath.anchor
|
|
74575
|
+
});
|
|
74576
|
+
if (spentPath.spendStatus !== "spent" || poolState2.currentIndex < frontier.nextIndex + 128n || history.finalizedPoolSnapshot.currentIndex !== poolState2.currentIndex || history.finalizedPoolSnapshot.currentRoot !== poolState2.currentRoot) {
|
|
74577
|
+
throw new Error("finalized note-exit postcondition failed");
|
|
74578
|
+
}
|
|
74579
|
+
store.writeWal(walName2, { ...wal, state: "settled" });
|
|
74580
|
+
return Object.freeze({
|
|
74581
|
+
signature: signature2,
|
|
74582
|
+
replayed: false,
|
|
74583
|
+
noteCommitment: selected.commitment,
|
|
74584
|
+
amountAtomic: amount,
|
|
74585
|
+
poolIndex: poolState2.currentIndex,
|
|
74586
|
+
manifestSha256: proved.manifestSha256,
|
|
74587
|
+
...denomination.record ? { denominationPolicy: denomination.record } : {},
|
|
74588
|
+
...denominationWarnings.length > 0 ? { denominationWarnings } : {},
|
|
74589
|
+
...foreignRecipient ? { recipientOwner: expectedRecipientOwner.toBase58() } : {},
|
|
74590
|
+
...relayed ? { broadcaster: broadcasterKey } : {},
|
|
74591
|
+
...relaySubmit ? { facilitatorRelay: true } : {}
|
|
74592
|
+
});
|
|
74593
|
+
};
|
|
74594
|
+
if (answerAtRelay === true && relaySubmit) {
|
|
74595
|
+
return Object.freeze({ signature: signature2, settled: false, noteCommitment: selected.commitment, amountAtomic: amount, preExitHistory, finish });
|
|
74316
74596
|
}
|
|
74317
|
-
|
|
74318
|
-
return Object.freeze({
|
|
74319
|
-
signature: signature2,
|
|
74320
|
-
replayed: false,
|
|
74321
|
-
noteCommitment: selected.commitment,
|
|
74322
|
-
amountAtomic: amount,
|
|
74323
|
-
poolIndex: poolState2.currentIndex,
|
|
74324
|
-
manifestSha256: proved.manifestSha256,
|
|
74325
|
-
...denomination.record ? { denominationPolicy: denomination.record } : {},
|
|
74326
|
-
...denominationWarnings.length > 0 ? { denominationWarnings } : {},
|
|
74327
|
-
...foreignRecipient ? { recipientOwner: expectedRecipientOwner.toBase58() } : {},
|
|
74328
|
-
...relayed ? { broadcaster: broadcasterKey } : {},
|
|
74329
|
-
...relaySubmit ? { facilitatorRelay: true } : {}
|
|
74330
|
-
});
|
|
74597
|
+
return finish();
|
|
74331
74598
|
}
|
|
74332
74599
|
function loadBroadcasterKeypairFile(path) {
|
|
74333
74600
|
let text3;
|
|
@@ -95809,11 +96076,11 @@ function dropFloatConfigs() {
|
|
|
95809
96076
|
configCache.clear();
|
|
95810
96077
|
configReads.clear();
|
|
95811
96078
|
}
|
|
95812
|
-
function warmFloatConfig({ origin, fetchImpl = fetch } = {}) {
|
|
96079
|
+
function warmFloatConfig({ origin, fetchImpl = fetch, timing } = {}) {
|
|
95813
96080
|
try {
|
|
95814
96081
|
const kept = configCache.get(origin);
|
|
95815
96082
|
if (kept && Date.now() - kept.readAtMs < CONFIG_CACHE_MS && floatPoolRecentlyUsed(FLOAT_POOL_WARM_MS) || configReads.has(origin)) return;
|
|
95816
|
-
const read =
|
|
96083
|
+
const read = timedConfigRead({ origin, fetchImpl, timing, route: "warm" });
|
|
95817
96084
|
configReads.set(origin, read);
|
|
95818
96085
|
read.then(
|
|
95819
96086
|
() => {
|
|
@@ -95826,6 +96093,18 @@ function warmFloatConfig({ origin, fetchImpl = fetch } = {}) {
|
|
|
95826
96093
|
} catch {
|
|
95827
96094
|
}
|
|
95828
96095
|
}
|
|
96096
|
+
function timedConfigRead({ origin, fetchImpl, timing, route }) {
|
|
96097
|
+
const mark = (phase) => {
|
|
96098
|
+
try {
|
|
96099
|
+
timing?.(phase);
|
|
96100
|
+
} catch {
|
|
96101
|
+
}
|
|
96102
|
+
};
|
|
96103
|
+
mark("float-config-start");
|
|
96104
|
+
const read = readFloatConfig({ origin, fetchImpl });
|
|
96105
|
+
read.then(() => mark(`float-config-answered-${route}`), () => mark(`float-config-failed-${route}`));
|
|
96106
|
+
return read;
|
|
96107
|
+
}
|
|
95829
96108
|
function refreshFloatConfig(origin, fetchImpl) {
|
|
95830
96109
|
try {
|
|
95831
96110
|
if (configRefreshes.has(origin) || configReads.has(origin)) return;
|
|
@@ -95842,19 +96121,32 @@ function refreshKeptFloatConfig({ origin, fetchImpl = fetch } = {}) {
|
|
|
95842
96121
|
} catch {
|
|
95843
96122
|
}
|
|
95844
96123
|
}
|
|
95845
|
-
async function readFloatOffer({ origin, paymentRequired, store, resourceUrl, fetchImpl = fetch }) {
|
|
96124
|
+
async function readFloatOffer({ origin, paymentRequired, store, resourceUrl, fetchImpl = fetch, timing }) {
|
|
96125
|
+
const mark = (phase) => {
|
|
96126
|
+
try {
|
|
96127
|
+
timing?.(phase);
|
|
96128
|
+
} catch {
|
|
96129
|
+
}
|
|
96130
|
+
};
|
|
95846
96131
|
const inFlight = configReads.get(origin);
|
|
95847
96132
|
if (inFlight) await inFlight.catch(() => void 0);
|
|
95848
96133
|
const kept = configCache.get(origin);
|
|
95849
96134
|
if (kept && Date.now() - kept.readAtMs < CONFIG_CACHE_MS) {
|
|
95850
96135
|
try {
|
|
95851
|
-
|
|
96136
|
+
const offer = floatOffer({ paymentRequired, store, config: kept.config, resourceUrl });
|
|
96137
|
+
mark(inFlight ? "float-config-joined-warm" : "float-config-joined-kept");
|
|
96138
|
+
return { offer, config: kept.config };
|
|
95852
96139
|
} catch {
|
|
95853
96140
|
configCache.delete(origin);
|
|
95854
96141
|
}
|
|
95855
96142
|
}
|
|
95856
96143
|
const warm = configReads.get(origin);
|
|
95857
|
-
|
|
96144
|
+
let config = warm ? await warm.catch(() => void 0) : void 0;
|
|
96145
|
+
if (config !== void 0) mark("float-config-joined-warm");
|
|
96146
|
+
else {
|
|
96147
|
+
config = await timedConfigRead({ origin, fetchImpl, timing, route: "read" });
|
|
96148
|
+
mark("float-config-joined-read");
|
|
96149
|
+
}
|
|
95858
96150
|
return { offer: floatOffer({ paymentRequired, store, config, resourceUrl }), config };
|
|
95859
96151
|
}
|
|
95860
96152
|
function keepSellerTerms(origin, url, paymentRequired) {
|
|
@@ -98572,6 +98864,15 @@ async function openPayerSession({
|
|
|
98572
98864
|
notePayHost(memoService);
|
|
98573
98865
|
const connection = connectRelay(rpc2, "finalized");
|
|
98574
98866
|
const timingLog = createTimingLog(`${path}.timing.log`, { component: "payer" });
|
|
98867
|
+
takeSiteOnionRaces().then((races) => {
|
|
98868
|
+
for (const race of races) {
|
|
98869
|
+
const mark = timingLog.start({ startedAt: race.startedAt });
|
|
98870
|
+
mark("onion:race-start", void 0, race.startedAt);
|
|
98871
|
+
for (const probe of race.probes) mark(`onion:${probe.role}-${probe.event}`, void 0, probe.at);
|
|
98872
|
+
mark("onion:race-end", race.answered ? "answered" : "none", race.endedAt);
|
|
98873
|
+
}
|
|
98874
|
+
}).catch(() => {
|
|
98875
|
+
});
|
|
98575
98876
|
let closed = false;
|
|
98576
98877
|
let queue = Promise.resolve();
|
|
98577
98878
|
const session = {
|
|
@@ -98631,6 +98932,7 @@ var init_session = __esm({
|
|
|
98631
98932
|
init_processLease();
|
|
98632
98933
|
init_proxy();
|
|
98633
98934
|
init_keepAlive();
|
|
98935
|
+
init_facilitatorOnion();
|
|
98634
98936
|
RELAY_READ_TIMEOUT_MS = 3e4;
|
|
98635
98937
|
READ_ONLY_METHOD = /^(get[A-Za-z]+|simulateTransaction|isBlockhashValid|minimumLedgerSlot)$/;
|
|
98636
98938
|
connectRelay = (rpcUrl, commitment = "finalized") => connect2(rpcUrl, commitment, { wrapFetch: (fetch2) => relayRpcFetch(fetch2) });
|
|
@@ -103892,7 +104194,7 @@ function hostConfigText({ home, env = process.env, platform = process.platform }
|
|
|
103892
104194
|
function isOlderSetupEntry(existing, entry) {
|
|
103893
104195
|
if (!isPlainObject3(existing) || entry.command !== "npx" || !Array.isArray(entry.args)) return false;
|
|
103894
104196
|
const older = { ...entry, args: entry.args.filter((arg) => !NPX_INSTALL_FLAGS.includes(arg)) };
|
|
103895
|
-
return older.args.length !== entry.args.length &&
|
|
104197
|
+
return older.args.length !== entry.args.length && sameJson2(existing, older);
|
|
103896
104198
|
}
|
|
103897
104199
|
function restrictToOwnerWindows(file, { run: run5 = execFileSync2 } = {}) {
|
|
103898
104200
|
const system32 = join18(process.env.SystemRoot || "C:/Windows", "System32");
|
|
@@ -103925,7 +104227,7 @@ function addToJsonHost(file, entry, { now = /* @__PURE__ */ new Date(), force =
|
|
|
103925
104227
|
}
|
|
103926
104228
|
const existing = current.mcpServers?.[MCP_SERVER_NAME];
|
|
103927
104229
|
if (existing !== void 0) {
|
|
103928
|
-
if (
|
|
104230
|
+
if (sameJson2(existing, entry)) return { file, changed: false };
|
|
103929
104231
|
if (!force && !isOlderSetupEntry(existing, entry)) {
|
|
103930
104232
|
throw new Error(`setup_host_config_conflict: the host's config file already has a different "${MCP_SERVER_NAME}" server, so setup left it alone; rerun setup with --force to replace it (the old file is backed up first), or edit it by hand`);
|
|
103931
104233
|
}
|
|
@@ -103973,7 +104275,7 @@ function addToJsonHost(file, entry, { now = /* @__PURE__ */ new Date(), force =
|
|
|
103973
104275
|
}
|
|
103974
104276
|
return { file, changed: true, ...backup ? { backup } : {} };
|
|
103975
104277
|
}
|
|
103976
|
-
var import_web3118, CONFIG_SCHEMA, CONFIG_FILE, NPX_PACKAGE, NPX_INSTALL_FLAGS, MCP_SERVER_NAME, P03_BINDING2, PRODUCTION, RETIRED_POOLS, NO_LIMIT_ATOMIC2, DEFAULT_CAPS, OLD_DEFAULT_SETUP_CAPS, OLD_DEFAULT_WALLET_BUDGETS, capText, POSITIVE_ATOMIC2, configPath, homeWalletPath, invalid3, isPubkey, HOST_TARGETS, WINDOWS_SHELL_CODE, isPlainObject3,
|
|
104278
|
+
var import_web3118, CONFIG_SCHEMA, CONFIG_FILE, NPX_PACKAGE, NPX_INSTALL_FLAGS, MCP_SERVER_NAME, P03_BINDING2, PRODUCTION, RETIRED_POOLS, NO_LIMIT_ATOMIC2, DEFAULT_CAPS, OLD_DEFAULT_SETUP_CAPS, OLD_DEFAULT_WALLET_BUDGETS, capText, POSITIVE_ATOMIC2, configPath, homeWalletPath, invalid3, isPubkey, HOST_TARGETS, WINDOWS_SHELL_CODE, isPlainObject3, sameJson2;
|
|
103977
104279
|
var init_config2 = __esm({
|
|
103978
104280
|
"wallet/src/setup/config.mjs"() {
|
|
103979
104281
|
"use strict";
|
|
@@ -104024,7 +104326,7 @@ var init_config2 = __esm({
|
|
|
104024
104326
|
HOST_TARGETS = Object.freeze(["claude-code", "claude-desktop", "cursor"]);
|
|
104025
104327
|
WINDOWS_SHELL_CODE = /[%$`"\r\n]/;
|
|
104026
104328
|
isPlainObject3 = (value) => Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
104027
|
-
|
|
104329
|
+
sameJson2 = (a, b) => {
|
|
104028
104330
|
const canonical5 = (value) => Array.isArray(value) ? value.map(canonical5) : isPlainObject3(value) ? Object.fromEntries(Object.keys(value).sort().map((key) => [key, canonical5(value[key])])) : value;
|
|
104029
104331
|
return JSON.stringify(canonical5(a)) === JSON.stringify(canonical5(b));
|
|
104030
104332
|
};
|
|
@@ -104399,6 +104701,20 @@ function computeBalance({ store, snapshotRead, source = "local", now = Date.now(
|
|
|
104399
104701
|
const inputs = provenInputs(byName.get(`resource-proof-${entry.name.slice("resource-payment-".length)}`)?.record);
|
|
104400
104702
|
return Boolean(digest2) && snapshotDigests.has(digest2) && inputs !== void 0 && inputs.length > 0 && inputs.every((commitment) => spentInSnapshot.has(commitment));
|
|
104401
104703
|
};
|
|
104704
|
+
const answeredExits = /* @__PURE__ */ new Map();
|
|
104705
|
+
for (const entry of records) {
|
|
104706
|
+
if (entry.type !== "unshield" || entry.name.startsWith(POCKET_FILL_RECORD) || entry.name.startsWith(MERGE_RECORD) || !Number.isSafeInteger(entry.record.exitAnsweredAtMs) || typeof entry.record.exitTransaction !== "string" || !canonicalAtomic(String(entry.record.noteCommitment ?? ""))) continue;
|
|
104707
|
+
answeredExits.set(String(entry.record.noteCommitment), {
|
|
104708
|
+
changeAtomic: canonicalAtomic(entry.record.changeAtomic) ? BigInt(entry.record.changeAtomic) : 0n,
|
|
104709
|
+
unconfirmed: entry.record.exitUnconfirmed === true
|
|
104710
|
+
});
|
|
104711
|
+
}
|
|
104712
|
+
const answeredSettling = (note, answered) => {
|
|
104713
|
+
const output2 = unspent.get(note);
|
|
104714
|
+
if (output2 === void 0) return void 0;
|
|
104715
|
+
const exited = BigInt(output2.valueAtomic) - answered.changeAtomic;
|
|
104716
|
+
return exited > 0n ? { inputs: [note], amountAtomic: exited, join: false } : void 0;
|
|
104717
|
+
};
|
|
104402
104718
|
for (const entry of records) {
|
|
104403
104719
|
const before = Object.hasOwn(snapshot.walStates, entry.name) ? snapshot.walStates[entry.name] : void 0;
|
|
104404
104720
|
const beforePhase = before === void 0 ? "absent" : entry.type === "payment-proof" ? entry.phase : classify(entry.name, { ...entry.record, state: before }).phase;
|
|
@@ -104406,6 +104722,18 @@ function computeBalance({ store, snapshotRead, source = "local", now = Date.now(
|
|
|
104406
104722
|
const join37 = entry.type === "payment" && joinedAccountOf(entry, byName) !== void 0;
|
|
104407
104723
|
if (entry.phase === "done" && beforePhase !== "done") {
|
|
104408
104724
|
if (join37 && snapshotDigests.has(digestKey(entry.record.memoDigest))) continue;
|
|
104725
|
+
const answeredExit = ["unshield", "note-exit"].includes(entry.type) ? answeredExits.get(String(entry.record.noteCommitment)) : void 0;
|
|
104726
|
+
if (answeredExit !== void 0) {
|
|
104727
|
+
const note = String(entry.record.noteCommitment);
|
|
104728
|
+
if (spentInSnapshot.has(note) || entry.type === "note-exit" && unspent.has(note)) continue;
|
|
104729
|
+
const exiting = answeredSettling(note, answeredExit);
|
|
104730
|
+
if (exiting) {
|
|
104731
|
+
settling.push(exiting);
|
|
104732
|
+
noteSettling(entry.name);
|
|
104733
|
+
settlingReasons.push(`unshield record ${entry.name} was answered after the last refresh: its exit is final on chain and the balance counts it as sent; refresh again in a minute`);
|
|
104734
|
+
continue;
|
|
104735
|
+
}
|
|
104736
|
+
}
|
|
104409
104737
|
const paying = settlingPayment(entry);
|
|
104410
104738
|
if (paying) {
|
|
104411
104739
|
settling.push(paying);
|
|
@@ -104483,6 +104811,24 @@ function computeBalance({ store, snapshotRead, source = "local", now = Date.now(
|
|
|
104483
104811
|
listedNotes.add(note);
|
|
104484
104812
|
const fill = entry.name.startsWith(POCKET_FILL_RECORD);
|
|
104485
104813
|
const merge = entry.name.startsWith(MERGE_RECORD);
|
|
104814
|
+
const answered = answeredExits.get(note);
|
|
104815
|
+
if (answered !== void 0) {
|
|
104816
|
+
const exiting = answered.changeAtomic > 0n && !spentInWalk.has(note) ? answeredSettling(note, answered) : void 0;
|
|
104817
|
+
if (exiting) {
|
|
104818
|
+
settling.push(exiting);
|
|
104819
|
+
noteSettling(entry.name);
|
|
104820
|
+
settlingReasons.push(`unshield record ${entry.name} was answered: its exit is final on chain and the balance counts it as sent; its change becomes spendable at the next refresh`);
|
|
104821
|
+
}
|
|
104822
|
+
detail.inFlight.push({
|
|
104823
|
+
kind: "unshield-exit",
|
|
104824
|
+
state: entry.state,
|
|
104825
|
+
amountAtomic: entry.record.amountAtomic ?? null,
|
|
104826
|
+
answered: true,
|
|
104827
|
+
inputs: exiting ? "settling" : reserve([note], `unshield ${entry.name}`),
|
|
104828
|
+
next: answered.unconfirmed ? "rerun the same unshield command; it resumes the exit (the pool history has not shown this exit as spent for 10 minutes)" : "nothing to do: the exit is final on chain and this wallet checks it against the pool history by itself"
|
|
104829
|
+
});
|
|
104830
|
+
continue;
|
|
104831
|
+
}
|
|
104486
104832
|
const inputs = reserve(
|
|
104487
104833
|
[note],
|
|
104488
104834
|
`unshield ${entry.name}`,
|
|
@@ -104526,7 +104872,8 @@ function computeBalance({ store, snapshotRead, source = "local", now = Date.now(
|
|
|
104526
104872
|
}
|
|
104527
104873
|
const anchorIndex = canonicalAtomic(snapshot.anchorIndex) ? BigInt(snapshot.anchorIndex) : void 0;
|
|
104528
104874
|
detail.fundedAccounts = unknownInputs ? 0 : [...unspent.values()].filter((output2) => output2.kind === "account" && BigInt(output2.valueAtomic) > 0n && !reserved.has(output2.commitment) && !joining.has(output2.commitment) && !settlingInputs.has(output2.commitment) && (anchorIndex === void 0 || BigInt(output2.leafIndex) < anchorIndex)).length;
|
|
104529
|
-
const
|
|
104875
|
+
const answeredOnly = detail.inFlight.length > 0 && detail.inFlight.every((item) => item.answered === true);
|
|
104876
|
+
const next = answeredOnly ? detail.inFlight.find((item) => item.next.startsWith("rerun"))?.next ?? "nothing to do: an answered unshield finishes its check by itself" : detail.inFlight.length ? "finish or cancel the work in detail.inFlight; the wallet runs one payment at a time" : pendingDeposits.length ? `deposit ${pendingDeposits[0].depositId} is not finished: rerun the same deposit command with --submit --service <facilitator URL>` : pocketsUnscanned ? scanPockets2 : unspentAtomic === 0n && successionMovableAtomic > 0n ? "this pool was succeeded by a new pool: its value moves there (a move per account, the facilitator pays the fee) and counts in this balance until then" : unspentAtomic === 0n ? "nothing to spend: deposit (shinjuku-wallet help deposit), or run balance --refresh if a payment to this wallet settled" : void 0;
|
|
104530
104877
|
if (movedInAtomic > 0n) {
|
|
104531
104878
|
settlingReasons.push(`${formatAtomic(movedInAtomic, decimals)} moved into this pool from the old pool after the last refresh: the balance counts it; refresh again in a minute`);
|
|
104532
104879
|
}
|
|
@@ -104661,7 +105008,7 @@ function requestBody(method, body) {
|
|
|
104661
105008
|
if (bytes2.length > 1024 * 1024) fail24("fetch_options_invalid", "the body is over 1 MiB");
|
|
104662
105009
|
return bytes2;
|
|
104663
105010
|
}
|
|
104664
|
-
async function offeredPrice(paymentRequired, store, serviceUrl2, target) {
|
|
105011
|
+
async function offeredPrice(paymentRequired, store, serviceUrl2, target, timing) {
|
|
104665
105012
|
let rail = paymentRail(paymentRequired);
|
|
104666
105013
|
if (rail === "confidential" && paymentRequired.accepts.some((offer) => offer?.scheme === "exact")) rail = "exact";
|
|
104667
105014
|
if (rail === "none") {
|
|
@@ -104672,7 +105019,7 @@ async function offeredPrice(paymentRequired, store, serviceUrl2, target) {
|
|
|
104672
105019
|
}
|
|
104673
105020
|
if (rail === "exact" && store) {
|
|
104674
105021
|
const origin = new URL(serviceUrl2).origin;
|
|
104675
|
-
const { offer, config } = await readFloatOffer({ origin, paymentRequired, store, resourceUrl: target });
|
|
105022
|
+
const { offer, config } = await readFloatOffer({ origin, paymentRequired, store, resourceUrl: target, timing });
|
|
104676
105023
|
return { rail, amountAtomic: offer.paidAtomic, priceAtomic: offer.priceAtomic, floatConfig: { origin, config } };
|
|
104677
105024
|
}
|
|
104678
105025
|
let highest;
|
|
@@ -104782,7 +105129,7 @@ async function payAndFetch(session, url, init = {}, opts = {}) {
|
|
|
104782
105129
|
if (ahead) {
|
|
104783
105130
|
mark("leg1-ahead");
|
|
104784
105131
|
} else {
|
|
104785
|
-
warmFloatConfig({ origin: new URL(session.memoServiceUrl).origin });
|
|
105132
|
+
warmFloatConfig({ origin: new URL(session.memoServiceUrl).origin, timing: mark });
|
|
104786
105133
|
}
|
|
104787
105134
|
startRecoveredPaymentTools(lazyProofTools(session));
|
|
104788
105135
|
}
|
|
@@ -104806,7 +105153,7 @@ async function payAndFetch(session, url, init = {}, opts = {}) {
|
|
|
104806
105153
|
}
|
|
104807
105154
|
challenge3 = { encoded, atMs: Date.now() };
|
|
104808
105155
|
mark("fetch-challenge");
|
|
104809
|
-
price = await offeredPrice(paymentRequired, store ?? session.openStore(), session.memoServiceUrl, target);
|
|
105156
|
+
price = await offeredPrice(paymentRequired, store ?? session.openStore(), session.memoServiceUrl, target, mark);
|
|
104810
105157
|
mark("fetch-price");
|
|
104811
105158
|
if (maxPrice !== void 0 && BigInt(price.priceAtomic) > BigInt(maxPrice)) {
|
|
104812
105159
|
fail24(
|
|
@@ -108908,7 +109255,8 @@ function build(a, tool) {
|
|
|
108908
109255
|
if (a.stage === "confirming") return "Waiting for you to confirm the send in your app.";
|
|
108909
109256
|
const amount = usdcText(a.done === true ? a.sentAtomic ?? a.amountAtomic : a.amountAtomic);
|
|
108910
109257
|
const what = amount ? `${amount} USDC` : "the USDC";
|
|
108911
|
-
|
|
109258
|
+
if (a.done !== true) return `Sending ${what} privately to ${a.to}.`;
|
|
109259
|
+
return typeof a.exitTransaction === "string" && a.privateSend === void 0 ? `Sent ${what} to ${a.to} (transaction ${a.exitTransaction}). Your private balance shows it in a few seconds; nothing to do.` : `Sent ${what} to ${a.to}.`;
|
|
108912
109260
|
}
|
|
108913
109261
|
if (typeof a.address === "string" && a.address && typeof a.stage === "string") return linkSay(a);
|
|
108914
109262
|
if (a.stage === "waiting_for_funds" && typeof a.depositAddress === "string") {
|
|
@@ -117403,7 +117751,9 @@ async function runUnshield({
|
|
|
117403
117751
|
profile,
|
|
117404
117752
|
facilitatorOrigin: facilitatorOrigin2,
|
|
117405
117753
|
onStage,
|
|
117406
|
-
selfPayStep = selfPay
|
|
117754
|
+
selfPayStep = selfPay,
|
|
117755
|
+
onAnswered,
|
|
117756
|
+
onCheckPending
|
|
117407
117757
|
}) {
|
|
117408
117758
|
const owner = new import_web3133.PublicKey(recipientOwner);
|
|
117409
117759
|
const mint = new import_web3133.PublicKey(store.state.asset);
|
|
@@ -117460,7 +117810,9 @@ async function runUnshield({
|
|
|
117460
117810
|
onStage,
|
|
117461
117811
|
walk,
|
|
117462
117812
|
mark,
|
|
117463
|
-
scoped
|
|
117813
|
+
scoped,
|
|
117814
|
+
onAnswered,
|
|
117815
|
+
onCheckPending
|
|
117464
117816
|
});
|
|
117465
117817
|
}
|
|
117466
117818
|
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");
|
|
@@ -117503,12 +117855,50 @@ async function runUnshield({
|
|
|
117503
117855
|
allowForeignRecipient: true,
|
|
117504
117856
|
relaySubmit: facilitatorExitRelay(facilitatorOrigin2),
|
|
117505
117857
|
requestAnchor: markedAnchorRequest(facilitatorAnchor(facilitatorOrigin2)),
|
|
117858
|
+
answerAtRelay: true,
|
|
117506
117859
|
deps: { walkHistory: walk(exitProofTools.deploymentIdentity) }
|
|
117507
117860
|
}), { ring: { connection: session.connection, pool: store.state.pool } }));
|
|
117861
|
+
const answer = { selfPayTransaction: paid.transaction ?? null, exitTransaction: exit.signature ?? null };
|
|
117862
|
+
if (exit.settled === false && !await finishAnsweredExit({ session, store, name, exit, answer, onAnswered, onCheckPending, mark, scoped })) return answer;
|
|
117508
117863
|
mark("unshield-exited");
|
|
117509
117864
|
const exited = store.readWal(`self-pay-${unshieldId}`);
|
|
117510
117865
|
store.writeWal(`self-pay-${unshieldId}`, { ...exited, state: "exited", exitTransaction: exit.signature, exitedAtMs: exited?.exitedAtMs ?? Date.now() });
|
|
117511
|
-
return
|
|
117866
|
+
return answer;
|
|
117867
|
+
}
|
|
117868
|
+
async function finishAnsweredExit({ session, store, name, exit, answer, changeAtomic, onAnswered, onCheckPending, mark, scoped }) {
|
|
117869
|
+
if (typeof onAnswered !== "function") {
|
|
117870
|
+
await scoped("unshield-exit", () => exit.finish());
|
|
117871
|
+
return true;
|
|
117872
|
+
}
|
|
117873
|
+
const record = store.readWal(name);
|
|
117874
|
+
store.writeWal(name, {
|
|
117875
|
+
...record,
|
|
117876
|
+
exitTransaction: exit.signature,
|
|
117877
|
+
exitAnsweredAtMs: record?.exitAnsweredAtMs ?? Date.now(),
|
|
117878
|
+
...changeAtomic !== void 0 ? { changeAtomic } : {}
|
|
117879
|
+
});
|
|
117880
|
+
try {
|
|
117881
|
+
await scoped("unshield-exit", () => refreshWallet({ session, store, history: exit.preExitHistory }));
|
|
117882
|
+
} catch {
|
|
117883
|
+
mark("unshield-exit-snapshot-failed");
|
|
117884
|
+
}
|
|
117885
|
+
mark("unshield-exit-answered");
|
|
117886
|
+
try {
|
|
117887
|
+
onAnswered(answer);
|
|
117888
|
+
} catch {
|
|
117889
|
+
}
|
|
117890
|
+
try {
|
|
117891
|
+
await scoped("unshield-exit", () => exit.finish());
|
|
117892
|
+
return true;
|
|
117893
|
+
} catch (error) {
|
|
117894
|
+
mark("unshield-exit-check-pending");
|
|
117895
|
+
store.writeWal(name, { ...store.readWal(name), exitCheckPendingAtMs: Date.now() });
|
|
117896
|
+
try {
|
|
117897
|
+
onCheckPending?.(error);
|
|
117898
|
+
} catch {
|
|
117899
|
+
}
|
|
117900
|
+
return false;
|
|
117901
|
+
}
|
|
117512
117902
|
}
|
|
117513
117903
|
async function runDirectExit({
|
|
117514
117904
|
session,
|
|
@@ -117525,7 +117915,9 @@ async function runDirectExit({
|
|
|
117525
117915
|
walk,
|
|
117526
117916
|
mark = () => {
|
|
117527
117917
|
},
|
|
117528
|
-
scoped = (_prefix, fn) => fn()
|
|
117918
|
+
scoped = (_prefix, fn) => fn(),
|
|
117919
|
+
onAnswered,
|
|
117920
|
+
onCheckPending
|
|
117529
117921
|
}) {
|
|
117530
117922
|
const name = `self-pay-${unshieldId}`;
|
|
117531
117923
|
if (record.amountAtomic !== String(amountAtomic) || record.exitAmountAtomic !== String(amountAtomic)) {
|
|
@@ -117563,6 +117955,7 @@ async function runDirectExit({
|
|
|
117563
117955
|
allowForeignRecipient: true,
|
|
117564
117956
|
relaySubmit: facilitatorExitRelay(facilitatorOrigin2),
|
|
117565
117957
|
requestAnchor: markedAnchorRequest(facilitatorAnchor(facilitatorOrigin2)),
|
|
117958
|
+
answerAtRelay: true,
|
|
117566
117959
|
deps: { walkHistory: walk(exitProofTools.deploymentIdentity), proveExit }
|
|
117567
117960
|
}), { ring: { connection: session.connection, pool: store.state.pool } }));
|
|
117568
117961
|
} catch (error) {
|
|
@@ -117571,10 +117964,13 @@ async function runDirectExit({
|
|
|
117571
117964
|
}
|
|
117572
117965
|
throw error;
|
|
117573
117966
|
}
|
|
117967
|
+
const answer = { selfPayTransaction: null, exitTransaction: exit.signature ?? null };
|
|
117968
|
+
const changeAtomic = exitAmountAtomic === void 0 ? void 0 : (BigInt(record.noteValueAtomic) - BigInt(record.exitAmountAtomic)).toString();
|
|
117969
|
+
if (exit.settled === false && !await finishAnsweredExit({ session, store, name, exit, answer, changeAtomic, onAnswered, onCheckPending, mark, scoped })) return answer;
|
|
117574
117970
|
mark("unshield-exited");
|
|
117575
117971
|
const exited = store.readWal(name);
|
|
117576
117972
|
store.writeWal(name, { ...exited, state: "exited", exitTransaction: exit.signature, exitedAtMs: exited?.exitedAtMs ?? Date.now() });
|
|
117577
|
-
return
|
|
117973
|
+
return answer;
|
|
117578
117974
|
}
|
|
117579
117975
|
function movingAtomic(store) {
|
|
117580
117976
|
let moving = 0n;
|
|
@@ -119394,6 +119790,12 @@ ${canonical5}`;
|
|
|
119394
119790
|
watcher?.kick?.();
|
|
119395
119791
|
} catch {
|
|
119396
119792
|
}
|
|
119793
|
+
if (resumeSends) {
|
|
119794
|
+
try {
|
|
119795
|
+
finishAnsweredExits();
|
|
119796
|
+
} catch {
|
|
119797
|
+
}
|
|
119798
|
+
}
|
|
119397
119799
|
let store;
|
|
119398
119800
|
try {
|
|
119399
119801
|
store = session.openStore();
|
|
@@ -119907,7 +120309,7 @@ ${canonical5}`;
|
|
|
119907
120309
|
amountAtomic: typeof record.amountAtomic === "string" ? record.amountAtomic : null,
|
|
119908
120310
|
to: record.mcpTo,
|
|
119909
120311
|
// One word per state (real-user pass F3): "sent" as wallet_cancel and openSendState say, never the record's "exited".
|
|
119910
|
-
state: retry ? "retrying" : joining ? "joining" : record.state === "exited" ? "sent" : live === "sending" ? "sending" : idle ?? record.state,
|
|
120312
|
+
state: retry ? "retrying" : joining ? "joining" : record.state === "exited" || live === "sent" ? "sent" : live === "sending" ? "sending" : idle ?? record.state,
|
|
119911
120313
|
transaction: sigOrNull(record.exitTransaction),
|
|
119912
120314
|
at,
|
|
119913
120315
|
...record.state === "exited" && started !== void 0 ? { startedAt: isoOf(started) } : {},
|
|
@@ -120353,7 +120755,8 @@ ${canonical5}`;
|
|
|
120353
120755
|
return sendDoneNext(job.to, job.result.privateSend) + `${job.result?.backupPath ? `. An encrypted backup of the wallet was saved at ${job.result.backupPath}` : ""}`;
|
|
120354
120756
|
}
|
|
120355
120757
|
if (kind === "unshield") {
|
|
120356
|
-
|
|
120758
|
+
const tx = job.result?.exitTransaction;
|
|
120759
|
+
return `Sent ${usdcText2(job.amountAtomic)} USDC to ${job.to}${typeof tx === "string" ? ` (transaction ${tx})` : ""}. Tell the user; nothing to do: the private balance shows it in a few seconds (wallet_balance)${job.result?.backupPath ? `. An encrypted backup of the wallet was saved at ${job.result.backupPath}` : ""}`;
|
|
120357
120760
|
}
|
|
120358
120761
|
const post = job.post;
|
|
120359
120762
|
if (!post || post.state === "running") {
|
|
@@ -120806,7 +121209,9 @@ ${canonical5}`;
|
|
|
120806
121209
|
}
|
|
120807
121210
|
function singleSendState(store, requestId, intent) {
|
|
120808
121211
|
const unshieldId = moneyId(requestId);
|
|
120809
|
-
|
|
121212
|
+
const record = store.readWal(`self-pay-${unshieldId}`);
|
|
121213
|
+
if (record?.state === "exited") return "sent";
|
|
121214
|
+
if (Number.isSafeInteger(record?.exitAnsweredAtMs) && typeof record.exitTransaction === "string" && record.exitUnconfirmed !== true) return "sent";
|
|
120810
121215
|
if (jobs.get(`unshield:${toRecordId(requestId)}`)?.state === "running" || selfPayMayHaveSigned(store, unshieldId)) return "sending";
|
|
120811
121216
|
return intent ? "joining" : void 0;
|
|
120812
121217
|
}
|
|
@@ -121289,7 +121694,7 @@ ${canonical5}`;
|
|
|
121289
121694
|
if (known && known.state !== "failed" && known.state !== "waiting" && sameRequest(known, request)) {
|
|
121290
121695
|
const wait3 = waitFor();
|
|
121291
121696
|
if (known.state === "running" && wait3 > 0) {
|
|
121292
|
-
const ends = (kind === "shield" || kind === "unshield") && known.stage !== "confirming" ? [known.promise] : [known.promise, stageChanged(known)];
|
|
121697
|
+
const ends = (kind === "shield" || kind === "unshield") && known.stage !== "confirming" ? [known.answered ?? known.promise] : [known.promise, stageChanged(known)];
|
|
121293
121698
|
await statusWait(
|
|
121294
121699
|
ends,
|
|
121295
121700
|
wait3,
|
|
@@ -121664,6 +122069,10 @@ ${canonical5}`;
|
|
|
121664
122069
|
if (kind !== "unshield") afterShield(job);
|
|
121665
122070
|
else refreshAtFinality();
|
|
121666
122071
|
}, async (error) => {
|
|
122072
|
+
if (job.answeredEarly) {
|
|
122073
|
+
log(`MCP_UNSHIELD_AFTER_ANSWER_FAILED requestId=${job.requestId} cause=${JSON.stringify(String(error?.message ?? error ?? "").split("\n", 1)[0].slice(0, 240))}`);
|
|
122074
|
+
return;
|
|
122075
|
+
}
|
|
121667
122076
|
const linkHeld = /* @__PURE__ */ new Map();
|
|
121668
122077
|
if (kind === "unshield" && /p03_merchant_respend_no_spendable_account|insufficient_recovered_value|insufficient_value/.test(String(error?.message ?? error))) {
|
|
121669
122078
|
try {
|
|
@@ -121707,7 +122116,14 @@ ${canonical5}`;
|
|
|
121707
122116
|
recorded = true;
|
|
121708
122117
|
}
|
|
121709
122118
|
if (!recorded) uncount(kind, key);
|
|
121710
|
-
}).finally(() =>
|
|
122119
|
+
}).finally(() => {
|
|
122120
|
+
job.finishing = false;
|
|
122121
|
+
signalStage(job);
|
|
122122
|
+
});
|
|
122123
|
+
job.answered = new Promise((resolve38) => {
|
|
122124
|
+
job.answerNow = resolve38;
|
|
122125
|
+
job.promise.then(resolve38, resolve38);
|
|
122126
|
+
});
|
|
121711
122127
|
if (needsConfirm) {
|
|
121712
122128
|
await statusWait([confirmation], fullWait ? Infinity : budgetLeft(startedAt), progress3, "waiting for the user to confirm the send");
|
|
121713
122129
|
if (job.stage === "confirming" || job.state === "failed") return jobAnswer(kind, job);
|
|
@@ -121716,7 +122132,7 @@ ${canonical5}`;
|
|
|
121716
122132
|
if (wait2 === Infinity) await job.promise.catch(() => {
|
|
121717
122133
|
});
|
|
121718
122134
|
else if (wait2 > 0) {
|
|
121719
|
-
await statusWait([job.
|
|
122135
|
+
await statusWait([job.answered], wait2, progress3, kind === "unshield" ? "sending privately; it takes a few minutes" : kind === "elsewhere" ? "checking the one-time address; a deposit takes a few minutes" : "making the USDC private; it takes a few minutes");
|
|
121720
122136
|
}
|
|
121721
122137
|
return jobAnswer(kind, job);
|
|
121722
122138
|
}
|
|
@@ -121774,9 +122190,10 @@ ${canonical5}`;
|
|
|
121774
122190
|
}
|
|
121775
122191
|
return session.openStore();
|
|
121776
122192
|
}
|
|
121777
|
-
async function unshieldPart(opened, job, unshieldId, amountAtomic, onStage) {
|
|
122193
|
+
async function unshieldPart(opened, job, unshieldId, amountAtomic, onStage, onAnswered) {
|
|
121778
122194
|
const store = await refreshStaleBeforeUnshield(opened, onStage);
|
|
121779
122195
|
bindUnshieldRecipient(store, unshieldId, amountAtomic, job.to, unshieldId === moneyId(job.requestId) ? job.requestId : void 0);
|
|
122196
|
+
let backup;
|
|
121780
122197
|
const result = await (ops.unshield ?? runUnshield)({
|
|
121781
122198
|
session,
|
|
121782
122199
|
store,
|
|
@@ -121787,17 +122204,40 @@ ${canonical5}`;
|
|
|
121787
122204
|
profile: money.profile,
|
|
121788
122205
|
facilitatorOrigin: money.facilitatorOrigin,
|
|
121789
122206
|
onStage,
|
|
121790
|
-
...ops.selfPay ? { selfPayStep: ops.selfPay } : {}
|
|
122207
|
+
...ops.selfPay ? { selfPayStep: ops.selfPay } : {},
|
|
122208
|
+
...typeof onAnswered === "function" ? { onAnswered: (answer) => {
|
|
122209
|
+
backup = backupNow(session.openStore());
|
|
122210
|
+
onAnswered({ ...answer, ...backup });
|
|
122211
|
+
} } : {},
|
|
122212
|
+
onCheckPending: (error) => {
|
|
122213
|
+
log(`MCP_UNSHIELD_CHECK_PENDING requestId=${job.requestId} cause=${JSON.stringify(String(error?.message ?? error ?? "").split("\n", 1)[0].slice(0, 240))}`);
|
|
122214
|
+
answeredExitTries.set(`self-pay-${unshieldId}`, { running: false, atMs: Date.now() });
|
|
122215
|
+
armAnsweredExitRetry();
|
|
122216
|
+
}
|
|
121791
122217
|
});
|
|
121792
|
-
return { ...result, ...backupNow(session.openStore()) };
|
|
122218
|
+
return { ...result, ...backup ?? backupNow(session.openStore()) };
|
|
121793
122219
|
}
|
|
121794
122220
|
function runUnshieldJob(job, onStage) {
|
|
121795
122221
|
if (isSplitSend(job)) return runPrivateSendJob(job, onStage);
|
|
121796
122222
|
return underLease((opened) => {
|
|
121797
122223
|
if (!opened.readWal(`self-pay-${moneyId(job.requestId)}`)) assertUnshieldNotPromised(opened, job.amountAtomic);
|
|
121798
|
-
return unshieldPart(opened, job, moneyId(job.requestId), job.amountAtomic, onStage);
|
|
122224
|
+
return unshieldPart(opened, job, moneyId(job.requestId), job.amountAtomic, onStage, (answer) => answerUnshieldEarly(job, answer));
|
|
121799
122225
|
});
|
|
121800
122226
|
}
|
|
122227
|
+
function answerUnshieldEarly(job, answer) {
|
|
122228
|
+
job.state = "done";
|
|
122229
|
+
job.doneAtMs = Date.now();
|
|
122230
|
+
job.result = answer;
|
|
122231
|
+
job.answeredEarly = true;
|
|
122232
|
+
job.finishing = true;
|
|
122233
|
+
try {
|
|
122234
|
+
closeJoinIntent(session.openStore(), job.requestId, "done");
|
|
122235
|
+
} catch {
|
|
122236
|
+
}
|
|
122237
|
+
log(`MCP_UNSHIELD_ANSWERED requestId=${job.requestId}`);
|
|
122238
|
+
signalStage(job);
|
|
122239
|
+
job.answerNow?.();
|
|
122240
|
+
}
|
|
121801
122241
|
async function runPrivateSendJob(job, onStage) {
|
|
121802
122242
|
const sendId = moneyId(job.requestId);
|
|
121803
122243
|
let store;
|
|
@@ -122009,6 +122449,89 @@ ${canonical5}`;
|
|
|
122009
122449
|
}
|
|
122010
122450
|
}
|
|
122011
122451
|
const resumeRefusals = /* @__PURE__ */ new Map();
|
|
122452
|
+
const answeredExitTries = /* @__PURE__ */ new Map();
|
|
122453
|
+
let answeredExitRetryTimer;
|
|
122454
|
+
function finishAnsweredExits() {
|
|
122455
|
+
if (!unshieldEnabled || finalityClosed || session.closed === true) return;
|
|
122456
|
+
let store;
|
|
122457
|
+
try {
|
|
122458
|
+
store = session.openStore();
|
|
122459
|
+
} catch {
|
|
122460
|
+
return;
|
|
122461
|
+
}
|
|
122462
|
+
let names = [];
|
|
122463
|
+
try {
|
|
122464
|
+
names = store.listWal().filter((name) => name.startsWith("self-pay-") && !name.startsWith("self-pay-merge-") && !name.startsWith("self-pay-pocket-"));
|
|
122465
|
+
} catch {
|
|
122466
|
+
return;
|
|
122467
|
+
}
|
|
122468
|
+
for (const name of names) {
|
|
122469
|
+
let record;
|
|
122470
|
+
try {
|
|
122471
|
+
record = store.readWal(name);
|
|
122472
|
+
} catch {
|
|
122473
|
+
continue;
|
|
122474
|
+
}
|
|
122475
|
+
if (record?.schema !== SELF_PAY_WAL_SCHEMA || record.state === "exited" || record.exitUnconfirmed === true || typeof record.exitTransaction !== "string" || typeof record.mcpTo !== "string" || !ATOMIC_TEXT.test(String(record.amountAtomic))) continue;
|
|
122476
|
+
const tried = answeredExitTries.get(name);
|
|
122477
|
+
if (tried !== void 0 && (tried.running || Date.now() - tried.atMs < ANSWERED_EXIT_RETRY_MS)) continue;
|
|
122478
|
+
const attempt = { running: true, atMs: Date.now() };
|
|
122479
|
+
answeredExitTries.set(name, attempt);
|
|
122480
|
+
const unshieldId = name.slice("self-pay-".length);
|
|
122481
|
+
log(`MCP_UNSHIELD_CHECK_RESUME unshieldId=${unshieldId}`);
|
|
122482
|
+
underLease((opened) => {
|
|
122483
|
+
const current = opened.readWal(name);
|
|
122484
|
+
if (current?.state === "exited" || current?.exitUnconfirmed === true || typeof current?.exitTransaction !== "string") return void 0;
|
|
122485
|
+
return (ops.unshield ?? runUnshield)({
|
|
122486
|
+
session,
|
|
122487
|
+
store: opened,
|
|
122488
|
+
unshieldId,
|
|
122489
|
+
amountAtomic: current.amountAtomic,
|
|
122490
|
+
recipientOwner: current.mcpTo,
|
|
122491
|
+
exitProofTools: money.exitProofTools,
|
|
122492
|
+
profile: money.profile,
|
|
122493
|
+
facilitatorOrigin: money.facilitatorOrigin,
|
|
122494
|
+
onStage: () => {
|
|
122495
|
+
},
|
|
122496
|
+
...ops.selfPay ? { selfPayStep: ops.selfPay } : {}
|
|
122497
|
+
});
|
|
122498
|
+
}, { orClosed: ANSWERED_EXIT_CLOSED }).then((result) => {
|
|
122499
|
+
if (result === ANSWERED_EXIT_CLOSED) return;
|
|
122500
|
+
const now = session.openStore().readWal(name);
|
|
122501
|
+
log(now?.state === "exited" ? `MCP_UNSHIELD_CHECK_DONE unshieldId=${unshieldId}` : `MCP_UNSHIELD_CHECK_PENDING unshieldId=${unshieldId}`);
|
|
122502
|
+
if (now?.state === "exited") refreshAtFinality();
|
|
122503
|
+
}, (error) => {
|
|
122504
|
+
const cause = String(error?.message ?? error ?? "").split("\n", 1)[0];
|
|
122505
|
+
attempt.provenUnspent = /confirmed note-exit is not finalized spent/.test(cause);
|
|
122506
|
+
log(`MCP_UNSHIELD_CHECK_PENDING unshieldId=${unshieldId} cause=${JSON.stringify(cause.slice(0, 240))}`);
|
|
122507
|
+
}).then(() => underLease((opened) => {
|
|
122508
|
+
const now = opened.readWal(name);
|
|
122509
|
+
if (attempt.provenUnspent === true && now?.state !== "exited" && now?.exitUnconfirmed !== true && Number.isSafeInteger(now?.exitAnsweredAtMs) && Date.now() - now.exitAnsweredAtMs > ANSWERED_EXIT_UNCONFIRMED_MS) {
|
|
122510
|
+
opened.writeWal(name, { ...now, exitUnconfirmed: true });
|
|
122511
|
+
log(`MCP_UNSHIELD_UNCONFIRMED unshieldId=${unshieldId}`);
|
|
122512
|
+
}
|
|
122513
|
+
}, { orClosed: ANSWERED_EXIT_CLOSED })).catch(() => {
|
|
122514
|
+
}).finally(() => {
|
|
122515
|
+
attempt.running = false;
|
|
122516
|
+
let now;
|
|
122517
|
+
try {
|
|
122518
|
+
now = session.openStore().readWal(name);
|
|
122519
|
+
} catch {
|
|
122520
|
+
now = void 0;
|
|
122521
|
+
}
|
|
122522
|
+
if (now?.state === "exited" || now?.exitUnconfirmed === true || !Number.isSafeInteger(now?.exitAnsweredAtMs) || Date.now() - now.exitAnsweredAtMs > ANSWERED_EXIT_RETRY_WINDOW_MS) return;
|
|
122523
|
+
armAnsweredExitRetry();
|
|
122524
|
+
});
|
|
122525
|
+
}
|
|
122526
|
+
}
|
|
122527
|
+
function armAnsweredExitRetry() {
|
|
122528
|
+
if (finalityClosed || session.closed === true || answeredExitRetryTimer !== void 0) return;
|
|
122529
|
+
answeredExitRetryTimer = setTimeout(() => {
|
|
122530
|
+
answeredExitRetryTimer = void 0;
|
|
122531
|
+
finishAnsweredExits();
|
|
122532
|
+
}, ANSWERED_EXIT_RETRY_MS + 100);
|
|
122533
|
+
answeredExitRetryTimer.unref?.();
|
|
122534
|
+
}
|
|
122012
122535
|
async function cancelElsewhere(args) {
|
|
122013
122536
|
const spec = KINDS.elsewhere;
|
|
122014
122537
|
if (!spec.enabled()) return refuse11("mcp_tool_disabled", `${spec.tool} is off: the owner did not enable it when starting this MCP server`, spec.disabledNext);
|
|
@@ -124032,6 +124555,8 @@ ${JSON.stringify(args ?? {})}`;
|
|
|
124032
124555
|
));
|
|
124033
124556
|
const resumeTimer = resumeSends ? setTimeout(resumePrivateSends, 0) : void 0;
|
|
124034
124557
|
resumeTimer?.unref?.();
|
|
124558
|
+
const answeredExitTimer = resumeSends ? setTimeout(finishAnsweredExits, 0) : void 0;
|
|
124559
|
+
answeredExitTimer?.unref?.();
|
|
124035
124560
|
const tempCleanTimer = typeof session.walletPath === "string" ? setTimeout(() => {
|
|
124036
124561
|
const pool2 = dirname24(session.walletPath);
|
|
124037
124562
|
removeStaleTemporaryFiles([pool2, join28(pool2, "wal"), join28(pool2, "move-counts")]).then((removed) => {
|
|
@@ -124057,6 +124582,8 @@ ${JSON.stringify(args ?? {})}`;
|
|
|
124057
124582
|
for (const timer of joinTimers) clearTimeout(timer);
|
|
124058
124583
|
joinTimers.clear();
|
|
124059
124584
|
clearTimeout(resumeTimer);
|
|
124585
|
+
clearTimeout(answeredExitTimer);
|
|
124586
|
+
clearTimeout(answeredExitRetryTimer);
|
|
124060
124587
|
clearTimeout(tempCleanTimer);
|
|
124061
124588
|
clearTimeout(intentStartTimer);
|
|
124062
124589
|
clearTimeout(intentTimer);
|
|
@@ -124080,6 +124607,7 @@ ${JSON.stringify(args ?? {})}`;
|
|
|
124080
124607
|
*/
|
|
124081
124608
|
moving: { value: () => {
|
|
124082
124609
|
if (moneyCallsInFlight - joinWaitingCalls > 0 || [...jobs.values()].some((job) => job.state === "running")) return true;
|
|
124610
|
+
if ([...jobs.values()].some((job) => job.finishing === true) || [...answeredExitTries.values()].some((attempt) => attempt.running)) return true;
|
|
124083
124611
|
try {
|
|
124084
124612
|
return mover.running?.() === true || successionRunning() || transferRuns.size > 0 || Boolean(joiner.status().running) || adopter.busy?.() === true || autoPockets.busy?.() === true || watcher?.depositing?.() === true;
|
|
124085
124613
|
} catch {
|
|
@@ -124388,7 +124916,7 @@ function createSetupTools({
|
|
|
124388
124916
|
};
|
|
124389
124917
|
return { tools: [setupTool, statusTool, ...MCP_TOOL_NAMES.map((name) => name === "x402_discover" ? discoverTool(discoverCacheDir) : notSetUp(name))], doneTool };
|
|
124390
124918
|
}
|
|
124391
|
-
var import_web3133, 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, 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, MONEY_FIRST_ANSWER_MS, JOIN_CALL_MAX_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, limitNext, SAFE_TEXT, MCP_TOOL_ALIASES, POOL_SWITCH_WHY, POOL_SWITCH_NEXT, SWITCH_STATES, quietSwitch, switchKey, ATOMIC_TEXT, switchAmount, switchEta, switchRows, OWNER_CAP_CODES, JOIN_END_MCP, JOIN_END_TERMINAL_LIBRARY, JOIN_RETRY_BACKOFF_MS, WALLET_CAP_FIX, capFix, ownerOnlyNext, mcpNext, CONFIDENTIAL_RETIRED, json2, answerResult, discoverTool, refuse11, publicOffer, FLOAT_PAID_CODES, floatStillSettling, MONEY_ID2, toRecordId, linkKindOf, moneyId, REFUSED_CODES, refusedCodeOf, PLAIN_REASONS, plainReason, KEPT_SEND_TRIES, shownId, isSplitSend, sendPartId, PROMISED_NEXT, PUBLIC_READ_TIMEOUT_MS, withTimeout, ownKey, readFailure, OWN_KEY_TOKENS_MAX, OWN_TOKENS_GRACE_MS, tokenAmountText, elsewhereId, AGENT_ID_SCHEMA, agentIdName, minutesText2, DEPOSIT_SENT_STATES, depositLanded, usdcText2, 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, 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, SWITCH_WAIT_MS, UNSHIELD_TO_NO_USDC_DETAIL, UNSHIELD_TO_INVALID_NEXT, INFERENCE_MIN_MAX_TOKENS, ELICIT_TIMEOUT_MS, ELICIT_UNSHOWN_MS, elicitUnshown, POLL_SECONDS3, TEMP_CLEAN_DELAY_MS, KEPT_ON_DISK, MAX_SHIELDED_BALANCE_ATOMIC, receiveGenerator, MCP_TOOL_NAMES, MCP_HIDDEN_TOOL_NAMES, SETUP_TERMINAL_NEXT, SETUP_POLL_NEXT, PRIVATE_INFERENCE_WHY, PRIVATE_INFERENCE_NEXT;
|
|
124919
|
+
var import_web3133, 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, 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, MONEY_FIRST_ANSWER_MS, JOIN_CALL_MAX_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, limitNext, SAFE_TEXT, MCP_TOOL_ALIASES, POOL_SWITCH_WHY, POOL_SWITCH_NEXT, SWITCH_STATES, quietSwitch, switchKey, ATOMIC_TEXT, 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, capFix, ownerOnlyNext, mcpNext, CONFIDENTIAL_RETIRED, json2, answerResult, discoverTool, refuse11, publicOffer, FLOAT_PAID_CODES, floatStillSettling, MONEY_ID2, toRecordId, linkKindOf, moneyId, REFUSED_CODES, refusedCodeOf, PLAIN_REASONS, plainReason, KEPT_SEND_TRIES, shownId, isSplitSend, sendPartId, PROMISED_NEXT, PUBLIC_READ_TIMEOUT_MS, withTimeout, ownKey, readFailure, OWN_KEY_TOKENS_MAX, OWN_TOKENS_GRACE_MS, tokenAmountText, elsewhereId, AGENT_ID_SCHEMA, agentIdName, minutesText2, DEPOSIT_SENT_STATES, depositLanded, usdcText2, 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, 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, SWITCH_WAIT_MS, UNSHIELD_TO_NO_USDC_DETAIL, UNSHIELD_TO_INVALID_NEXT, INFERENCE_MIN_MAX_TOKENS, ELICIT_TIMEOUT_MS, ELICIT_UNSHOWN_MS, elicitUnshown, POLL_SECONDS3, TEMP_CLEAN_DELAY_MS, KEPT_ON_DISK, MAX_SHIELDED_BALANCE_ATOMIC, receiveGenerator, MCP_TOOL_NAMES, MCP_HIDDEN_TOOL_NAMES, SETUP_TERMINAL_NEXT, SETUP_POLL_NEXT, PRIVATE_INFERENCE_WHY, PRIVATE_INFERENCE_NEXT;
|
|
124392
124920
|
var init_tools = __esm({
|
|
124393
124921
|
"wallet/src/mcp/tools.mjs"() {
|
|
124394
124922
|
"use strict";
|
|
@@ -124523,6 +125051,10 @@ var init_tools = __esm({
|
|
|
124523
125051
|
quietSwitch = (item) => item.state === "done" && item.tellUser !== true;
|
|
124524
125052
|
switchKey = (item) => `${item.from}:${item.state}`;
|
|
124525
125053
|
ATOMIC_TEXT = /^[0-9]{1,31}$/;
|
|
125054
|
+
ANSWERED_EXIT_RETRY_MS = 3e4;
|
|
125055
|
+
ANSWERED_EXIT_UNCONFIRMED_MS = 10 * 6e4;
|
|
125056
|
+
ANSWERED_EXIT_RETRY_WINDOW_MS = 30 * 6e4;
|
|
125057
|
+
ANSWERED_EXIT_CLOSED = /* @__PURE__ */ Symbol("answered-exit-closed");
|
|
124526
125058
|
switchAmount = (atomic4, decimals) => {
|
|
124527
125059
|
try {
|
|
124528
125060
|
return ATOMIC_TEXT.test(String(atomic4)) ? formatAtomic(BigInt(atomic4), decimals) : null;
|