shinjuku-shielded 0.3.66 → 0.3.67

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": "402e7c3666bf4dfe147de8229872bdf611540526a15d5fdb690392c81b878b9d",
5
- "bytes": 12181283,
6
- "sourceCommit": "07b54a455cdbafc18b7f79b107b0cf9e5e722be9",
4
+ "sha256": "4d9b6de27c68f9fb53c414d063679fde5a62eb26a2a46f13bebfde9a4d74b042",
5
+ "bytes": 12186827,
6
+ "sourceCommit": "fb9acd3df41de84537c71fc80913c41a37568bf4",
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-22T11:29:33.345Z"
1285
+ "publishedAt": "2026-10-22T12:44:47.481Z"
1286
1286
  }
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "shinjuku-shielded",
3
- "version": "0.3.66",
3
+ "version": "0.3.67",
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": "402e7c36",
7
- "shinjukuSha256": "402e7c3666bf4dfe147de8229872bdf611540526a15d5fdb690392c81b878b9d",
6
+ "shinjukuRelease": "4d9b6de2",
7
+ "shinjukuSha256": "4d9b6de27c68f9fb53c414d063679fde5a62eb26a2a46f13bebfde9a4d74b042",
8
8
  "license": "SEE LICENSE IN LICENSE.txt",
9
9
  "author": "Shinjuku Shielded",
10
10
  "homepage": "https://github.com/ShinjukuStaition/shinjuku-mcp#readme",
