shinjuku-shielded 0.3.31 → 0.3.33
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 +3 -3
- package/package.json +3 -3
- package/shinjuku-wallet.mjs +204 -58
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": "dae9ba8800e48179602d5595c5bbc71029a758be726e72482d24a52126649ac9",
|
|
5
|
+
"bytes": 11184999,
|
|
6
|
+
"sourceCommit": "5a445fbb0e06e50a3365809a078f3d5b0de03c51",
|
|
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",
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "shinjuku-shielded",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.33",
|
|
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": "dae9ba88",
|
|
7
|
+
"shinjukuSha256": "dae9ba8800e48179602d5595c5bbc71029a758be726e72482d24a52126649ac9",
|
|
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
|
@@ -46392,6 +46392,28 @@ var init_ohttp = __esm({
|
|
|
46392
46392
|
}
|
|
46393
46393
|
});
|
|
46394
46394
|
|
|
46395
|
+
// wallet/src/pay/phaseTiming.mjs
|
|
46396
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
46397
|
+
function withPhaseScope(mark, prefix, fn) {
|
|
46398
|
+
if (typeof mark !== "function") return fn();
|
|
46399
|
+
const outer = scope.getStore();
|
|
46400
|
+
const write = (phase) => mark(`${prefix}:${phase}`);
|
|
46401
|
+
return scope.run(outer ? (phase) => outer(`${prefix}:${phase}`) : write, fn);
|
|
46402
|
+
}
|
|
46403
|
+
function markPhase(phase) {
|
|
46404
|
+
try {
|
|
46405
|
+
scope.getStore()?.(phase);
|
|
46406
|
+
} catch {
|
|
46407
|
+
}
|
|
46408
|
+
}
|
|
46409
|
+
var scope;
|
|
46410
|
+
var init_phaseTiming = __esm({
|
|
46411
|
+
"wallet/src/pay/phaseTiming.mjs"() {
|
|
46412
|
+
"use strict";
|
|
46413
|
+
scope = new AsyncLocalStorage();
|
|
46414
|
+
}
|
|
46415
|
+
});
|
|
46416
|
+
|
|
46395
46417
|
// wallet/src/net/proxy.mjs
|
|
46396
46418
|
import { spawn } from "node:child_process";
|
|
46397
46419
|
import { randomBytes as randomBytes5 } from "node:crypto";
|
|
@@ -46575,7 +46597,15 @@ function describeRpcPost(input, body) {
|
|
|
46575
46597
|
const calls = Array.isArray(parsed) ? parsed : [parsed];
|
|
46576
46598
|
const resendable = calls.length > 0 && calls.every((call3) => typeof call3?.method === "string" && RESENDABLE_METHOD.test(call3.method));
|
|
46577
46599
|
const method = Array.isArray(parsed) ? "batch" : parsed?.method;
|
|
46578
|
-
return {
|
|
46600
|
+
return {
|
|
46601
|
+
key: `${new URL(input instanceof Request ? input.url : String(input)).origin} ${method ?? ""}`,
|
|
46602
|
+
resendable,
|
|
46603
|
+
// The method in a timing mark: a JSON-RPC method name only, else "other".
|
|
46604
|
+
mark: typeof method === "string" && /^[A-Za-z]{1,40}$/.test(method) ? method : "other"
|
|
46605
|
+
};
|
|
46606
|
+
}
|
|
46607
|
+
function markRefusal(response, post) {
|
|
46608
|
+
if (response.status === 429 || response.status === 503) markPhase(`rpc-${response.status}-${post?.mark ?? "other"}`);
|
|
46579
46609
|
}
|
|
46580
46610
|
function noteAnswer(response) {
|
|
46581
46611
|
if (!response.ok) return;
|
|
@@ -46607,6 +46637,7 @@ async function rpcFetch(input, init) {
|
|
|
46607
46637
|
if (!post?.resendable) {
|
|
46608
46638
|
const response = await fetch(input, init);
|
|
46609
46639
|
noteAnswer(response);
|
|
46640
|
+
markRefusal(response, post);
|
|
46610
46641
|
return response;
|
|
46611
46642
|
}
|
|
46612
46643
|
let strikes = 0;
|
|
@@ -46617,9 +46648,11 @@ async function rpcFetch(input, init) {
|
|
|
46617
46648
|
if (stop2) throw new Error(`rpc_rate_limited: ${stop2}`);
|
|
46618
46649
|
waited = true;
|
|
46619
46650
|
}
|
|
46651
|
+
if (waited) markPhase(`rpc-paced-${post.mark}`);
|
|
46620
46652
|
const circuit = torRotations;
|
|
46621
46653
|
const response = await fetch(input, init);
|
|
46622
46654
|
noteAnswer(response);
|
|
46655
|
+
markRefusal(response, post);
|
|
46623
46656
|
if (response.status !== 429) return response;
|
|
46624
46657
|
await response.body?.cancel().catch(() => {
|
|
46625
46658
|
});
|
|
@@ -46709,6 +46742,7 @@ var init_proxy = __esm({
|
|
|
46709
46742
|
"use strict";
|
|
46710
46743
|
init_facilitatorOnion();
|
|
46711
46744
|
init_ohttp();
|
|
46745
|
+
init_phaseTiming();
|
|
46712
46746
|
TOR_HTTP_TUNNEL = "http://127.0.0.1:9080";
|
|
46713
46747
|
TOR_CHECK = "https://check.torproject.org/api/ip";
|
|
46714
46748
|
PROOF_TIMEOUT_MS = 2e4;
|
|
@@ -49625,28 +49659,6 @@ var init_serviceUrl = __esm({
|
|
|
49625
49659
|
}
|
|
49626
49660
|
});
|
|
49627
49661
|
|
|
49628
|
-
// wallet/src/pay/phaseTiming.mjs
|
|
49629
|
-
import { AsyncLocalStorage } from "node:async_hooks";
|
|
49630
|
-
function withPhaseScope(mark, prefix, fn) {
|
|
49631
|
-
if (typeof mark !== "function") return fn();
|
|
49632
|
-
const outer = scope.getStore();
|
|
49633
|
-
const write = (phase) => mark(`${prefix}:${phase}`);
|
|
49634
|
-
return scope.run(outer ? (phase) => outer(`${prefix}:${phase}`) : write, fn);
|
|
49635
|
-
}
|
|
49636
|
-
function markPhase(phase) {
|
|
49637
|
-
try {
|
|
49638
|
-
scope.getStore()?.(phase);
|
|
49639
|
-
} catch {
|
|
49640
|
-
}
|
|
49641
|
-
}
|
|
49642
|
-
var scope;
|
|
49643
|
-
var init_phaseTiming = __esm({
|
|
49644
|
-
"wallet/src/pay/phaseTiming.mjs"() {
|
|
49645
|
-
"use strict";
|
|
49646
|
-
scope = new AsyncLocalStorage();
|
|
49647
|
-
}
|
|
49648
|
-
});
|
|
49649
|
-
|
|
49650
49662
|
// wallet/src/anchorClock.mjs
|
|
49651
49663
|
function observePoolAnchors(state, nowMs = Date.now()) {
|
|
49652
49664
|
try {
|
|
@@ -50445,8 +50457,9 @@ function createMemoReader(baseUrl, { fetchImpl = fetch, pause: pause3 = pauseFor
|
|
|
50445
50457
|
};
|
|
50446
50458
|
const origin = new URL(baseUrl).origin;
|
|
50447
50459
|
const keyOf2 = (digest2) => `${origin}|${digest2}`;
|
|
50448
|
-
|
|
50449
|
-
|
|
50460
|
+
const aheadKey = typeof fetchImpl?.baseFetch === "function" ? fetchImpl.baseFetch : fetchImpl;
|
|
50461
|
+
let ahead = prefetchedMemosByFetch.get(aheadKey);
|
|
50462
|
+
if (ahead === void 0) prefetchedMemosByFetch.set(aheadKey, ahead = /* @__PURE__ */ new Map());
|
|
50450
50463
|
const live = (key) => {
|
|
50451
50464
|
const entry = ahead.get(key);
|
|
50452
50465
|
if (entry !== void 0 && now() - entry.at > MEMO_PREFETCH_LIFE_MS) ahead.delete(key);
|
|
@@ -54852,6 +54865,23 @@ function foldCompactLeaves(leaves, counts) {
|
|
|
54852
54865
|
});
|
|
54853
54866
|
return roots;
|
|
54854
54867
|
}
|
|
54868
|
+
function foldCompactLeavesReusing(pool2, leaves, counts) {
|
|
54869
|
+
const prior = lastFolds.get(pool2);
|
|
54870
|
+
let common = 0;
|
|
54871
|
+
if (prior !== void 0) {
|
|
54872
|
+
const most = Math.min(prior.leaves.length, leaves.length);
|
|
54873
|
+
while (common < most && prior.leaves[common] === leaves[common]) common += 1;
|
|
54874
|
+
}
|
|
54875
|
+
const known = (at) => prior !== void 0 && at <= common && prior.roots.has(at);
|
|
54876
|
+
const roots = foldCompactLeaves(leaves, new Set([...counts].filter((at) => !known(at))));
|
|
54877
|
+
for (const at of counts) if (known(at)) roots.set(at, prior.roots.get(at));
|
|
54878
|
+
const kept = new Map(roots);
|
|
54879
|
+
if (prior !== void 0) {
|
|
54880
|
+
for (const [at, root] of prior.roots) if (at <= common && !kept.has(at)) kept.set(at, root);
|
|
54881
|
+
}
|
|
54882
|
+
lastFolds.set(pool2, { leaves: leaves.slice(), roots: kept });
|
|
54883
|
+
return roots;
|
|
54884
|
+
}
|
|
54855
54885
|
function fieldOf(hex4) {
|
|
54856
54886
|
if (typeof hex4 !== "string" || !HEX64.test(hex4)) throw refuse3("p03_compact_history_record_invalid");
|
|
54857
54887
|
const value = BigInt(`0x${hex4}`);
|
|
@@ -55062,7 +55092,7 @@ function withBoundedOwnReads(connection) {
|
|
|
55062
55092
|
}
|
|
55063
55093
|
});
|
|
55064
55094
|
}
|
|
55065
|
-
async function readPages(history, pool2, needed, first) {
|
|
55095
|
+
async function readPages(history, pool2, needed, first, { wakeSlot } = {}) {
|
|
55066
55096
|
const records = [];
|
|
55067
55097
|
const imports = [];
|
|
55068
55098
|
let initialization;
|
|
@@ -55093,7 +55123,19 @@ async function readPages(history, pool2, needed, first) {
|
|
|
55093
55123
|
initialization = result.initialization;
|
|
55094
55124
|
syncedSlot = result.syncedSlot;
|
|
55095
55125
|
records.push(...result.records);
|
|
55096
|
-
if (result.total < needed)
|
|
55126
|
+
if (result.total < needed) {
|
|
55127
|
+
if (isIndex(wakeSlot)) {
|
|
55128
|
+
Promise.resolve().then(() => history._rpcRequest("getP03Transitions", [pool2, {
|
|
55129
|
+
commitment: "finalized",
|
|
55130
|
+
fromOrdinal: 0,
|
|
55131
|
+
toOrdinal: 1,
|
|
55132
|
+
minContextSlot: wakeSlot
|
|
55133
|
+
}])).catch(() => {
|
|
55134
|
+
});
|
|
55135
|
+
markPhase("compact-behind-wake");
|
|
55136
|
+
}
|
|
55137
|
+
throw refuse3("p03_compact_history_source_behind");
|
|
55138
|
+
}
|
|
55097
55139
|
}
|
|
55098
55140
|
return { records: records.slice(0, needed), imports, initialization, syncedSlot };
|
|
55099
55141
|
}
|
|
@@ -55322,7 +55364,12 @@ async function readCompactP03History({
|
|
|
55322
55364
|
knownSnapshot,
|
|
55323
55365
|
// compactP03HistoryReport: run beside the spot checks once the initialization is verified
|
|
55324
55366
|
// ({ snapshot, initialization, contexts }); its result comes back as `alongside`.
|
|
55325
|
-
alongside
|
|
55367
|
+
alongside,
|
|
55368
|
+
// Called once with the served contexts in chain order, before the fold and every own-RPC
|
|
55369
|
+
// check: they are NOT verified yet. A payment asks the memo service for their memos here
|
|
55370
|
+
// (payAndFetch.mjs), and uses an answer only for a context the verified report names. Its
|
|
55371
|
+
// result and any throw are ignored.
|
|
55372
|
+
onList
|
|
55326
55373
|
}) {
|
|
55327
55374
|
const program = new import_web397.PublicKey(programId);
|
|
55328
55375
|
const poolKey = new import_web397.PublicKey(pool2);
|
|
@@ -55349,7 +55396,7 @@ async function readCompactP03History({
|
|
|
55349
55396
|
initialization: served.initialization,
|
|
55350
55397
|
syncedSlot: served.syncedSlot,
|
|
55351
55398
|
cached: true
|
|
55352
|
-
} : await readPages(source, poolString, count2, first);
|
|
55399
|
+
} : await readPages(source, poolString, count2, first, { wakeSlot: snapshot.slot });
|
|
55353
55400
|
markPhase(page.cached === true ? "compact-list-cached" : "compact-list");
|
|
55354
55401
|
const binding = {
|
|
55355
55402
|
programId: programString,
|
|
@@ -55375,6 +55422,10 @@ async function readCompactP03History({
|
|
|
55375
55422
|
}
|
|
55376
55423
|
});
|
|
55377
55424
|
const imports = orderCompactImports(page.imports, contexts, { snapshot, replay });
|
|
55425
|
+
try {
|
|
55426
|
+
onList?.(contexts);
|
|
55427
|
+
} catch {
|
|
55428
|
+
}
|
|
55378
55429
|
const picks = [];
|
|
55379
55430
|
const order = [...contexts.keys()];
|
|
55380
55431
|
const checks = page.cached === true ? 0 : spotChecks;
|
|
@@ -55406,7 +55457,7 @@ async function readCompactP03History({
|
|
|
55406
55457
|
for (const anchor of anchors) counts.add(Number(anchor.index / SUBTREE_LEAVES3));
|
|
55407
55458
|
if (appendRoots) for (let at = 1; at <= count2; at += 1) counts.add(at);
|
|
55408
55459
|
for (const at of counts) if (at > count2) throw refuse3("p03_compact_history_snapshot_invalid");
|
|
55409
|
-
roots =
|
|
55460
|
+
roots = foldCompactLeavesReusing(poolString, contexts.map((context) => context.outCommitment), counts);
|
|
55410
55461
|
if (roots.get(count2) !== snapshot.currentRoot) throw refuse3("p03_compact_history_root_mismatch");
|
|
55411
55462
|
for (const anchor of anchors) {
|
|
55412
55463
|
if (roots.get(Number(anchor.index / SUBTREE_LEAVES3)) !== anchor.root) throw refuse3("p03_compact_history_root_mismatch");
|
|
@@ -55470,7 +55521,8 @@ async function compactP03HistoryReport({
|
|
|
55470
55521
|
forceRead = false,
|
|
55471
55522
|
freshMs = 0,
|
|
55472
55523
|
priorAttestation,
|
|
55473
|
-
knownSnapshot
|
|
55524
|
+
knownSnapshot,
|
|
55525
|
+
onList
|
|
55474
55526
|
}) {
|
|
55475
55527
|
if (deploymentIdentity === void 0) throw new Error("p03_history_deployment_identity_required");
|
|
55476
55528
|
const program = new import_web397.PublicKey(programId);
|
|
@@ -55539,6 +55591,7 @@ async function compactP03HistoryReport({
|
|
|
55539
55591
|
pool: pool2,
|
|
55540
55592
|
alongside: attest,
|
|
55541
55593
|
...knownSnapshot !== void 0 ? { knownSnapshot } : {},
|
|
55594
|
+
...onList !== void 0 ? { onList } : {},
|
|
55542
55595
|
...warm ? { served: cached.served } : {},
|
|
55543
55596
|
...cached ? { initialization: cached.initialization } : {}
|
|
55544
55597
|
});
|
|
@@ -55616,7 +55669,7 @@ async function tryCompactP03HistoryReport(options) {
|
|
|
55616
55669
|
return { ok: false, reason: refusalReason(error), ...typeof error?.detail === "string" ? { detail: error.detail } : {}, error };
|
|
55617
55670
|
}
|
|
55618
55671
|
}
|
|
55619
|
-
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, isSignature, isIndex, IMPORT_KEYS, IMPORT_MAX_VALUES, LIST_ATTEMPTS, OWN_READ_TIMEOUT_MS, BOUNDED_OWN_METHODS;
|
|
55672
|
+
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, isSignature, isIndex, IMPORT_KEYS, IMPORT_MAX_VALUES, LIST_ATTEMPTS, OWN_READ_TIMEOUT_MS, BOUNDED_OWN_METHODS;
|
|
55620
55673
|
var init_compact = __esm({
|
|
55621
55674
|
"wallet/src/history/compact.mjs"() {
|
|
55622
55675
|
"use strict";
|
|
@@ -55727,6 +55780,7 @@ var init_compact = __esm({
|
|
|
55727
55780
|
};
|
|
55728
55781
|
hash4 = (left, right) => poseidon2([left, right], 3);
|
|
55729
55782
|
bitAt = (value, level) => Math.floor(value / 2 ** level) % 2;
|
|
55783
|
+
lastFolds = /* @__PURE__ */ new Map();
|
|
55730
55784
|
isSignature = (value) => typeof value === "string" && value.length >= 64 && value.length <= 88 && BASE58.test(value);
|
|
55731
55785
|
isIndex = (value) => Number.isSafeInteger(value) && value >= 0;
|
|
55732
55786
|
IMPORT_KEYS = ["afterOrdinal", "instructionIndex", "record", "signature", "slot", "transactionIndex", "values"];
|
|
@@ -56299,7 +56353,7 @@ function prewarmWalletP03History(args) {
|
|
|
56299
56353
|
return false;
|
|
56300
56354
|
}
|
|
56301
56355
|
}
|
|
56302
|
-
async function loadWalletP03HistoryNow({ store, connection: given, programId, pool: pool2, deploymentIdentity, cache, forceRead = false }) {
|
|
56356
|
+
async function loadWalletP03HistoryNow({ store, connection: given, programId, pool: pool2, deploymentIdentity, cache, forceRead = false, onCompactList }) {
|
|
56303
56357
|
const { connection, source } = resolveHistorySource(given, pool2);
|
|
56304
56358
|
announceHistorySource(source);
|
|
56305
56359
|
const split5 = connection?.historyRpc;
|
|
@@ -56329,7 +56383,17 @@ async function loadWalletP03HistoryNow({ store, connection: given, programId, po
|
|
|
56329
56383
|
}
|
|
56330
56384
|
}
|
|
56331
56385
|
if (split5 && cache === void 0 && (source === "pinned" || source === "flag")) {
|
|
56332
|
-
const compact = await compactFirst({
|
|
56386
|
+
const compact = await compactFirst({
|
|
56387
|
+
store,
|
|
56388
|
+
connection,
|
|
56389
|
+
source,
|
|
56390
|
+
programId,
|
|
56391
|
+
pool: pool2,
|
|
56392
|
+
deploymentIdentity,
|
|
56393
|
+
forceRead,
|
|
56394
|
+
knownSnapshot: movedSnapshot,
|
|
56395
|
+
onCompactList
|
|
56396
|
+
});
|
|
56333
56397
|
if (compact !== void 0) {
|
|
56334
56398
|
if (runKey !== void 0) rememberRunReport(runKey, compact);
|
|
56335
56399
|
return compact;
|
|
@@ -56369,7 +56433,7 @@ async function loadWalletP03HistoryNow({ store, connection: given, programId, po
|
|
|
56369
56433
|
if (runKey !== void 0) rememberRunReport(runKey, result.report);
|
|
56370
56434
|
return result.report;
|
|
56371
56435
|
}
|
|
56372
|
-
async function compactFirst({ store, connection, source, programId, pool: pool2, deploymentIdentity, forceRead, knownSnapshot }) {
|
|
56436
|
+
async function compactFirst({ store, connection, source, programId, pool: pool2, deploymentIdentity, forceRead, knownSnapshot, onCompactList }) {
|
|
56373
56437
|
const started = Date.now();
|
|
56374
56438
|
let behindNoticed = false;
|
|
56375
56439
|
let behindTries = 0;
|
|
@@ -56380,6 +56444,8 @@ async function compactFirst({ store, connection, source, programId, pool: pool2,
|
|
|
56380
56444
|
pool: pool2,
|
|
56381
56445
|
deploymentIdentity,
|
|
56382
56446
|
forceRead,
|
|
56447
|
+
// The served list, unverified, before its fold (compact.mjs onList): a payment's memo prefetch.
|
|
56448
|
+
...typeof onCompactList === "function" ? { onList: onCompactList } : {},
|
|
56383
56449
|
cache: walletCompactHistoryCache(store),
|
|
56384
56450
|
freshMs: HISTORY_WARM_FRESH_MS,
|
|
56385
56451
|
// The walk cache's attestation, read only when the compact cache holds none.
|
|
@@ -60363,7 +60429,7 @@ async function runRecover({ store, connection, programId, digests, serviceUrl: s
|
|
|
60363
60429
|
const pool2 = new import_web3102.PublicKey(state.pool);
|
|
60364
60430
|
const chainProgramId = new import_web3102.PublicKey(programId);
|
|
60365
60431
|
const poolStateRead = (async () => {
|
|
60366
|
-
const poolState3 = await readPoolState2(connection, pool2);
|
|
60432
|
+
const poolState3 = await (deps.poolState ?? readPoolState2(connection, pool2));
|
|
60367
60433
|
if (!poolState3) throw new Error("pool account not found");
|
|
60368
60434
|
if (!poolState3.owner.equals(chainProgramId)) throw new Error("pool account owner mismatch");
|
|
60369
60435
|
markPhase("recover-pool");
|
|
@@ -62405,6 +62471,7 @@ var init_errorCodes = __esm({
|
|
|
62405
62471
|
"fetch_url_refused",
|
|
62406
62472
|
"fetch_offer_unsupported",
|
|
62407
62473
|
"fetch_challenge_invalid",
|
|
62474
|
+
"fetch_seller_unreachable",
|
|
62408
62475
|
"fetch_session_closed",
|
|
62409
62476
|
"fetch_max_payment_required",
|
|
62410
62477
|
"mcp_cap_required",
|
|
@@ -71909,6 +71976,9 @@ async function prepareRecoveredPayment({
|
|
|
71909
71976
|
const generator = pinnedGenerator4();
|
|
71910
71977
|
const viewing = deriveWalletViewingAuthority2({ seedBytes: seedBytes5(state), generator });
|
|
71911
71978
|
const chainTime2 = deps.chainTime === void 0 ? startFinalizedChainTime(connection) : void 0;
|
|
71979
|
+
const poolState2 = deps.recover === void 0 ? readPoolState2(connection, pool2) : void 0;
|
|
71980
|
+
poolState2?.catch(() => {
|
|
71981
|
+
});
|
|
71912
71982
|
if (deps.provePayment === void 0 && proofTools !== void 0) {
|
|
71913
71983
|
(deps.prewarmProof ?? ((tools) => setImmediate(() => {
|
|
71914
71984
|
prewarmP03PaymentProofTools(tools).catch(() => {
|
|
@@ -71982,7 +72052,12 @@ async function prepareRecoveredPayment({
|
|
|
71982
72052
|
digests,
|
|
71983
72053
|
serviceUrl: serviceUrl2,
|
|
71984
72054
|
fresh: true,
|
|
71985
|
-
deps: {
|
|
72055
|
+
deps: {
|
|
72056
|
+
fetchImpl: deps.fetchImpl,
|
|
72057
|
+
finalizedHistory: history,
|
|
72058
|
+
transitionContextFor: history.transitionContextFor,
|
|
72059
|
+
...poolState2 !== void 0 ? { poolState: poolState2 } : {}
|
|
72060
|
+
}
|
|
71986
72061
|
});
|
|
71987
72062
|
markPhase("recover");
|
|
71988
72063
|
const unspentAccounts = recovery.recovered.filter((entry) => entry.kind === "account" && entry.spendStatus === "unspent");
|
|
@@ -72225,6 +72300,7 @@ var init_prepareRecoveredPayment = __esm({
|
|
|
72225
72300
|
init_recoveryPath();
|
|
72226
72301
|
init_recoveredPayment();
|
|
72227
72302
|
init_recover();
|
|
72303
|
+
init_chain2();
|
|
72228
72304
|
init_notes2();
|
|
72229
72305
|
init_accountSelection();
|
|
72230
72306
|
init_phaseTiming();
|
|
@@ -91169,6 +91245,7 @@ async function readJson(response, limit) {
|
|
|
91169
91245
|
}
|
|
91170
91246
|
}
|
|
91171
91247
|
async function readFloatConfig({ origin, fetchImpl = fetch }) {
|
|
91248
|
+
const readAtMs = Date.now();
|
|
91172
91249
|
let response;
|
|
91173
91250
|
try {
|
|
91174
91251
|
response = await fetchImpl(
|
|
@@ -91202,7 +91279,7 @@ async function readFloatConfig({ origin, fetchImpl = fetch }) {
|
|
|
91202
91279
|
if (config?.schema !== FLOAT_CONFIG_SCHEMA || !DECIMAL3.test(String(config.feeAtomic ?? "")) || !DECIMAL3.test(String(config.largestAtomic ?? "")) || typeof config.network !== "string" || typeof config.asset !== "string" || !prefix || prefix.pathname !== FLOAT_PAY_PATH || prefix.href !== config.payUrlPrefix || !feePayerOk) {
|
|
91203
91280
|
fail18("p03_float_config_unreadable");
|
|
91204
91281
|
}
|
|
91205
|
-
|
|
91282
|
+
const read = {
|
|
91206
91283
|
feeAtomic: String(config.feeAtomic),
|
|
91207
91284
|
largestAtomic: String(config.largestAtomic),
|
|
91208
91285
|
network: config.network,
|
|
@@ -91210,6 +91287,23 @@ async function readFloatConfig({ origin, fetchImpl = fetch }) {
|
|
|
91210
91287
|
payUrlPrefix: config.payUrlPrefix,
|
|
91211
91288
|
pocketFeePayer: config.pocketFeePayer
|
|
91212
91289
|
};
|
|
91290
|
+
configCache.set(origin, { config: read, readAtMs });
|
|
91291
|
+
return read;
|
|
91292
|
+
}
|
|
91293
|
+
function dropFloatConfigs() {
|
|
91294
|
+
configCache.clear();
|
|
91295
|
+
}
|
|
91296
|
+
async function readFloatOffer({ origin, paymentRequired, store, fetchImpl = fetch }) {
|
|
91297
|
+
const kept = configCache.get(origin);
|
|
91298
|
+
if (kept && Date.now() - kept.readAtMs < CONFIG_CACHE_MS) {
|
|
91299
|
+
try {
|
|
91300
|
+
return { offer: floatOffer({ paymentRequired, store, config: kept.config }), config: kept.config };
|
|
91301
|
+
} catch {
|
|
91302
|
+
configCache.delete(origin);
|
|
91303
|
+
}
|
|
91304
|
+
}
|
|
91305
|
+
const config = await readFloatConfig({ origin, fetchImpl });
|
|
91306
|
+
return { offer: floatOffer({ paymentRequired, store, config }), config };
|
|
91213
91307
|
}
|
|
91214
91308
|
function floatOriginOf(floatOrigin, serviceUrl2) {
|
|
91215
91309
|
const value = floatOrigin ?? serviceUrl2;
|
|
@@ -91303,7 +91397,7 @@ function withSellerResource(xPayment, record) {
|
|
|
91303
91397
|
return patched;
|
|
91304
91398
|
}
|
|
91305
91399
|
function floatFetch(base, seen) {
|
|
91306
|
-
|
|
91400
|
+
const wrapper = async (target, init = {}) => {
|
|
91307
91401
|
const response = await base(target, keepAliveInit(init));
|
|
91308
91402
|
const paid = Object.keys(init.headers ?? {}).some((name) => name.toLowerCase() === "payment-signature");
|
|
91309
91403
|
if (paid || response.status === 402 || response.status < 400) return response;
|
|
@@ -91325,6 +91419,7 @@ function floatFetch(base, seen) {
|
|
|
91325
91419
|
};
|
|
91326
91420
|
return new Response(null, { status: 400 });
|
|
91327
91421
|
};
|
|
91422
|
+
return Object.defineProperty(wrapper, "baseFetch", { value: base });
|
|
91328
91423
|
}
|
|
91329
91424
|
function floatRefusalError(refusal2, record) {
|
|
91330
91425
|
const extra = {
|
|
@@ -91471,6 +91566,7 @@ async function payViaFloat({
|
|
|
91471
91566
|
continue;
|
|
91472
91567
|
}
|
|
91473
91568
|
dropUnsent();
|
|
91569
|
+
dropFloatConfigs();
|
|
91474
91570
|
throw floatRefusalError(seen.refusal, record);
|
|
91475
91571
|
}
|
|
91476
91572
|
if (PENDING_CODES.has(error?.sellerCode) && Date.now() < finishingUntil) {
|
|
@@ -91572,7 +91668,7 @@ function paidResult(record, replayed) {
|
|
|
91572
91668
|
float: { floatId: record.floatId }
|
|
91573
91669
|
};
|
|
91574
91670
|
}
|
|
91575
|
-
var import_web3109, FLOAT_PAYMENT_SCHEMA, REGENERATE_CODES, FLOAT_PAYMENT_WAL_PREFIX, FLOAT_CONFIG_SCHEMA, FLOAT_PAY_PATH, MAX_BODY_BYTES, FLOAT_REFUND_ETA_SECONDS, REFUND_SETTLED_AFTER_MS, FINISHING_POLL_MS, FINISHING_LIMIT_MS, SELLER_TIMEOUT_MS, CONFIG_TIMEOUT_MS, DECIMAL3, POSITIVE, PENDING_CODES, hash8, fail18, floatPaymentWalName, plainText;
|
|
91671
|
+
var import_web3109, FLOAT_PAYMENT_SCHEMA, REGENERATE_CODES, FLOAT_PAYMENT_WAL_PREFIX, FLOAT_CONFIG_SCHEMA, FLOAT_PAY_PATH, MAX_BODY_BYTES, FLOAT_REFUND_ETA_SECONDS, REFUND_SETTLED_AFTER_MS, FINISHING_POLL_MS, FINISHING_LIMIT_MS, SELLER_TIMEOUT_MS, CONFIG_TIMEOUT_MS, CONFIG_CACHE_MS, DECIMAL3, POSITIVE, PENDING_CODES, hash8, fail18, floatPaymentWalName, configCache, plainText;
|
|
91576
91672
|
var init_floatPay = __esm({
|
|
91577
91673
|
"wallet/src/pay/floatPay.mjs"() {
|
|
91578
91674
|
"use strict";
|
|
@@ -91601,6 +91697,7 @@ var init_floatPay = __esm({
|
|
|
91601
91697
|
FINISHING_LIMIT_MS = 6e4;
|
|
91602
91698
|
SELLER_TIMEOUT_MS = 12e4;
|
|
91603
91699
|
CONFIG_TIMEOUT_MS = 3e4;
|
|
91700
|
+
CONFIG_CACHE_MS = 6e4;
|
|
91604
91701
|
DECIMAL3 = /^(0|[1-9][0-9]*)$/;
|
|
91605
91702
|
POSITIVE = /^[1-9][0-9]*$/;
|
|
91606
91703
|
PENDING_CODES = /* @__PURE__ */ new Set(["float_paid_finishing", "payment_pending_retry_same_payment"]);
|
|
@@ -91609,6 +91706,7 @@ var init_floatPay = __esm({
|
|
|
91609
91706
|
throw Object.assign(new Error(code), extra);
|
|
91610
91707
|
};
|
|
91611
91708
|
floatPaymentWalName = (requestKey) => `${FLOAT_PAYMENT_WAL_PREFIX}${requestKey}`;
|
|
91709
|
+
configCache = /* @__PURE__ */ new Map();
|
|
91612
91710
|
plainText = (value) => value.replace(/[^ -~]+/g, " ").trim().slice(0, 300);
|
|
91613
91711
|
}
|
|
91614
91712
|
});
|
|
@@ -117790,6 +117888,7 @@ init_payResource();
|
|
|
117790
117888
|
init_quote2();
|
|
117791
117889
|
init_floatPay();
|
|
117792
117890
|
init_walletHistory();
|
|
117891
|
+
init_recover();
|
|
117793
117892
|
init_keepAlive();
|
|
117794
117893
|
init_phaseTiming();
|
|
117795
117894
|
init_chain2();
|
|
@@ -118065,8 +118164,8 @@ async function offeredPrice(paymentRequired, store, serviceUrl2) {
|
|
|
118065
118164
|
}
|
|
118066
118165
|
if (rail === "exact" && store) {
|
|
118067
118166
|
const origin = new URL(serviceUrl2).origin;
|
|
118068
|
-
const config = await
|
|
118069
|
-
return { rail, amountAtomic:
|
|
118167
|
+
const { offer, config } = await readFloatOffer({ origin, paymentRequired, store });
|
|
118168
|
+
return { rail, amountAtomic: offer.paidAtomic, floatConfig: { origin, config } };
|
|
118070
118169
|
}
|
|
118071
118170
|
let highest;
|
|
118072
118171
|
for (const offer of paymentRequired.accepts) {
|
|
@@ -118140,7 +118239,7 @@ async function payAndFetch(session, url, init = {}, opts = {}) {
|
|
|
118140
118239
|
let challenge3;
|
|
118141
118240
|
if (!rerun) {
|
|
118142
118241
|
if (store !== void 0) startHistoryPrewarm(session, store, mark);
|
|
118143
|
-
const response = await
|
|
118242
|
+
const response = await unpaidRequest(target, () => keepAliveInit({
|
|
118144
118243
|
method,
|
|
118145
118244
|
headers,
|
|
118146
118245
|
...body ? { body } : {},
|
|
@@ -118183,6 +118282,19 @@ async function payAndFetch(session, url, init = {}, opts = {}) {
|
|
|
118183
118282
|
throw error;
|
|
118184
118283
|
}
|
|
118185
118284
|
}
|
|
118285
|
+
var UNPAID_NOT_SENT = /* @__PURE__ */ new Set(["UND_ERR_CONNECT_TIMEOUT", "ECONNREFUSED"]);
|
|
118286
|
+
async function unpaidRequest(target, init) {
|
|
118287
|
+
for (let attempt = 0; ; attempt += 1) {
|
|
118288
|
+
try {
|
|
118289
|
+
return await fetch(target, init());
|
|
118290
|
+
} catch (error) {
|
|
118291
|
+
const code = typeof error?.cause?.code === "string" && /^[A-Z][A-Z0-9_]{2,40}$/.test(error.cause.code) ? error.cause.code : void 0;
|
|
118292
|
+
if (attempt === 0 && UNPAID_NOT_SENT.has(code)) continue;
|
|
118293
|
+
const cause = error?.name === "TimeoutError" ? "no answer in 120 s" : code ?? "network error";
|
|
118294
|
+
fail20("fetch_seller_unreachable", `the seller did not answer the first, unpaid request (${cause}); nothing was paid`);
|
|
118295
|
+
}
|
|
118296
|
+
}
|
|
118297
|
+
}
|
|
118186
118298
|
function startHistoryPrewarm(session, store, mark) {
|
|
118187
118299
|
try {
|
|
118188
118300
|
withPhaseScope(mark, "prewarm", () => prewarmWalletP03History({
|
|
@@ -118190,7 +118302,16 @@ function startHistoryPrewarm(session, store, mark) {
|
|
|
118190
118302
|
connection: connectSplit(session.connection, session.historyUrl),
|
|
118191
118303
|
programId: session.programId,
|
|
118192
118304
|
pool: store.state.pool,
|
|
118193
|
-
deploymentIdentity: session.proofTools.deploymentIdentity
|
|
118305
|
+
deploymentIdentity: session.proofTools.deploymentIdentity,
|
|
118306
|
+
// The memos the proof's recovery will read, asked when the compact list arrives, beside
|
|
118307
|
+
// its fold, spot checks, and attestation (B2 #3, 2026-10-15: the recovery waited 0.18-0.44 s
|
|
118308
|
+
// for them after the walk, M). The same set the recovery asks (every listed transition
|
|
118309
|
+
// its cache lacks); it takes an answer only for a transition of the verified report
|
|
118310
|
+
// (chain.mjs createMemoReader prefetch; recover.mjs checks each bundle's digest).
|
|
118311
|
+
onCompactList: (contexts) => {
|
|
118312
|
+
markPhase("memo-prefetch");
|
|
118313
|
+
prefetchRecoveryMemos({ store, finalizedHistory: { contexts }, serviceUrl: session.memoServiceUrl, programId: session.programId });
|
|
118314
|
+
}
|
|
118194
118315
|
}));
|
|
118195
118316
|
} catch {
|
|
118196
118317
|
}
|
|
@@ -125294,8 +125415,7 @@ async function railOffer(paymentRequired, rail, store, facilitator) {
|
|
|
125294
125415
|
}
|
|
125295
125416
|
try {
|
|
125296
125417
|
if (!facilitator) throw new Error("p03_float_origin_missing");
|
|
125297
|
-
const
|
|
125298
|
-
const offer = floatOffer({ paymentRequired, store, config });
|
|
125418
|
+
const { offer } = await readFloatOffer({ origin: new URL(facilitator).origin, paymentRequired, store });
|
|
125299
125419
|
return { priceAtomic: offer.priceAtomic, feeAtomic: offer.feeAtomic, totalAtomic: offer.paidAtomic };
|
|
125300
125420
|
} catch (error) {
|
|
125301
125421
|
const refusal2 = floatRefusal(error) ?? ["p03_float_config_unreadable", "the price through Shinjuku could not be read; nothing was paid", "call x402_preview again in a minute"];
|
|
@@ -125546,15 +125666,16 @@ async function runShieldFromElsewhere({ session, depositId, amountAtomic, onStag
|
|
|
125546
125666
|
const result = await (steps.submit ?? submitRelayedDeposit)(common);
|
|
125547
125667
|
return { state: result.state, transaction: typeof result.receipt?.signature === "string" ? result.receipt.signature : null };
|
|
125548
125668
|
}
|
|
125549
|
-
|
|
125669
|
+
var walkWalletHistory = (session, store) => loadWalletP03History({
|
|
125670
|
+
store,
|
|
125671
|
+
connection: connectSplit(session.connection, session.historyUrl),
|
|
125672
|
+
programId: session.programId,
|
|
125673
|
+
pool: store.state.pool,
|
|
125674
|
+
deploymentIdentity: session.proofTools.deploymentIdentity
|
|
125675
|
+
});
|
|
125676
|
+
async function refreshWallet({ session, store, history: walked }) {
|
|
125550
125677
|
const walStates = captureWalStates(store);
|
|
125551
|
-
const history = await
|
|
125552
|
-
store,
|
|
125553
|
-
connection: connectSplit(session.connection, session.historyUrl),
|
|
125554
|
-
programId: session.programId,
|
|
125555
|
-
pool: store.state.pool,
|
|
125556
|
-
deploymentIdentity: session.proofTools.deploymentIdentity
|
|
125557
|
-
});
|
|
125678
|
+
const history = walked ?? await walkWalletHistory(session, store);
|
|
125558
125679
|
const result = await runRecover({
|
|
125559
125680
|
store,
|
|
125560
125681
|
connection: session.connection,
|
|
@@ -125800,7 +125921,9 @@ function createWalletTools({
|
|
|
125800
125921
|
let refreshRun;
|
|
125801
125922
|
let refreshFailedAt = 0;
|
|
125802
125923
|
let refreshFailedCode;
|
|
125803
|
-
|
|
125924
|
+
let refreshInBackground = false;
|
|
125925
|
+
const refreshStep = (store, history) => (ops.refresh ?? refreshWallet)({ session, store, ...history ? { history } : {} });
|
|
125926
|
+
const refreshWalk = ops.refreshWalk ?? (ops.refresh ? void 0 : (store) => walkWalletHistory(session, store));
|
|
125804
125927
|
const errorCode2 = (error, fallback) => describeError(error, { fallback, safeText: SAFE_TEXT }).split(/[\s:;(]/, 1)[0];
|
|
125805
125928
|
const underLease = (task) => session.serial(async () => {
|
|
125806
125929
|
let release;
|
|
@@ -125944,9 +126067,27 @@ function createWalletTools({
|
|
|
125944
126067
|
deps: ops.oneTimeAdopt && typeof ops.oneTimeAdopt === "object" ? ops.oneTimeAdopt : {}
|
|
125945
126068
|
});
|
|
125946
126069
|
if (ops.oneTimeAdopt !== false) adopter.start();
|
|
125947
|
-
function refreshShared() {
|
|
126070
|
+
function refreshShared({ background = false } = {}) {
|
|
125948
126071
|
if (!refreshRun) {
|
|
125949
|
-
|
|
126072
|
+
refreshInBackground = background;
|
|
126073
|
+
refreshRun = (async () => {
|
|
126074
|
+
let early;
|
|
126075
|
+
if (background && refreshWalk) {
|
|
126076
|
+
try {
|
|
126077
|
+
const store = session.openStore();
|
|
126078
|
+
const records = JSON.stringify(captureWalStates(store));
|
|
126079
|
+
const pool2 = store.state.pool;
|
|
126080
|
+
early = { records, pool: pool2, history: await refreshWalk(store) };
|
|
126081
|
+
} catch {
|
|
126082
|
+
early = void 0;
|
|
126083
|
+
}
|
|
126084
|
+
}
|
|
126085
|
+
return underLease((store) => {
|
|
126086
|
+
const same2 = early !== void 0 && early.pool === store.state.pool && early.records === JSON.stringify(captureWalStates(store));
|
|
126087
|
+
if (early !== void 0 && !same2) log("MCP_REFRESH_WALK_AGAIN");
|
|
126088
|
+
return refreshStep(store, same2 ? early.history : void 0);
|
|
126089
|
+
});
|
|
126090
|
+
})().then(() => {
|
|
125950
126091
|
refreshFailedAt = 0;
|
|
125951
126092
|
log("MCP_REFRESH_DONE");
|
|
125952
126093
|
}, (error) => {
|
|
@@ -125956,6 +126097,7 @@ function createWalletTools({
|
|
|
125956
126097
|
throw error;
|
|
125957
126098
|
}).finally(() => {
|
|
125958
126099
|
refreshRun = void 0;
|
|
126100
|
+
refreshInBackground = false;
|
|
125959
126101
|
});
|
|
125960
126102
|
}
|
|
125961
126103
|
return refreshRun;
|
|
@@ -125988,7 +126130,7 @@ function createWalletTools({
|
|
|
125988
126130
|
}
|
|
125989
126131
|
if (watched === finalityTarget && status?.confirmationStatus === "finalized") {
|
|
125990
126132
|
log("MCP_FINALITY_REFRESH");
|
|
125991
|
-
await refreshShared().catch(() => {
|
|
126133
|
+
await refreshShared({ background: true }).catch(() => {
|
|
125992
126134
|
});
|
|
125993
126135
|
return;
|
|
125994
126136
|
}
|
|
@@ -126013,6 +126155,7 @@ function createWalletTools({
|
|
|
126013
126155
|
return;
|
|
126014
126156
|
}
|
|
126015
126157
|
if (!stale || refreshFailedAt && Date.now() - refreshFailedAt < REFRESH_RETRY_MS) return;
|
|
126158
|
+
if (finalityWait || refreshRun && refreshInBackground) return;
|
|
126016
126159
|
await refreshShared().catch(() => {
|
|
126017
126160
|
});
|
|
126018
126161
|
}
|
|
@@ -126388,6 +126531,8 @@ function createWalletTools({
|
|
|
126388
126531
|
);
|
|
126389
126532
|
} else if (code.startsWith("wallet_spend_refused_")) {
|
|
126390
126533
|
next = "the wallet file's own budget refused it (init --max-payment / --max-cumulative); nothing was paid. Read wallet_balance detail.budget";
|
|
126534
|
+
} else if (code === "fetch_seller_unreachable") {
|
|
126535
|
+
next = `Nothing was paid and nothing was sent to the seller. Call x402_pay again with request_id "${requestId}" and the same url, method, headers, and body (it never pays twice); if it fails the same way again, the seller is down: tell your owner`;
|
|
126391
126536
|
} else if (code.startsWith("wallet_quote_refused_") || code.startsWith("fetch_")) {
|
|
126392
126537
|
next = "nothing was paid; do not retry this URL unchanged";
|
|
126393
126538
|
} else {
|
|
@@ -135601,6 +135746,7 @@ function failureHint(command, reason, deps, values) {
|
|
|
135601
135746
|
if (/fetch_offer_unsupported/.test(reason)) {
|
|
135602
135747
|
return `nothing was paid: the seller's 402 offers no scheme this wallet pays (shielded-exact, or standard exact through Shinjuku). Hidden-amount (confidential) payments are retired since 2026-10-11`;
|
|
135603
135748
|
}
|
|
135749
|
+
if (/fetch_seller_unreachable/.test(reason)) return "nothing was paid: the seller did not answer the first, unpaid request. Rerun the same command (same --request-id) later; if it fails again, the seller is down";
|
|
135604
135750
|
if (/fetch_challenge_invalid/.test(reason)) return "nothing was paid: the seller's 402 is not a valid x402 v2 challenge (PAYMENT-REQUIRED header). Do not pay this seller until it sends one";
|
|
135605
135751
|
if (/fetch_url_refused/.test(reason)) return "nothing was sent: use the https URL. Plain http goes only to a private host (localhost, 10.x, 192.168.x) or to an .onion inside a --tor run";
|
|
135606
135752
|
if (/fetch_options_invalid/.test(reason)) {
|