shinjuku-shielded 0.3.59 → 0.3.61

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 CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "schema": "carbon-shielded-wallet/bundle-manifest/v1",
3
3
  "file": "shinjuku-wallet.mjs",
4
- "sha256": "a18f4dcc8553e48c173aa610e7b3632d8edb25dbe317dd1f820e44673dd0fa39",
5
- "bytes": 12158087,
6
- "sourceCommit": "4274f17fee017d2010ae9d1ca94c5c03d200effc",
4
+ "sha256": "fd8f40cfc0110953e30d8479bfe751545e04952df8faf03b634073d7fd308c78",
5
+ "bytes": 12166389,
6
+ "sourceCommit": "c40abda927c59b08675a7e8c6067ace24cf24e78",
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-22T04:38:17.814Z"
1285
+ "publishedAt": "2026-10-22T06:27:33.519Z"
1286
1286
  }
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "shinjuku-shielded",
3
- "version": "0.3.59",
3
+ "version": "0.3.61",
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": "a18f4dcc",
7
- "shinjukuSha256": "a18f4dcc8553e48c173aa610e7b3632d8edb25dbe317dd1f820e44673dd0fa39",
6
+ "shinjukuRelease": "fd8f40cf",
7
+ "shinjukuSha256": "fd8f40cfc0110953e30d8479bfe751545e04952df8faf03b634073d7fd308c78",
8
8
  "license": "SEE LICENSE IN LICENSE.txt",
9
9
  "author": "Shinjuku Shielded",
10
10
  "homepage": "https://github.com/ShinjukuStaition/shinjuku-mcp#readme",
@@ -42630,7 +42630,15 @@ function warmOnions({ onions = routedOnions(), fetchImpl = globalThis.fetch, tim
42630
42630
  }
42631
42631
  return () => controller.abort();
42632
42632
  }