@@ -42650,6 +42650,7 @@ function raceOnions(onions, {
42650
42650
  let startSpares = () => {
42651
42651
  };
42652
42652
  let spareTimer;
42653
+ const startedAt = Date.now();
42653
42654
  const winner = new Promise((resolve38) => {
42654
42655
  let open3 = 0;
42655
42656
  let done = false;
@@ -42662,7 +42663,7 @@ function raceOnions(onions, {
42662
42663
  const failed = () => {
42663
42664
  open3 -= 1;
42664
42665
  if (open3 > 0 || done) return;
42665
- if (!sparesStarted && !signal.aborted) return startSpares();
42666
+ if (!sparesStarted && !signal.aborted) return startSpares("failed");
42666
42667
  if (!controller.signal.aborted) onNone?.();
42667
42668
  settle(onions[0]);
42668
42669
  };
@@ -42670,15 +42671,15 @@ function raceOnions(onions, {
42670
42671
  open3 += 1;
42671
42672
  probe(onion).then(settle, failed);
42672
42673
  };
42673
- startSpares = () => {
42674
+ startSpares = (cause) => {
42674
42675
  if (sparesStarted || done || signal.aborted) return;
42675
42676
  sparesStarted = true;
42676
42677
  clearTimeout(spareTimer);
42677
- onSpares?.();
42678
+ onSpares?.({ afterMs: Date.now() - startedAt, cause });
42678
42679
  for (const onion of spares) start(onion);
42679
42680
  };
42680
42681
  if (!sparesStarted) {
42681
- spareTimer = setTimeout(() => startSpares(), spareAfterMs);
42682
+ spareTimer = setTimeout(() => startSpares("silent"), spareAfterMs);
42682
42683
  spareTimer.unref?.();
42683
42684
  }
42684
42685
  for (const onion of onions) start(onion);
@@ -42686,7 +42687,7 @@ function raceOnions(onions, {
42686
42687
  clearTimeout(spareTimer);
42687
42688
  controller.abort();
42688
42689
  });
42689
- return { winner, abort: () => controller.abort(), startSpares: () => startSpares() };
42690
+ return { winner, abort: () => controller.abort(), startSpares: () => startSpares("wait") };
42690
42691
  }
42691
42692
  function facilitatorOrigins(argv2) {
42692
42693
  const origins = /* @__PURE__ */ new Set();
@@ -42755,7 +42756,8 @@ async function routeFacilitatorsOverOnion(argv2, {
42755
42756
  spares,
42756
42757
  waitMs: routeWaitMs,
42757
42758
  label: origin,
42758
- 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)
42759
+ // The line names the time and the spare wait, so a live run counts how often and when the spares join.
42760
+ onSpares: ({ afterMs, cause }) => err(`tor: the ${spares.length} spare onions ${spareHosts} of ${origin} join after ${(afterMs / 1e3).toFixed(1)} s (${SPARE_CAUSE[cause]}; the spare wait is ${spareAfterMs / 1e3} s; Tor may still be fetching the onion addresses)
42759
42761
  `),
42760
42762
  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)
42761
42763
  `)
@@ -42821,9 +42823,9 @@ async function routeFacilitatorsOverOnion(argv2, {
42821
42823
  const spares = group.spares ?? [];
42822
42824
  group.startSpares = race(group, liveOnions(group), {
42823
42825
  ...group.onNone ? { onNone: group.onNone } : {},
42824
- ...spares.length > 0 ? { spares, spareAfterMs, onSpares: () => {
42826
+ ...spares.length > 0 ? { spares, spareAfterMs, onSpares: (info) => {
42825
42827
  group.live = group.onions.length;
42826
- group.onSpares?.();
42828
+ group.onSpares?.(info);
42827
42829
  } } : {}
42828
42830
  }).startSpares;
42829
42831
  }
@@ -42899,7 +42901,7 @@ async function routeFacilitatorsOverOnion(argv2, {
42899
42901
  }
42900
42902
  };
42901
42903
  }
42902
- 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, hostOf, noAnswer, routedOnions, routedOrigins, onionsOfOrigin, routesOverOnion, GLOBAL_DISPATCHER, onionDispatchers;
42904
+ 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, GLOBAL_DISPATCHER, onionDispatchers;
42903
42905
  var init_facilitatorOnion = __esm({
42904
42906
  "wallet/src/net/facilitatorOnion.mjs"() {
42905
42907
  "use strict";
@@ -42925,7 +42927,6 @@ var init_facilitatorOnion = __esm({
42925
42927
  HISTORY_ONIONS = Object.freeze([
42926
42928
  "http://d6xg3phhurxhzqcsgh2mh52yf744labhrnd7mducwynlertfsjzyslqd.onion",
42927
42929
  "http://3yccoinnouxbjx3emvdxwhbu56cq4de7sfwgvcp4xb7hveccnpurcrid.onion",
42928
- "http://zflgixkemk6sa2wnd6gzmmtlxl42si6b57uxwxq3r36g6wwzmmd3nmyd.onion",
42929
42930
  "http://5362sown5vydadla47lmo6rafet2fs6iltisxapo5laf7aqjmmvtvhid.onion"
42930
42931
  ]);
42931
42932
  PINNED_HISTORY_ONIONS = Object.freeze({ [HISTORY_ONIONS[0]]: HISTORY_ONIONS });
@@ -42936,7 +42937,8 @@ var init_facilitatorOnion = __esm({
42936
42937
  WARM_TIMEOUT_MS = 3e4;
42937
42938
  RACE_TIMEOUT_MS = 9e4;
42938
42939
  ROUTE_WAIT_MS = 15e3;
42939
- SPARE_AFTER_MS = ROUTE_WAIT_MS;
42940
+ SPARE_AFTER_MS = 8e3;
42941
+ SPARE_CAUSE = Object.freeze({ silent: "no pinned onion answered", failed: "every pinned probe failed", wait: "a request's route wait ended" });
42940
42942
  routedGroups = [];
42941
42943
  liveOnions = (group) => group.onions.slice(0, group.live ?? group.onions.length);
42942
42944
  hostOf = (onion) => `${new URL(onion).host.slice(0, 8)}...`;
@@ -46729,11 +46731,12 @@ function markPhase(phase, outcome) {
46729
46731
  } catch {
46730
46732
  }
46731
46733
  }
46732
- var scope;
46734
+ var scope, phaseScopeActive;
46733
46735
  var init_phaseTiming = __esm({
46734
46736
  "wallet/src/pay/phaseTiming.mjs"() {
46735
46737
  "use strict";
46736
46738
  scope = new AsyncLocalStorage();
46739
+ phaseScopeActive = () => scope.getStore() !== void 0;
46737
46740
  }
46738
46741
  });
46739
46742
 
@@ -50683,7 +50686,7 @@ function connect2(rpcUrl, commitment = "finalized", { timeoutMs, wrapFetch = (fe
50683
50686
  const connection = countRpcCalls(new import_web395.Connection(rpcUrl, { commitment, fetch: fetch2, disableRetryOnRateLimit: true }));
50684
50687
  let nextId = 0;
50685
50688
  Object.defineProperty(connection, "abortableRpcRequest", {
50686
- value: async (method, params, signal, onResponse) => {
50689
+ value: async (method, params, signal, onResponse, { id, lane, rejectHttpError = false } = {}) => {
50687
50690
  let reported = false;
50688
50691
  const onResponseHead = (response2) => {
50689
50692
  if (reported) return;
@@ -50693,14 +50696,16 @@ function connect2(rpcUrl, commitment = "finalized", { timeoutMs, wrapFetch = (fe
50693
50696
  } catch {
50694
50697
  }
50695
50698
  };
50696
- const response = await fetch2(rpcUrl, {
50699
+ const init = {
50697
50700
  method: "POST",
50698
50701
  signal,
50699
50702
  onResponseHead,
50700
50703
  headers: { "content-type": "application/json" },
50701
- body: JSON.stringify({ jsonrpc: "2.0", id: `abortable-${nextId += 1}`, method, params })
50702
- });
50704
+ body: JSON.stringify({ jsonrpc: "2.0", id: id ?? `abortable-${nextId += 1}`, method, params })
50705
+ };
50706
+ const response = await fetch2(rpcUrl, lane === void 0 ? init : torLaneInit(lane, init));
50703
50707
  onResponseHead(response);
50708
+ if (rejectHttpError && !response.ok) throw new Error(`${response.status} ${response.statusText}: ${await response.text()}`);
50704
50709
  return response.json();
50705
50710
  },
50706
50711
  enumerable: false,
@@ -54250,33 +54255,37 @@ async function programDataCoverage(args) {
54250
54255
  return programDataCoverageFor(extendedArgs);
54251
54256
  }
54252
54257
  }
54253
- async function programDataCoverageFor({
54254
- connection,
54255
- program,
54256
- initialization,
54257
- snapshotSlot,
54258
- firstAvailable,
54259
- deploymentIdentity,
54260
- concurrency,
54261
- prior,
54262
- attest = attestProgramDataCoverage,
54263
- // Called once before a full attestation (compact.mjs: a notice line and a timing mark):
54264
- // { priorRefused, cause } — priorRefused is true when a cached attestation was there but its
54265
- // two reads refused it; cause is a short fixed word for why (reuseRefusalCause).
54266
- onFullAttestation,
54267
- // Called before the two reads are asked once more after a transport failure or a timeout
54268
- // (compact.mjs: a new Tor circuit). Absent: no second try.
54269
- onReuseRetry,
54270
- // The connection for the two reuse reads ONLY (compact.mjs: the split's own RPC, bounded),
54271
- // so one RPC answers both, at or after snapshotSlot, with no history-source floor below it
54272
- // (2026-10-16 c1s: the signature read on the proxy cost a -32016 retry, about 0.2 s).
54273
- // The full attestation and its newest signature keep `connection`. Absent: `connection`.
54274
- reuseConnection = connection,
54275
- // The pool snapshot's `programDataReuse` (readFinalizedPoolSliced, 2026-10-22): the same two facts
54276
- // from the same RPC as the pool account, at its slot. Used instead of the two reads only when it
54277
- // is at `snapshotSlot` and names the cached attestation's address; checked exactly as they are.
54278
- reuseAnswer
54279
- }) {
54258
+ async function programDataCoverageFor(args) {
54259
+ const {
54260
+ connection,
54261
+ program,
54262
+ initialization,
54263
+ snapshotSlot,
54264
+ firstAvailable,
54265
+ deploymentIdentity,
54266
+ concurrency,
54267
+ prior,
54268
+ attest = attestProgramDataCoverage,
54269
+ // Called once before a full attestation (compact.mjs: a notice line and a timing mark):
54270
+ // { priorRefused, cause } — priorRefused is true when a cached attestation was there but its
54271
+ // two reads refused it; cause is a short fixed word for why (reuseRefusalCause).
54272
+ onFullAttestation,
54273
+ // Called before the two reads are asked once more after a transport failure or a timeout
54274
+ // (compact.mjs: a new Tor circuit). Absent: no second try.
54275
+ onReuseRetry,
54276
+ // The connection for the two reuse reads ONLY (compact.mjs: the split's own RPC, bounded),
54277
+ // so one RPC answers both, at or after snapshotSlot, with no history-source floor below it
54278
+ // (2026-10-16 c1s: the signature read on the proxy cost a -32016 retry, about 0.2 s).
54279
+ // The full attestation and its newest signature keep `connection`. Absent: `connection`.
54280
+ reuseConnection = connection,
54281
+ // The pool snapshot's `programDataReuse` (readFinalizedPoolSliced, 2026-10-22): the same two facts
54282
+ // from the same RPC as the pool account, at its slot. Used instead of the two reads only when it
54283
+ // is at `snapshotSlot` and names the cached attestation's address; checked exactly as they are.
54284
+ reuseAnswer,
54285
+ // Set on the one call after a join (below): it does not join again.
54286
+ joined = false,
54287
+ joinWaitMs = ATTEST_JOIN_WAIT_MS
54288
+ } = args;
54280
54289
  if (deploymentIdentity === void 0) return { coverage: void 0, attestation: void 0, reused: false };
54281
54290
  let priorRefused = false;
54282
54291
  let cause;
@@ -54285,8 +54294,8 @@ async function programDataCoverageFor({
54285
54294
  const address5 = new import_web396.PublicKey(prior.coverage.programDataAddress);
54286
54295
  const deployedAtSlot = BigInt(prior.coverage.deployedAtSlot);
54287
54296
  const reuse = (signature2) => {
54288
- const coverage2 = Object.freeze({ ...prior.coverage, throughFinalizedSlot: BigInt(snapshotSlot) });
54289
- return { coverage: coverage2, attestation: { key, newestSignature: signature2, coverage: coverage2 }, reused: true };
54297
+ const coverage = Object.freeze({ ...prior.coverage, throughFinalizedSlot: BigInt(snapshotSlot) });
54298
+ return { coverage, attestation: { key, newestSignature: signature2, coverage }, reused: true };
54290
54299
  };
54291
54300
  const pooled = reuseAnswer !== void 0 && reuseAnswer.slot === snapshotSlot && reuseAnswer.address === address5.toBase58() ? reuseAnswer : void 0;
54292
54301
  if (pooled !== void 0) {
@@ -54303,7 +54312,7 @@ async function programDataCoverageFor({
54303
54312
  } else {
54304
54313
  for (let attempt = 1; ; attempt += 1) {
54305
54314
  try {
54306
- const [, newest2] = await Promise.all([
54315
+ const [, newest] = await Promise.all([
54307
54316
  readProgramDataHeader({
54308
54317
  connection: reuseConnection,
54309
54318
  address: address5,
@@ -54312,7 +54321,7 @@ async function programDataCoverageFor({
54312
54321
  }),
54313
54322
  newestSignature(reuseConnection, address5, snapshotSlot)
54314
54323
  ]);
54315
- if (newest2.signature === prior.newestSignature) return reuse(newest2.signature);
54324
+ if (newest.signature === prior.newestSignature) return reuse(newest.signature);
54316
54325
  cause = "programdata_newest_signature_changed";
54317
54326
  break;
54318
54327
  } catch (error) {
@@ -54324,23 +54333,52 @@ async function programDataCoverageFor({
54324
54333
  }
54325
54334
  priorRefused = true;
54326
54335
  }
54336
+ const running = key === void 0 || joined ? void 0 : fullAttestations.get(key);
54337
+ let replace = false;
54338
+ if (running !== void 0) {
54339
+ markPhase("attest-full-joined");
54340
+ let timer;
54341
+ const leader = await Promise.race([
54342
+ running.catch(() => void 0),
54343
+ new Promise((resolve38) => {
54344
+ timer = setTimeout(() => resolve38(JOIN_TIMED_OUT), joinWaitMs);
54345
+ })
54346
+ ]);
54347
+ clearTimeout(timer);
54348
+ if (leader === JOIN_TIMED_OUT) {
54349
+ markPhase("attest-full-join-timeout");
54350
+ replace = true;
54351
+ } else if (leader?.attestation !== void 0) {
54352
+ return programDataCoverageFor({ ...args, prior: leader.attestation, joined: true });
54353
+ }
54354
+ }
54327
54355
  onFullAttestation?.({ priorRefused, ...cause ? { cause } : {} });
54328
- const available = typeof firstAvailable === "function" ? await firstAvailable() : firstAvailable;
54329
- const coverage = await attest({
54330
- connection,
54331
- program,
54332
- initialization,
54333
- snapshotSlot,
54334
- firstAvailable: available,
54335
- deploymentIdentity,
54336
- concurrency
54337
- });
54338
- const newest = await newestSignature(connection, new import_web396.PublicKey(coverage.programDataAddress), snapshotSlot);
54339
- return {
54340
- coverage,
54341
- attestation: key !== void 0 && newest.slot <= snapshotSlot ? { key, newestSignature: newest.signature, coverage } : void 0,
54342
- reused: false
54343
- };
54356
+ const full = (async () => {
54357
+ const available = typeof firstAvailable === "function" ? await firstAvailable() : firstAvailable;
54358
+ const coverage = await attest({
54359
+ connection,
54360
+ program,
54361
+ initialization,
54362
+ snapshotSlot,
54363
+ firstAvailable: available,
54364
+ deploymentIdentity,
54365
+ concurrency
54366
+ });
54367
+ const newest = await newestSignature(connection, new import_web396.PublicKey(coverage.programDataAddress), snapshotSlot);
54368
+ return {
54369
+ coverage,
54370
+ attestation: key !== void 0 && newest.slot <= snapshotSlot ? { key, newestSignature: newest.signature, coverage } : void 0,
54371
+ reused: false
54372
+ };
54373
+ })();
54374
+ if (key !== void 0 && (replace || !fullAttestations.has(key))) {
54375
+ fullAttestations.set(key, full);
54376
+ const forget = () => {
54377
+ if (fullAttestations.get(key) === full) fullAttestations.delete(key);
54378
+ };
54379
+ full.then(forget, forget);
54380
+ }
54381
+ return full;
54344
54382
  }
54345
54383
  async function attestProgramDataCoverage({
54346
54384
  connection,
@@ -55767,7 +55805,7 @@ function base58Decode(value) {
55767
55805
  while (zeros < value.length && value[zeros] === "1") zeros += 1;
55768
55806
  return Uint8Array.from(Buffer.concat([Buffer.alloc(zeros), body]));
55769
55807
  }
55770
- 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, PROGRAMDATA_HEADER_BYTES, POOL_SLICES_WITH_PROGRAMDATA, SLICED_ROOTS_OFFSET, SLICED_LEAVES_OFFSET, SLICES_REFUSED_ENDPOINTS, SLICES_REFUSED_CONNECTIONS, REUSE_REFUSED_ENDPOINTS, REUSE_REFUSED_CONNECTIONS, PROGRAMDATA_ADDRESSES, 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;
55808
+ 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, PROGRAMDATA_HEADER_BYTES, POOL_SLICES_WITH_PROGRAMDATA, SLICED_ROOTS_OFFSET, SLICED_LEAVES_OFFSET, SLICES_REFUSED_ENDPOINTS, SLICES_REFUSED_CONNECTIONS, REUSE_REFUSED_ENDPOINTS, REUSE_REFUSED_CONNECTIONS, PROGRAMDATA_ADDRESSES, fullAttestations, ATTEST_JOIN_WAIT_MS, JOIN_TIMED_OUT, 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;
55771
55809
  var init_walk = __esm({
55772
55810
  "wallet/src/history/walk.mjs"() {
55773
55811
  "use strict";
@@ -56051,6 +56089,9 @@ var init_walk = __esm({
56051
56089
  REUSE_REFUSED_ENDPOINTS = /* @__PURE__ */ new Set();
56052
56090
  REUSE_REFUSED_CONNECTIONS = /* @__PURE__ */ new WeakSet();
56053
56091
  PROGRAMDATA_ADDRESSES = /* @__PURE__ */ new Map();
56092
+ fullAttestations = /* @__PURE__ */ new Map();
56093
+ ATTEST_JOIN_WAIT_MS = 45e3;
56094
+ JOIN_TIMED_OUT = /* @__PURE__ */ Symbol("join-timed-out");
56054
56095
  HISTORY_FETCH_CONCURRENCY = 4;
56055
56096
  HISTORY_BULK_TRANSACTIONS = 256;
56056
56097
  HISTORY_BULK_ADDRESSES = 256;
@@ -57323,13 +57364,17 @@ function failureCause(error) {
57323
57364
  }
57324
57365
  async function boundedOwnRead(operation) {
57325
57366
  const circuit = torCircuit();
57326
- const pending = operation();
57367
+ const stalled = new AbortController();
57368
+ const pending = operation(stalled.signal);
57327
57369
  pending.catch(() => {
57328
57370
  });
57329
57371
  let timer;
57330
57372
  try {
57331
57373
  return await Promise.race([pending, new Promise((_, reject) => {
57332
- timer = setTimeout(() => reject(new Error("ETIMEDOUT: own RPC read stalled")), OWN_READ_TIMEOUT_MS);
57374
+ timer = setTimeout(() => {
57375
+ stalled.abort();
57376
+ reject(new Error("ETIMEDOUT: own RPC read stalled"));
57377
+ }, OWN_READ_TIMEOUT_MS);
57333
57378
  })]);
57334
57379
  } catch (error) {
57335
57380
  if (error?.message === "ETIMEDOUT: own RPC read stalled") {
@@ -57460,14 +57505,81 @@ function ed25519Verifies2(message, signature2, publicKey3) {
57460
57505
  async function ownTransaction(own, signature2) {
57461
57506
  let response;
57462
57507
  try {
57463
- response = await retryRpc2(() => boundedOwnRead(() => own._rpcRequest("getTransaction", [signature2, {
57464
- commitment: "finalized",
57465
- maxSupportedTransactionVersion: 1,
57466
- encoding: "base64"
57467
- }])), { attempts: 3 });
57508
+ response = await retryRpc2(() => boundedOwnRead((stalled) => hedgedOwnTransactionRead(own, signature2, { stalled })), { attempts: 3 });
57468
57509
  } catch (error) {
57469
57510
  throw Object.assign(refuse3("p03_compact_history_spot_check_unavailable"), { cause: error });
57470
57511
  }
57512
+ return checkedOwnTransaction(response, signature2);
57513
+ }
57514
+ async function hedgedOwnTransactionRead(own, signature2, { stalled, hedge = inTorRun, afterMs = SPOT_HEDGE_AFTER_MS } = {}) {
57515
+ const params = [signature2, { commitment: "finalized", maxSupportedTransactionVersion: 1, encoding: "base64" }];
57516
+ if (typeof own.abortableRpcRequest !== "function") return own._rpcRequest("getTransaction", params);
57517
+ const id = `spot-${spotReadId += 1}`;
57518
+ const copies = [];
57519
+ const send3 = (lane) => {
57520
+ const controller = new AbortController();
57521
+ const signal = stalled === void 0 ? controller.signal : AbortSignal.any([stalled, controller.signal]);
57522
+ const copy = { controller, lane, outcome: void 0 };
57523
+ copy.read = own.abortableRpcRequest(
57524
+ "getTransaction",
57525
+ params,
57526
+ signal,
57527
+ void 0,
57528
+ { id, rejectHttpError: true, ...lane === void 0 ? {} : { lane } }
57529
+ );
57530
+ copies.push(copy);
57531
+ return copy;
57532
+ };
57533
+ const hedging = hedge();
57534
+ return new Promise((resolve38, reject) => {
57535
+ let timer;
57536
+ let done = false;
57537
+ const finish = (settle) => {
57538
+ done = true;
57539
+ clearTimeout(timer);
57540
+ for (const copy of copies) if (copy.outcome === void 0) copy.controller.abort();
57541
+ settle();
57542
+ };
57543
+ const settled = () => {
57544
+ if (done || copies.some((copy) => copy.outcome === void 0)) return;
57545
+ const answered = copies.find((copy) => copy.outcome.response !== void 0);
57546
+ finish(() => answered !== void 0 ? resolve38(answered.outcome.response) : reject(copies[0].outcome.error));
57547
+ };
57548
+ const follow = (copy, which) => copy.read.then((response) => {
57549
+ let passes = false;
57550
+ try {
57551
+ checkedOwnTransaction(response, signature2);
57552
+ passes = true;
57553
+ } catch {
57554
+ passes = false;
57555
+ }
57556
+ copy.outcome = { response, passes };
57557
+ if (passes && !done) {
57558
+ if (copies.length > 1) markPhase(`spot-hedge-won-${which}`);
57559
+ finish(() => resolve38(response));
57560
+ return;
57561
+ }
57562
+ if (!done && hedging && copies.length === 1) {
57563
+ sendHedge();
57564
+ return;
57565
+ }
57566
+ settled();
57567
+ }, (error) => {
57568
+ copy.outcome = { error };
57569
+ settled();
57570
+ });
57571
+ const sendHedge = () => {
57572
+ clearTimeout(timer);
57573
+ timer = void 0;
57574
+ if (done || copies.length > 1) return;
57575
+ markPhase("spot-hedge-sent");
57576
+ follow(send3(SPOT_HEDGE_LANE), "hedge");
57577
+ };
57578
+ follow(send3(void 0), "first");
57579
+ timer = hedging ? setTimeout(sendHedge, afterMs) : void 0;
57580
+ });
57581
+ }
57582
+ function checkedOwnTransaction(response, signature2) {
57471
57583
  const result = response?.result;
57472
57584
  if (!result || typeof result !== "object" || !Number.isSafeInteger(result.slot) || !Array.isArray(result.transaction) || typeof result.transaction[0] !== "string" || result.transaction[1] !== "base64" || !result.meta) {
57473
57585
  throw refuse3("p03_compact_history_spot_check_unavailable");
@@ -58114,7 +58226,7 @@ async function tryCompactP03HistoryReport(options) {
58114
58226
  return { ok: false, reason, ...detail ? { detail } : {}, error };
58115
58227
  }
58116
58228
  }
58117
- 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, compactReportsRunning, compactHistoryReadsRunning;
58229
+ 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, compactReportsRunning, compactHistoryReadsRunning;
58118
58230
  var init_compact = __esm({
58119
58231
  "wallet/src/history/compact.mjs"() {
58120
58232
  "use strict";
@@ -58247,6 +58359,9 @@ var init_compact = __esm({
58247
58359
  pageZeroInFlight = /* @__PURE__ */ new Map();
58248
58360
  OWN_READ_TIMEOUT_MS = HISTORY_RPC_REQUEST_TIMEOUT_MS;
58249
58361
  BOUNDED_OWN_METHODS = /* @__PURE__ */ new Set(["getAccountInfo", "getAccountInfoAndContext", "getMultipleAccountsInfo", "getMultipleAccountsInfoAndContext"]);
58362
+ SPOT_HEDGE_AFTER_MS = 4e3;
58363
+ SPOT_HEDGE_LANE = "spot-hedge";
58364
+ spotReadId = 0;
58250
58365
  compactReportsRunning = 0;
58251
58366
  compactHistoryReadsRunning = () => compactReportsRunning;
58252
58367
  }
@@ -117115,13 +117230,26 @@ async function runUnshield({
117115
117230
  const owner = new import_web3133.PublicKey(recipientOwner);
117116
117231
  const mint = new import_web3133.PublicKey(store.state.asset);
117117
117232
  const recipient = getAssociatedTokenAddressSync(mint, owner, true, TOKEN_PROGRAM_ID);
117118
- const walk = (deploymentIdentity) => () => loadWalletP03History({
117233
+ let timing;
117234
+ try {
117235
+ timing = typeof session.timing === "function" ? session.timing() : void 0;
117236
+ } catch {
117237
+ timing = void 0;
117238
+ }
117239
+ const mark = (phase) => {
117240
+ try {
117241
+ timing?.(phase);
117242
+ } catch {
117243
+ }
117244
+ };
117245
+ const scoped = (prefix, fn) => phaseScopeActive() || timing === void 0 ? fn() : withPhaseScope(mark, prefix, fn);
117246
+ const walk = (deploymentIdentity) => () => scoped("unshield-walk", () => loadWalletP03History({
117119
117247
  store,
117120
117248
  connection: connectSplit(session.connection, session.historyUrl),
117121
117249
  programId: session.programId,
117122
117250
  pool: store.state.pool,
117123
117251
  deploymentIdentity
117124
- });
117252
+ }));
117125
117253
  const name = `self-pay-${unshieldId}`;
117126
117254
  let record = store.readWal(name);
117127
117255
  if (record && record.mode === void 0 && !selfPayMayHaveSigned(store, unshieldId)) {
@@ -117140,7 +117268,22 @@ async function runUnshield({
117140
117268
  }
117141
117269
  }
117142
117270
  if (record?.mode === DIRECT_EXIT_MODE) {
117143
- return runDirectExit({ session, store, unshieldId, amountAtomic, record, owner, mint, recipient, exitProofTools, facilitatorOrigin: facilitatorOrigin2, onStage, walk });
117271
+ return runDirectExit({
117272
+ session,
117273
+ store,
117274
+ unshieldId,
117275
+ amountAtomic,
117276
+ record,
117277
+ owner,
117278
+ mint,
117279
+ recipient,
117280
+ exitProofTools,
117281
+ facilitatorOrigin: facilitatorOrigin2,
117282
+ onStage,
117283
+ walk,
117284
+ mark,
117285
+ scoped
117286
+ });
117144
117287
  }
117145
117288
  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");
117146
117289
  if (!selfPayMayHaveSigned(store, unshieldId)) {
@@ -117148,6 +117291,7 @@ async function runUnshield({
117148
117291
  }
117149
117292
  const payerTools = session.proofTools;
117150
117293
  onStage("self-pay");
117294
+ mark("unshield-self-pay");
117151
117295
  const paid = await selfPayStep({
117152
117296
  store,
117153
117297
  connection: session.connection,
@@ -117165,8 +117309,10 @@ async function runUnshield({
117165
117309
  });
117166
117310
  const payment = store.readWal(`${RESOURCE_PAYMENT_WAL_PREFIX2}${sha256Hex2(Buffer.from(selfPayRequestId(unshieldId), "utf8"))}`);
117167
117311
  if (!payment?.memoDigest || !paid.noteCommitment) throw new Error("mcp_unshield_failed: the self-payment record is incomplete; call wallet_unshield again with the same request_id");
117312
+ mark("unshield-paid");
117168
117313
  onStage("exit");
117169
- const exit = await exitWhenAnchored(() => runRecoveredP03NoteExit({
117314
+ mark("unshield-exit");
117315
+ const exit = await scoped("unshield-exit", () => exitWhenAnchored(() => runRecoveredP03NoteExit({
117170
117316
  store,
117171
117317
  connection: session.connection,
117172
117318
  programId: session.programId,
@@ -117180,12 +117326,29 @@ async function runUnshield({
117180
117326
  relaySubmit: facilitatorExitRelay(facilitatorOrigin2),
117181
117327
  requestAnchor: facilitatorAnchor(facilitatorOrigin2),
117182
117328
  deps: { walkHistory: walk(exitProofTools.deploymentIdentity) }
117183
- }), { ring: { connection: session.connection, pool: store.state.pool } });
117329
+ }), { ring: { connection: session.connection, pool: store.state.pool } }));
117330
+ mark("unshield-exited");
117184
117331
  const exited = store.readWal(`self-pay-${unshieldId}`);
117185
117332
  store.writeWal(`self-pay-${unshieldId}`, { ...exited, state: "exited", exitTransaction: exit.signature, exitedAtMs: exited?.exitedAtMs ?? Date.now() });
117186
117333
  return { selfPayTransaction: paid.transaction ?? null, exitTransaction: exit.signature ?? null };
117187
117334
  }
117188
- async function runDirectExit({ session, store, unshieldId, amountAtomic, record, owner, mint, recipient, exitProofTools, facilitatorOrigin: facilitatorOrigin2, onStage, walk }) {
117335
+ async function runDirectExit({
117336
+ session,
117337
+ store,
117338
+ unshieldId,
117339
+ amountAtomic,
117340
+ record,
117341
+ owner,
117342
+ mint,
117343
+ recipient,
117344
+ exitProofTools,
117345
+ facilitatorOrigin: facilitatorOrigin2,
117346
+ onStage,
117347
+ walk,
117348
+ mark = () => {
117349
+ },
117350
+ scoped = (_prefix, fn) => fn()
117351
+ }) {
117189
117352
  const name = `self-pay-${unshieldId}`;
117190
117353
  if (record.amountAtomic !== String(amountAtomic) || record.exitAmountAtomic !== String(amountAtomic)) {
117191
117354
  throw new Error("mcp_request_id_reused: this unshield's direct exit is bound to another amount; nothing new was signed");
@@ -117198,6 +117361,7 @@ async function runDirectExit({ session, store, unshieldId, amountAtomic, record,
117198
117361
  }
117199
117362
  if (!selfPayMayHaveSigned(store, unshieldId)) await checkUnshieldRecipient({ connection: session.connection, mint, owner });
117200
117363
  onStage("exit");
117364
+ mark("unshield-exit");
117201
117365
  const proveExit = async (request) => {
117202
117366
  const proved = await proveRecoveredP03NoteExit({ request, tools: exitProofTools });
117203
117367
  const now = store.readWal(name);
@@ -117207,7 +117371,7 @@ async function runDirectExit({ session, store, unshieldId, amountAtomic, record,
117207
117371
  const exitAmountAtomic = record.exitAmountAtomic === record.noteValueAtomic ? void 0 : record.exitAmountAtomic;
117208
117372
  let exit;
117209
117373
  try {
117210
- exit = await exitWhenAnchored(() => runRecoveredP03NoteExit({
117374
+ exit = await scoped("unshield-exit", () => exitWhenAnchored(() => runRecoveredP03NoteExit({
117211
117375
  store,
117212
117376
  connection: session.connection,
117213
117377
  programId: session.programId,
@@ -117222,13 +117386,14 @@ async function runDirectExit({ session, store, unshieldId, amountAtomic, record,
117222
117386
  relaySubmit: facilitatorExitRelay(facilitatorOrigin2),
117223
117387
  requestAnchor: facilitatorAnchor(facilitatorOrigin2),
117224
117388
  deps: { walkHistory: walk(exitProofTools.deploymentIdentity), proveExit }
117225
- }), { ring: { connection: session.connection, pool: store.state.pool } });
117389
+ }), { ring: { connection: session.connection, pool: store.state.pool } }));
117226
117390
  } catch (error) {
117227
117391
  if (/requested recovered note is not uniquely spendable/.test(String(error?.message)) && store.readWal(name)?.state === "started" && !store.readWal(directExitWalName(record)) && !selfPayMayHaveSigned(store, unshieldId)) {
117228
117392
  throw new Error("mcp_unshield_received_payment_gone: the received payment this unshield chose is no longer spendable (another spend took it, or the wallet's last chain read was old); nothing was signed, and this request_id cannot pass");
117229
117393
  }
117230
117394
  throw error;
117231
117395
  }
117396
+ mark("unshield-exited");
117232
117397
  const exited = store.readWal(name);
117233
117398
  store.writeWal(name, { ...exited, state: "exited", exitTransaction: exit.signature, exitedAtMs: exited?.exitedAtMs ?? Date.now() });
117234
117399
  return { selfPayTransaction: null, exitTransaction: exit.signature ?? null };