42633
- function raceOnions(onions, { fetchImpl = globalThis.fetch, timeoutMs = RACE_TIMEOUT_MS, path = "/api/health", onNone } = {}) {
42633
+ function raceOnions(onions, {
42634
+ fetchImpl = globalThis.fetch,
42635
+ timeoutMs = RACE_TIMEOUT_MS,
42636
+ path = "/api/health",
42637
+ onNone,
42638
+ spares = [],
42639
+ spareAfterMs = SPARE_AFTER_MS,
42640
+ onSpares
42641
+ } = {}) {
42634
42642
  const controller = new AbortController();
42635
42643
  const signal = AbortSignal.any([controller.signal, AbortSignal.timeout(timeoutMs)]);
42636
42644
  const probe = (onion) => Promise.resolve().then(() => fetchImpl(`${onion}${path}`, onionInit({ redirect: "error", signal, headers: { accept: "application/json" } }))).then((response) => {
@@ -42639,11 +42647,46 @@ function raceOnions(onions, { fetchImpl = globalThis.fetch, timeoutMs = RACE_TIM
42639
42647
  if (!response?.ok) throw new Error(`onion answered ${response?.status}`);
42640
42648
  return onion;
42641
42649
  });
42642
- const winner = Promise.any(onions.map(probe)).catch(() => {
42643
- if (!controller.signal.aborted) onNone?.();
42644
- return onions[0];
42645
- }).finally(() => controller.abort());
42646
- return { winner, abort: () => controller.abort() };
42650
+ let startSpares = () => {
42651
+ };
42652
+ let spareTimer;
42653
+ const winner = new Promise((resolve38) => {
42654
+ let open3 = 0;
42655
+ let done = false;
42656
+ let sparesStarted = spares.length === 0;
42657
+ const settle = (onion) => {
42658
+ if (done) return;
42659
+ done = true;
42660
+ resolve38(onion);
42661
+ };
42662
+ const failed = () => {
42663
+ open3 -= 1;
42664
+ if (open3 > 0 || done) return;
42665
+ if (!sparesStarted && !signal.aborted) return startSpares();
42666
+ if (!controller.signal.aborted) onNone?.();
42667
+ settle(onions[0]);
42668
+ };
42669
+ const start = (onion) => {
42670
+ open3 += 1;
42671
+ probe(onion).then(settle, failed);
42672
+ };
42673
+ startSpares = () => {
42674
+ if (sparesStarted || done || signal.aborted) return;
42675
+ sparesStarted = true;
42676
+ clearTimeout(spareTimer);
42677
+ onSpares?.();
42678
+ for (const onion of spares) start(onion);
42679
+ };
42680
+ if (!sparesStarted) {
42681
+ spareTimer = setTimeout(() => startSpares(), spareAfterMs);
42682
+ spareTimer.unref?.();
42683
+ }
42684
+ for (const onion of onions) start(onion);
42685
+ }).finally(() => {
42686
+ clearTimeout(spareTimer);
42687
+ controller.abort();
42688
+ });
42689
+ return { winner, abort: () => controller.abort(), startSpares: () => startSpares() };
42647
42690
  }
42648
42691
  function facilitatorOrigins(argv2) {
42649
42692
  const origins = /* @__PURE__ */ new Set();
@@ -42692,7 +42735,8 @@ async function routeFacilitatorsOverOnion(argv2, {
42692
42735
  fetchImpl = globalThis.fetch,
42693
42736
  err = (text3) => process.stderr.write(text3),
42694
42737
  raceTimeoutMs = RACE_TIMEOUT_MS,
42695
- routeWaitMs = ROUTE_WAIT_MS
42738
+ routeWaitMs = ROUTE_WAIT_MS,
42739
+ spareAfterMs = SPARE_AFTER_MS
42696
42740
  } = {}) {
42697
42741
  const routes = /* @__PURE__ */ new Map();
42698
42742
  const groups = /* @__PURE__ */ new Map();
@@ -42700,17 +42744,29 @@ async function routeFacilitatorsOverOnion(argv2, {
42700
42744
  for (const origin of named.length > 0 ? named : [DEFAULT_FACILITATOR_ORIGIN]) {
42701
42745
  const pinned = PINNED_FACILITATOR_ONIONS[origin];
42702
42746
  const onions = (pinned ?? [await publishedOnion(origin, fetchImpl)]).filter((onion) => onion && V3_ONION.test(onion));
42747
+ const spares = pinned ? (PINNED_SPARE_ONIONS[origin] ?? []).filter((onion) => V3_ONION.test(onion)) : [];
42703
42748
  if (onions.length > 0) {
42704
42749
  const key = onions.join(" ");
42705
42750
  if (!groups.has(key)) {
42706
- groups.set(key, { onions, waitMs: routeWaitMs, onNone: () => err(`tor: no onion of ${origin} answered its start probe (${onions.length} tried); its requests go to its onions in turn and wait for them (Tor may still be building circuits)
42707
- `) });
42751
+ const spareHosts = spares.map((onion) => `${new URL(onion).host.slice(0, 8)}...`).join(", ");
42752
+ const group = {
42753
+ onions: [...onions, ...spares],
42754
+ live: onions.length,
42755
+ spares,
42756
+ waitMs: routeWaitMs,
42757
+ onSpares: () => err(`tor: no onion of ${origin} has answered yet; its ${spares.length} spare onions ${spareHosts} join (Tor may still be fetching the onion addresses)
42758
+ `),
42759
+ onNone: () => err(`tor: no onion of ${origin} answered its start probe (${liveOnions(group).length} tried); its requests go to its onions in turn and wait for them (Tor may still be building circuits)
42760
+ `)
42761
+ };
42762
+ groups.set(key, group);
42708
42763
  }
42709
42764
  routes.set(origin, groups.get(key));
42710
42765
  routes.set(payHostOf(origin), groups.get(key));
42711
42766
  const hosts = onions.map((onion) => `${new URL(onion).host.slice(0, 8)}...`).join(", ");
42712
42767
  const source = pinned ? "pinned in this wallet" : `published by ${origin}`;
42713
- err(`tor: ${origin} is reached over its onion service ${hosts} (${onions.length > 1 ? `${source}; the first to answer serves this run` : source}), so no Tor exit and no front such as Cloudflare sees these requests
42768
+ const spareNote = spares.length > 0 ? `; ${spares.length} spares join if none answers in ${Math.round(spareAfterMs / 1e3)} s` : "";
42769
+ err(`tor: ${origin} is reached over its onion service ${hosts} (${onions.length > 1 ? `${source}; the first to answer serves this run` : source}${spareNote}), so no Tor exit and no front such as Cloudflare sees these requests
42714
42770
  `);
42715
42771
  } else {
42716
42772
  err(`tor: ${origin} publishes no onion service; its requests go through a Tor exit, which sees the host name (TLS hides the content)
@@ -42734,12 +42790,18 @@ async function routeFacilitatorsOverOnion(argv2, {
42734
42790
  aborts.push(warmOnions({ onions: group.onions, fetchImpl }));
42735
42791
  continue;
42736
42792
  }
42737
- const race = raceOnions(group.onions, {
42793
+ const spares = group.spares ?? [];
42794
+ const race = raceOnions(liveOnions(group), {
42738
42795
  fetchImpl,
42739
42796
  timeoutMs: raceTimeoutMs,
42740
42797
  ...group.path ? { path: group.path } : {},
42741
- ...group.onNone ? { onNone: group.onNone } : {}
42798
+ ...group.onNone ? { onNone: group.onNone } : {},
42799
+ ...spares.length > 0 ? { spares, spareAfterMs, onSpares: () => {
42800
+ group.live = group.onions.length;
42801
+ group.onSpares?.();
42802
+ } } : {}
42742
42803
  });
42804
+ group.startSpares = race.startSpares;
42743
42805
  group.pending = race.winner.then((onion) => {
42744
42806
  group.winner = onion;
42745
42807
  group.pending = void 0;
@@ -42760,7 +42822,11 @@ async function routeFacilitatorsOverOnion(argv2, {
42760
42822
  const group = url && routes.get(url.origin);
42761
42823
  if (!group) return original(input, init);
42762
42824
  const send3 = (onion) => {
42763
- if (onion === void 0) onion = group.onions[(group.sent = (group.sent ?? 0) + 1) % group.onions.length];
42825
+ if (onion === void 0) {
42826
+ group.startSpares?.();
42827
+ const live = liveOnions(group);
42828
+ onion = live[(group.sent = (group.sent ?? 0) + 1) % live.length];
42829
+ }
42764
42830
  const target = `${onion}${url.pathname}${url.search}`;
42765
42831
  return original(input instanceof Request ? new Request(target, input) : target, onionInit(init));
42766
42832
  };
@@ -42782,7 +42848,7 @@ async function routeFacilitatorsOverOnion(argv2, {
42782
42848
  }
42783
42849
  };
42784
42850
  }
42785
- var SITE_ONIONS, PINNED_FACILITATOR_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, routedGroups, routedOnions, routedOrigins, onionsOfOrigin, routesOverOnion, GLOBAL_DISPATCHER, onionDispatchers;
42851
+ 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, routedGroups, liveOnions, routedOnions, routedOrigins, onionsOfOrigin, routesOverOnion, GLOBAL_DISPATCHER, onionDispatchers;
42786
42852
  var init_facilitatorOnion = __esm({
42787
42853
  "wallet/src/net/facilitatorOnion.mjs"() {
42788
42854
  "use strict";
@@ -42791,11 +42857,20 @@ var init_facilitatorOnion = __esm({
42791
42857
  "http://2kfhlfuyuwvhmibjrpxqsg4nrbcxasjgjq7kmnfzgfwzptkhhznz3dad.onion",
42792
42858
  "http://chhgw7nfggqhhjawz54bpsiihdow66s2yvkh6ccnugpcdmhhww6xkkqd.onion"
42793
42859
  ]);
42860
+ SITE_SPARE_ONIONS = Object.freeze([
42861
+ "http://ntr5qkdfgff4gspwderjnqtkzekyhb5a4j76ov4dqncxmcb53gdsmmid.onion",
42862
+ "http://vofhhl336r4bnwn7hid2uvqaa72wx66xkdu2yt4n54xljsxwn2yds6qd.onion"
42863
+ ]);
42794
42864
  PINNED_FACILITATOR_ONIONS = Object.freeze({
42795
42865
  "https://shinjukustaition.com": SITE_ONIONS,
42796
42866
  "https://www.shinjukustaition.com": SITE_ONIONS,
42797
42867
  "https://pay.shinjukustaition.com": SITE_ONIONS
42798
42868
  });
42869
+ PINNED_SPARE_ONIONS = Object.freeze({
42870
+ "https://shinjukustaition.com": SITE_SPARE_ONIONS,
42871
+ "https://www.shinjukustaition.com": SITE_SPARE_ONIONS,
42872
+ "https://pay.shinjukustaition.com": SITE_SPARE_ONIONS
42873
+ });
42799
42874
  HISTORY_ONIONS = Object.freeze([
42800
42875
  "http://d6xg3phhurxhzqcsgh2mh52yf744labhrnd7mducwynlertfsjzyslqd.onion",
42801
42876
  "http://3yccoinnouxbjx3emvdxwhbu56cq4de7sfwgvcp4xb7hveccnpurcrid.onion",
@@ -42810,8 +42885,10 @@ var init_facilitatorOnion = __esm({
42810
42885
  WARM_TIMEOUT_MS = 3e4;
42811
42886
  RACE_TIMEOUT_MS = 9e4;
42812
42887
  ROUTE_WAIT_MS = 15e3;
42888
+ SPARE_AFTER_MS = ROUTE_WAIT_MS;
42813
42889
  routedGroups = [];
42814
- routedOnions = () => [...new Set(routedGroups.flatMap((group) => group.winner ? [group.winner] : group.onions))];
42890
+ liveOnions = (group) => group.onions.slice(0, group.live ?? group.onions.length);
42891
+ routedOnions = () => [...new Set(routedGroups.flatMap((group) => group.winner ? [group.winner] : liveOnions(group)))];
42815
42892
  routedOrigins = /* @__PURE__ */ new Map();
42816
42893
  onionsOfOrigin = (origin) => routedOrigins.get(origin) ?? PINNED_FACILITATOR_ONIONS[origin] ?? [];
42817
42894
  routesOverOnion = (origin) => routedOrigins.has(origin);
@@ -47584,7 +47661,7 @@ function readE1TreeAccount(bytes2) {
47584
47661
  leaves: v.getUint32(RIGHTMOST_OFFSET + 32 * D + 32, true)
47585
47662
  };
47586
47663
  }
47587
- var E1, E1_VALUES_PER_TAG, E1_INPUTS_PER_TAG, E1_REPLAY_INPUT_INDICES, E1_ERROR_CODES, D, B, C, LOWER, TREE_MAGIC, CHANGELOG_BYTES, CHANGELOGS_OFFSET, RIGHTMOST_OFFSET, CANOPY_OFFSET, CANOPY_NODES, ZERO, MAX2, fail, eq32, isZero, u32le, asValue, node, EMPTY_NODES, hashToParent, B58, R_FIELD, CPROOF, bigOf, isCanonical, E1_LOADED_ACCOUNT_SIZES, ACCOUNT_OVERHEAD, sizeOk, hexOf, E1TreeMirror;
47664
+ var E1, E1_VALUES_PER_TAG, E1_INPUTS_PER_TAG, E1_REPLAY_INPUT_INDICES, E1_ERROR_CODES, D, B, C, LOWER, TREE_MAGIC, CHANGELOG_BYTES, CHANGELOGS_OFFSET, RIGHTMOST_OFFSET, CANOPY_OFFSET, CANOPY_NODES, ZERO, MAX2, fail, eq32, isZero, u32le, asValue, node, EMPTY_NODES, hashToParent, B58, R_FIELD, CPROOF, bigOf, isCanonical, E1_LOADED_ACCOUNT_SIZES, ACCOUNT_OVERHEAD, sizeOk, hexOf, BUILD_STEP_NODES, E1TreeMirror;
47588
47665
  var init_p03E1Tree = __esm({
47589
47666
  "wallet/vendor/shared/p03E1Tree.mjs"() {
47590
47667
  "use strict";
@@ -47695,6 +47772,7 @@ var init_p03E1Tree = __esm({
47695
47772
  for (const x of b) s4 += x.toString(16).padStart(2, "0");
47696
47773
  return s4;
47697
47774
  };
47775
+ BUILD_STEP_NODES = 64;
47698
47776
  E1TreeMirror = class _E1TreeMirror {
47699
47777
  #levels;
47700
47778
  // #levels[l][i] = node at level l (0 = leaves), undefined = empty subtree
@@ -47712,14 +47790,28 @@ var init_p03E1Tree = __esm({
47712
47790
  }
47713
47791
  /** Sentinel, then every value in the given order (chain order, each settle already sorted). */
47714
47792
  static fromOrderedValues(values) {
47793
+ const build2 = _E1TreeMirror.fromOrderedValuesSteps(values);
47794
+ for (; ; ) {
47795
+ const step = build2.next();
47796
+ if (step.done) return step.value;
47797
+ }
47798
+ }
47799
+ /**
47800
+ * fromOrderedValues in steps, for a caller that keeps its thread free between them (the wallet
47801
+ * builds the tree of its cached settles at start, in slices): one step per value inserted and per
47802
+ * BUILD_STEP_NODES hashes. The generator returns the mirror fromOrderedValues returns, and throws
47803
+ * where it throws.
47804
+ */
47805
+ static *fromOrderedValuesSteps(values) {
47715
47806
  const m = new _E1TreeMirror();
47716
47807
  m.#sorted.push(m.#pushLeaf({ value: ZERO, nextValue: MAX2, nextIndex: 0 }));
47717
47808
  for (const v of values) {
47718
47809
  asValue(v);
47719
47810
  if (isZero(v)) fail("p03_e1_value_zero");
47720
47811
  m.#linkInsert(v);
47812
+ yield;
47721
47813
  }
47722
- m.#rebuildNodes();
47814
+ yield* m.#rebuildNodes();
47723
47815
  return m;
47724
47816
  }
47725
47817
  clone() {
@@ -47841,11 +47933,20 @@ var init_p03E1Tree = __esm({
47841
47933
  this.#levels[l + 1][i >>> 1] = n;
47842
47934
  }
47843
47935
  }
47844
- #rebuildNodes() {
47845
- this.#levels[0] = this.#leaves.map((l) => e1LeafHash(l));
47936
+ // Every node from the leaves up, a step per BUILD_STEP_NODES hashes (fromOrderedValuesSteps).
47937
+ *#rebuildNodes() {
47938
+ const hashed = new Array(this.#leaves.length);
47939
+ for (let i = 0; i < hashed.length; i++) {
47940
+ hashed[i] = e1LeafHash(this.#leaves[i]);
47941
+ if ((i + 1) % BUILD_STEP_NODES === 0) yield;
47942
+ }
47943
+ this.#levels[0] = hashed;
47846
47944
  for (let l = 0; l < D; l++) {
47847
47945
  const below = this.#levels[l], up = new Array(Math.ceil(below.length / 2));
47848
- for (let i = 0; i < up.length; i++) up[i] = node(below[2 * i], below[2 * i + 1] ?? EMPTY_NODES[l]);
47946
+ for (let i = 0; i < up.length; i++) {
47947
+ up[i] = node(below[2 * i], below[2 * i + 1] ?? EMPTY_NODES[l]);
47948
+ if ((i + 1) % BUILD_STEP_NODES === 0) yield;
47949
+ }
47849
47950
  this.#levels[l + 1] = up;
47850
47951
  }
47851
47952
  }
@@ -54587,19 +54688,70 @@ function initializationReplayStore(instruction) {
54587
54688
  if (data.length === 123 && data[122] === REPLAY_STORE_INDEXED) return REPLAY_STORE_INDEXED;
54588
54689
  return void 0;
54589
54690
  }
54590
- function replayedE1Mirror(key, settles, matchesChain) {
54691
+ function e1SettleCopies(settles) {
54591
54692
  const wellFormed2 = settles.every((values) => Array.isArray(values) && values.every((value) => value instanceof Uint8Array && value.length === 32));
54592
- const copies = wellFormed2 ? settles.map((values) => values.map((value) => Uint8Array.from(value))) : settles;
54593
- const settleKeys = wellFormed2 ? copies.map((values) => values.map((value) => Buffer.from(value).toString("hex")).join("")) : void 0;
54693
+ if (!wellFormed2) return { copies: settles, keys: void 0 };
54694
+ const copies = settles.map((values) => values.map((value) => Uint8Array.from(value)));
54695
+ return { copies, keys: copies.map((values) => values.map((value) => Buffer.from(value).toString("hex")).join("")) };
54696
+ }
54697
+ function runE1TreeCandidate(candidate, untilMs = Infinity) {
54698
+ try {
54699
+ while (candidate.mirror === void 0 && !candidate.failed) {
54700
+ const step = candidate.build.next();
54701
+ if (step.done) candidate.mirror = step.value;
54702
+ else if (performance.now() >= untilMs) break;
54703
+ }
54704
+ } catch {
54705
+ candidate.failed = true;
54706
+ }
54707
+ return candidate.failed ? void 0 : candidate.mirror;
54708
+ }
54709
+ function startE1TreeCandidate({ key, settles, sliceMs = 8 }) {
54710
+ try {
54711
+ if (lastVerifiedE1Tree?.key === key || e1TreeCandidate?.key === key) return void 0;
54712
+ const { copies, keys: keys3 } = e1SettleCopies(settles);
54713
+ if (keys3 === void 0) return void 0;
54714
+ const candidate = {
54715
+ key,
54716
+ settles: keys3,
54717
+ build: E1TreeMirror.fromOrderedValuesSteps(copies.flatMap((values) => e1SortValues(values))),
54718
+ mirror: void 0,
54719
+ failed: false
54720
+ };
54721
+ e1TreeCandidate = candidate;
54722
+ let hurry = false;
54723
+ const done = (async () => {
54724
+ while (e1TreeCandidate === candidate && candidate.mirror === void 0 && !candidate.failed) {
54725
+ runE1TreeCandidate(candidate, hurry ? Infinity : performance.now() + sliceMs);
54726
+ if (candidate.mirror === void 0 && !candidate.failed) await new Promise((resolve38) => setImmediate(resolve38));
54727
+ }
54728
+ return candidate.mirror !== void 0 && !candidate.failed;
54729
+ })();
54730
+ return { done, hurry: () => {
54731
+ hurry = true;
54732
+ } };
54733
+ } catch {
54734
+ return void 0;
54735
+ }
54736
+ }
54737
+ function replayedE1Mirror(key, settles, matchesChain) {
54738
+ const { copies, keys: settleKeys } = e1SettleCopies(settles);
54739
+ const wellFormed2 = settleKeys !== void 0;
54740
+ const startsThis = (kept) => kept.length <= settleKeys.length && kept.every((value, index) => value === settleKeys[index]);
54741
+ const candidate = e1TreeCandidate?.key === key ? e1TreeCandidate : void 0;
54742
+ if (candidate !== void 0) e1TreeCandidate = void 0;
54594
54743
  const last = lastVerifiedE1Tree;
54595
- if (wellFormed2 && last?.key === key && last.settles.length <= settleKeys.length && last.settles.every((value, index) => value === settleKeys[index])) {
54744
+ const base = !wellFormed2 ? void 0 : last?.key === key && startsThis(last.settles) ? { settles: last.settles, mirror: () => last.mirror.clone(), count: "extended" } : candidate !== void 0 && startsThis(candidate.settles) ? { settles: candidate.settles, mirror: () => runE1TreeCandidate(candidate), count: "candidate" } : void 0;
54745
+ if (base !== void 0) {
54596
54746
  try {
54597
- const mirror2 = last.mirror.clone();
54598
- for (const values of copies.slice(last.settles.length)) mirror2.insertSettle(values);
54599
- if (matchesChain(mirror2)) {
54600
- lastVerifiedE1Tree = { key, settles: settleKeys, mirror: mirror2 };
54601
- e1ReplayCounts.extended += 1;
54602
- return mirror2;
54747
+ const mirror2 = base.mirror();
54748
+ if (mirror2 !== void 0) {
54749
+ for (const values of copies.slice(base.settles.length)) mirror2.insertSettle(values);
54750
+ if (matchesChain(mirror2)) {
54751
+ lastVerifiedE1Tree = { key, settles: settleKeys, mirror: mirror2 };
54752
+ e1ReplayCounts[base.count] += 1;
54753
+ return mirror2;
54754
+ }
54603
54755
  }
54604
54756
  } catch {
54605
54757
  }
@@ -55451,7 +55603,7 @@ function base58Decode(value) {
55451
55603
  while (zeros < value.length && value[zeros] === "1") zeros += 1;
55452
55604
  return Uint8Array.from(Buffer.concat([Buffer.alloc(zeros), body]));
55453
55605
  }
55454
- var import_web396, b58Cache, b58, REPLAY_STORE_INDEXED, CLOSE_REPLAY_TREE_TAG, EXTEND_ANCHOR_RING_TAG, WIDEN_ANCHOR_RING_TAG, WIDE_ANCHOR_RING_POOL_BYTES, LINK_SUCCESSOR_TAG, IMPORT_REPLAY_LEAVES_TAG, SETTLE_MOVE_TAG, SWEEP_PREDECESSOR_VAULT_TAG, RELINK_SUCCESSOR_TAG, ROTATE_PAYMENT_SETTLER_TAG, IMPORT_A_LEAF_BYTES, IMPORT_MEMBERSHIP_BYTES, IMPORT_PRESENT_SHIFT, IMPORT_MAX_ENTRIES, MOVE_HEAD_BYTES, MOVE_INSERTED_VALUES, DEFAULT_KEY, FIELD_BYTES2, PRIMARY_PROOF_BYTES, SUBTREE_LEAVES, PAGE_SIZE, FIELD_MODULUS3, BPF_LOADER_UPGRADEABLE_PROGRAM_ID, SYSTEM_PROGRAM, TEST_EXECUTABLES, derivationMemo, memo, reviewedExecutables, isProgramDataIdentityError, ASSUMED_ORIGINAL_EXECUTABLE, AUTHENTICATED_HISTORY_REPORTS, HISTORY_ATTESTATIONS, SNAPSHOT_POOL_STATES, REPORT_POOL_STATES, hasExecutableEvidence, P03_FINALIZED_HISTORY_SOURCE_MODEL, P03_PROGRAMDATA_COVERAGE_SOURCE_MODEL, P03_RUN_RECOVER_UNAVAILABLE_FROM_CHAIN, PROFILES, P03_SETTLEMENT_TAGS, P03_INLINE_SETTLEMENT_TAGS, P03_PAYMENT_REPLAY_INDICES, NO_CONTEXTS, REFRESH_READ_BYTES, E1_TREE_HEADER_BYTES, E1_TREE_MAGIC, E1_CHANGELOG_BYTES, E1_CHANGELOGS_OFFSET, E1_RIGHTMOST_OFFSET, E1_LEAF_COUNT_OFFSET, E1_CANOPY_OFFSET, E1_CANOPY_NODES, P03_POOL_SLICES_METHOD, POOL_SLICES, SLICED_ROOTS_OFFSET, SLICED_LEAVES_OFFSET, SLICES_REFUSED_ENDPOINTS, SLICES_REFUSED_CONNECTIONS, HISTORY_FETCH_CONCURRENCY, HISTORY_BULK_TRANSACTIONS, HISTORY_BULK_ADDRESSES, TRANSIENT_RPC_ATTEMPTS, TRANSIENT_RPC_BASE_DELAY_MS, LAGGING_NODE_STEP_OF_BASE, LAGGING_NODE_MAX_RETRIES, LAGGING_NODE_FAST_RETRIES, LAGGING_NODE_SLOW_STEP_OF_BASE, LAGGING_NODE_RPC_CODES, lastVerifiedE1Tree, e1ReplayCounts;
55606
+ var import_web396, b58Cache, b58, REPLAY_STORE_INDEXED, CLOSE_REPLAY_TREE_TAG, EXTEND_ANCHOR_RING_TAG, WIDEN_ANCHOR_RING_TAG, WIDE_ANCHOR_RING_POOL_BYTES, LINK_SUCCESSOR_TAG, IMPORT_REPLAY_LEAVES_TAG, SETTLE_MOVE_TAG, SWEEP_PREDECESSOR_VAULT_TAG, RELINK_SUCCESSOR_TAG, ROTATE_PAYMENT_SETTLER_TAG, IMPORT_A_LEAF_BYTES, IMPORT_MEMBERSHIP_BYTES, IMPORT_PRESENT_SHIFT, IMPORT_MAX_ENTRIES, MOVE_HEAD_BYTES, MOVE_INSERTED_VALUES, DEFAULT_KEY, FIELD_BYTES2, PRIMARY_PROOF_BYTES, SUBTREE_LEAVES, PAGE_SIZE, FIELD_MODULUS3, BPF_LOADER_UPGRADEABLE_PROGRAM_ID, SYSTEM_PROGRAM, TEST_EXECUTABLES, derivationMemo, memo, reviewedExecutables, isProgramDataIdentityError, ASSUMED_ORIGINAL_EXECUTABLE, AUTHENTICATED_HISTORY_REPORTS, HISTORY_ATTESTATIONS, SNAPSHOT_POOL_STATES, REPORT_POOL_STATES, hasExecutableEvidence, P03_FINALIZED_HISTORY_SOURCE_MODEL, P03_PROGRAMDATA_COVERAGE_SOURCE_MODEL, P03_RUN_RECOVER_UNAVAILABLE_FROM_CHAIN, PROFILES, P03_SETTLEMENT_TAGS, P03_INLINE_SETTLEMENT_TAGS, P03_PAYMENT_REPLAY_INDICES, NO_CONTEXTS, REFRESH_READ_BYTES, E1_TREE_HEADER_BYTES, E1_TREE_MAGIC, E1_CHANGELOG_BYTES, E1_CHANGELOGS_OFFSET, E1_RIGHTMOST_OFFSET, E1_LEAF_COUNT_OFFSET, E1_CANOPY_OFFSET, E1_CANOPY_NODES, P03_POOL_SLICES_METHOD, POOL_SLICES, SLICED_ROOTS_OFFSET, SLICED_LEAVES_OFFSET, SLICES_REFUSED_ENDPOINTS, SLICES_REFUSED_CONNECTIONS, HISTORY_FETCH_CONCURRENCY, HISTORY_BULK_TRANSACTIONS, HISTORY_BULK_ADDRESSES, TRANSIENT_RPC_ATTEMPTS, TRANSIENT_RPC_BASE_DELAY_MS, LAGGING_NODE_STEP_OF_BASE, LAGGING_NODE_MAX_RETRIES, LAGGING_NODE_FAST_RETRIES, LAGGING_NODE_SLOW_STEP_OF_BASE, LAGGING_NODE_RPC_CODES, lastVerifiedE1Tree, e1ReplayCounts, e1TreeCandidate;
55455
55607
  var init_walk = __esm({
55456
55608
  "wallet/src/history/walk.mjs"() {
55457
55609
  "use strict";
@@ -55740,7 +55892,7 @@ var init_walk = __esm({
55740
55892
  LAGGING_NODE_FAST_RETRIES = 5;
55741
55893
  LAGGING_NODE_SLOW_STEP_OF_BASE = 4.6;
55742
55894
  LAGGING_NODE_RPC_CODES = /* @__PURE__ */ new Set([-32004, -32016]);
55743
- e1ReplayCounts = { full: 0, extended: 0 };
55895
+ e1ReplayCounts = { full: 0, extended: 0, candidate: 0 };
55744
55896
  }
55745
55897
  });
55746
55898
 
@@ -56660,6 +56812,31 @@ function startCompactPreFold(pool2, cached) {
56660
56812
  preFolds.set(pool2, preFold);
56661
56813
  return preFold;
56662
56814
  }
56815
+ function startCompactE1Candidate(programId, pool2, cached, preFold) {
56816
+ const records = cached?.served?.records;
56817
+ if (!Array.isArray(records) || records.length === 0) return void 0;
56818
+ let hurry = false;
56819
+ let running;
56820
+ const done = (async () => {
56821
+ await (preFold?.done ?? new Promise((resolve38) => setImmediate(resolve38)));
56822
+ if (initializationReplayStore(cached.initialization) !== REPLAY_STORE_INDEXED2) return void 0;
56823
+ const contexts = records.map((record) => ({
56824
+ kind: record.kind,
56825
+ provenance: { slot: record.slot, transactionIndex: record.transactionIndex, instructionIndex: record.instructionIndex },
56826
+ replayValues: record.replayValues.map((value) => fieldOf(value))
56827
+ }));
56828
+ const imports = (Array.isArray(cached.served.imports) ? cached.served.imports : []).map((entry) => validateImport(entry, void 0));
56829
+ running = startE1TreeCandidate({ key: `${programId}:${pool2}`, settles: compactTreeSettles(contexts, imports) });
56830
+ if (running === void 0) return markPhase("compact-e1-ahead-skipped");
56831
+ markPhase("compact-e1-ahead-start");
56832
+ if (hurry) running.hurry();
56833
+ return markPhase(await running.done ? "compact-e1-ahead-done" : "compact-e1-ahead-dropped");
56834
+ })().catch(() => markPhase("compact-e1-ahead-skipped"));
56835
+ return { done, hurry: () => {
56836
+ hurry = true;
56837
+ running?.hurry();
56838
+ } };
56839
+ }
56663
56840
  function sparseRoots(roots, count2) {
56664
56841
  const array = new Array(count2 + 1);
56665
56842
  array[0] = zeroRoots()[OUTER_DEPTH2];
@@ -57630,6 +57807,7 @@ async function compactP03HistoryReportRun({
57630
57807
  }
57631
57808
  };
57632
57809
  const preFold = cached ? startCompactPreFold(poolKey.toBase58(), cached) : void 0;
57810
+ const e1Ahead = cached ? startCompactE1Candidate(program.toBase58(), poolKey.toBase58(), cached, preFold) : void 0;
57633
57811
  const compact = await readCompactP03History({
57634
57812
  history,
57635
57813
  own: connection,
@@ -57656,6 +57834,10 @@ async function compactP03HistoryReportRun({
57656
57834
  let e1Tree;
57657
57835
  if (snapshot.replayStore === REPLAY_STORE_INDEXED2) {
57658
57836
  try {
57837
+ if (e1Ahead !== void 0) {
57838
+ e1Ahead.hurry();
57839
+ await e1Ahead.done;
57840
+ }
57659
57841
  e1Tree = assertP03E1TreeComplete({
57660
57842
  program,
57661
57843
  pool: poolKey,
@@ -118627,8 +118809,12 @@ ${canonical5}`;
118627
118809
  const linkReads = readOpenLinkHeld(store);
118628
118810
  const finishing = finishSentDeposits(store);
118629
118811
  const finishDeadline = finishing.length ? balanceStartedAt + balanceRefreshWaitMs : void 0;
118812
+ let finishedHere = [];
118630
118813
  if (finishing.length) {
118631
- const finished = Promise.all(finishing).then((outcomes) => outcomes.some((outcome2) => outcome2?.stage === "done" || outcome2?.stage === "partly_shielded") ? refreshShared().then(() => "done") : "passed").catch(() => "failed");
118814
+ const finished = Promise.all(finishing).then((outcomes) => {
118815
+ finishedHere = outcomes.filter((outcome2) => outcome2?.stage === "done" || outcome2?.stage === "partly_shielded");
118816
+ return finishedHere.length ? refreshShared().then(() => "done") : "passed";
118817
+ }).catch(() => "failed");
118632
118818
  const outcome = await Promise.race([
118633
118819
  finished,
118634
118820
  new Promise((resolve38) => {
@@ -118780,6 +118966,22 @@ ${canonical5}`;
118780
118966
  } catch {
118781
118967
  landingAtomic = 0n;
118782
118968
  }
118969
+ if (landingAtomic === 0n && shieldedAtomic === null && !refresh.refreshError && finishedHere.length) {
118970
+ for (const outcome of finishedHere) {
118971
+ const id = outcome.record?.id;
118972
+ const round = outcome.record?.round ?? 1;
118973
+ let amount = payMeAmounts.get(`${id}:${round}`);
118974
+ if (amount === void 0) {
118975
+ try {
118976
+ const deposit = store.readWal(`deposit-${outcome.record?.depositId ?? payMeRoundDepositId(id, round)}`);
118977
+ if (/^[1-9][0-9]*$/.test(String(deposit?.amountAtomic ?? ""))) amount = BigInt(deposit.amountAtomic);
118978
+ } catch {
118979
+ amount = void 0;
118980
+ }
118981
+ }
118982
+ if (typeof amount === "bigint" && amount > 0n) landingAtomic += amount;
118983
+ }
118984
+ }
118783
118985
  const landedNext = landingAtomic > 0n && !refresh.refreshError ? `${usdcText2(landingAtomic)} USDC you added landed on chain and is being counted (landingAtomic, not in balanceAtomic yet): call wallet_balance again in ${POLL_SECONDS3} s; that call waits up to ${waitSeconds} s for it. Tell the user it needs no step from them` : void 0;
118784
118986
  if (landedNext) next = landedNext;
118785
118987
  const stalled = [...resumeRefusals].map(([requestId, error2]) => `"${requestId}" (${error2})`);