shinjuku-shielded 0.3.69 → 0.3.71

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": "c6cbe0a61037f0a435f7ce448d6ff6fc6a4a97a9b7336fea33c9e7a1e56c11e7",
5
- "bytes": 12194855,
6
- "sourceCommit": "6325678a822487e65a0bccf3f398ba32fab563e8",
4
+ "sha256": "61674c4e8c6309ae6c93338211bf57a674837f572e498215300031a65b9aa743",
5
+ "bytes": 12200396,
6
+ "sourceCommit": "ec62139d8d55db9f55e17c488d052b6c8248acda",
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-22T14:42:59.608Z"
1285
+ "publishedAt": "2026-10-22T16:40:39.055Z"
1286
1286
  }
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "shinjuku-shielded",
3
- "version": "0.3.69",
3
+ "version": "0.3.71",
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": "c6cbe0a6",
7
- "shinjukuSha256": "c6cbe0a61037f0a435f7ce448d6ff6fc6a4a97a9b7336fea33c9e7a1e56c11e7",
6
+ "shinjukuRelease": "61674c4e",
7
+ "shinjukuSha256": "61674c4e8c6309ae6c93338211bf57a674837f572e498215300031a65b9aa743",
8
8
  "license": "SEE LICENSE IN LICENSE.txt",
9
9
  "author": "Shinjuku Shielded",
10
10
  "homepage": "https://github.com/ShinjukuStaition/shinjuku-mcp#readme",
@@ -51938,13 +51938,7 @@ function createCompactHistoryCacheStore({ path, hmacKey, now }) {
51938
51938
  accounts: [...state.initialization.accounts],
51939
51939
  data: Buffer.from(state.initialization.data).toString("hex")
51940
51940
  },
51941
- ...state.attestation ? {
51942
- attestation: {
51943
- key: state.attestation.key,
51944
- newestSignature: state.attestation.newestSignature,
51945
- coverage: encodeTagged(state.attestation.coverage)
51946
- }
51947
- } : {},
51941
+ ...state.attestation ? { attestation: serializeAttestation(state.attestation) } : {},
51948
51942
  // 2026-10-16: the append root after each served record (hex, count 1..n) and the empty
51949
51943
  // tree's root, a fold hint for a new process (compact.mjs hintCompactFold). Optional: an
51950
51944
  // older build reads the file and drops it; a file without it folds as before.
@@ -51986,7 +51980,7 @@ function createCompactHistoryCacheStore({ path, hmacKey, now }) {
51986
51980
  }
51987
51981
  });
51988
51982
  }
51989
- var P03_HISTORY_CACHE_SCHEMA, positionOrNull, encodeTagged, decodeTagged, deserializeAttestation, serializeState, deserializeState, P03_COMPACT_HISTORY_CACHE_SCHEMA;
51983
+ var P03_HISTORY_CACHE_SCHEMA, positionOrNull, encodeTagged, decodeTagged, deserializeAttestation, serializeAttestation, serializeState, deserializeState, P03_COMPACT_HISTORY_CACHE_SCHEMA;
51990
51984
  var init_cacheStore = __esm({
51991
51985
  "wallet/src/history/cacheStore.mjs"() {
51992
51986
  "use strict";
@@ -52019,8 +52013,22 @@ var init_cacheStore = __esm({
52019
52013
  if (coverage.complete !== true || typeof coverage.programDataAddress !== "string" || typeof coverage.programDataSha256 !== "string" || typeof coverage.deployedAtSlot !== "bigint" || typeof coverage.throughFinalizedSlot !== "bigint") {
52020
52014
  throw new Error("p03_history_cache_attestation_invalid");
52021
52015
  }
52022
- return { key: value.key, newestSignature: value.newestSignature, coverage };
52016
+ if (value.newestSignatureSlot !== void 0 && (!Number.isSafeInteger(value.newestSignatureSlot) || value.newestSignatureSlot < 0 || BigInt(value.newestSignatureSlot) > coverage.throughFinalizedSlot)) {
52017
+ throw new Error("p03_history_cache_attestation_invalid");
52018
+ }
52019
+ return {
52020
+ key: value.key,
52021
+ newestSignature: value.newestSignature,
52022
+ ...value.newestSignatureSlot === void 0 ? {} : { newestSignatureSlot: value.newestSignatureSlot },
52023
+ coverage
52024
+ };
52023
52025
  };
52026
+ serializeAttestation = (attestation) => ({
52027
+ key: attestation.key,
52028
+ newestSignature: attestation.newestSignature,
52029
+ ...Number.isSafeInteger(attestation.newestSignatureSlot) ? { newestSignatureSlot: attestation.newestSignatureSlot } : {},
52030
+ coverage: encodeTagged(attestation.coverage)
52031
+ });
52024
52032
  serializeState = (state) => ({
52025
52033
  schema: P03_HISTORY_CACHE_SCHEMA,
52026
52034
  programId: state.programId,
@@ -52028,13 +52036,7 @@ var init_cacheStore = __esm({
52028
52036
  cursor: { ...state.cursor },
52029
52037
  snapshot: { ...state.snapshot },
52030
52038
  transactions: state.transactions.map(serializeTransactionEntry),
52031
- ...state.attestation ? {
52032
- attestation: {
52033
- key: state.attestation.key,
52034
- newestSignature: state.attestation.newestSignature,
52035
- coverage: encodeTagged(state.attestation.coverage)
52036
- }
52037
- } : {}
52039
+ ...state.attestation ? { attestation: serializeAttestation(state.attestation) } : {}
52038
52040
  });
52039
52041
  deserializeState = (value) => {
52040
52042
  if (!value || value.schema !== P03_HISTORY_CACHE_SCHEMA || typeof value.programId !== "string" || typeof value.pool !== "string" || !value.cursor || typeof value.cursor.lastPoolSignature !== "string" || !Number.isSafeInteger(value.cursor.lastSlot) || !value.snapshot || !Number.isSafeInteger(value.snapshot.slot) || typeof value.snapshot.terminal !== "boolean" || typeof value.snapshot.currentIndex !== "string" || typeof value.snapshot.currentRoot !== "string" || !Array.isArray(value.transactions)) {
@@ -53662,6 +53664,11 @@ function finalizedPoolStateOf(report, { programId, pool: pool2 }) {
53662
53664
  if (entry === void 0 || entry.programId !== String(programId) || entry.pool !== String(pool2)) return void 0;
53663
53665
  return entry.state;
53664
53666
  }
53667
+ function poolReadAtOf(report) {
53668
+ if (!report || !AUTHENTICATED_HISTORY_REPORTS.has(report)) return void 0;
53669
+ const readAt = REPORT_POOL_STATES.get(report)?.readAt;
53670
+ return Number.isFinite(readAt) ? readAt : void 0;
53671
+ }
53665
53672
  function p03SettlementConsumesBuffer(tag2) {
53666
53673
  return P03_SETTLEMENT_TAGS.includes(tag2) && !P03_INLINE_SETTLEMENT_TAGS.includes(tag2);
53667
53674
  }
@@ -53843,13 +53850,34 @@ async function refreshFinalizedP03HistorySnapshot({
53843
53850
  history,
53844
53851
  paymentSettler
53845
53852
  }) {
53853
+ const { authenticated, program, poolKey } = refreshBinding(history, programId, pool2);
53854
+ const snapshot = await readFinalizedPoolForRefresh(connection, program, poolKey);
53855
+ return refreshedFromSnapshot({ connection, program, poolKey, authenticated, snapshot, paymentSettler });
53856
+ }
53857
+ async function refreshFinalizedP03HistoryFromSliced({ connection, programId, pool: pool2, history, snapshot }) {
53858
+ const { authenticated, program, poolKey } = refreshBinding(history, programId, pool2);
53859
+ if (snapshot === null || typeof snapshot !== "object" || snapshot.programDataReuse === void 0) return void 0;
53860
+ let view2 = snapshot;
53861
+ if (snapshot.replayStore === REPLAY_STORE_INDEXED) {
53862
+ const slices = snapshot.e1TreeSlices;
53863
+ if (!slices || slices.slot !== snapshot.slot || !(slices.header instanceof Uint8Array)) return void 0;
53864
+ view2 = withPoolStateOf(snapshot, Object.freeze({
53865
+ ...snapshot,
53866
+ e1TreeHeader: Object.freeze({ address: slices.address, ownerProgramId: slices.ownerProgramId, data: Buffer.from(slices.header) })
53867
+ }));
53868
+ }
53869
+ return refreshedFromSnapshot({ connection, program, poolKey, authenticated, snapshot: view2, reuseAnswer: snapshot.programDataReuse });
53870
+ }
53871
+ function refreshBinding(history, programId, pool2) {
53846
53872
  const authenticated = assertAuthenticatedFinalizedP03History(history);
53847
53873
  const program = canonicalKey(programId, "program_id");
53848
53874
  const poolKey = canonicalKey(pool2, "pool");
53849
53875
  if (authenticated.programId !== b58(program) || authenticated.pool !== poolKey.toBase58()) {
53850
53876
  throw new Error("p03_history_refresh_binding_invalid");
53851
53877
  }
53852
- const snapshot = await readFinalizedPoolForRefresh(connection, program, poolKey);
53878
+ return { authenticated, program, poolKey };
53879
+ }
53880
+ async function refreshedFromSnapshot({ connection, program, poolKey, authenticated, snapshot, paymentSettler, reuseAnswer }) {
53853
53881
  if (snapshot.terminal !== authenticated.finalizedPoolSnapshot.terminal || snapshot.currentIndex !== authenticated.finalizedPoolSnapshot.currentIndex || snapshot.currentRoot !== authenticated.finalizedPoolSnapshot.currentRoot || !sameP03PoolPolicy(snapshot, authenticated.finalizedPoolSnapshot.policy) || !sameE1TreeHeader(snapshot, authenticated.finalizedPoolSnapshot.e1Tree, program, poolKey) || paymentSettler !== void 0 && snapshot.paymentSettler?.toBase58() !== paymentSettler) {
53854
53882
  throw Object.assign(
53855
53883
  new Error("p03_history_refresh_transition_detected"),
@@ -53869,7 +53897,8 @@ async function refreshFinalizedP03HistorySnapshot({
53869
53897
  programDataSha256: priorCoverage.programDataSha256,
53870
53898
  ...priorCoverage.programHistory ? { programHistory: priorCoverage.programHistory } : {}
53871
53899
  },
53872
- prior: HISTORY_ATTESTATIONS.get(authenticated)
53900
+ prior: HISTORY_ATTESTATIONS.get(authenticated),
53901
+ ...reuseAnswer !== void 0 ? { reuseAnswer } : {}
53873
53902
  });
53874
53903
  const deploymentCoverage = refreshedCoverage.coverage;
53875
53904
  if (!hasExecutableEvidence(deploymentCoverage)) throw new Error("p03_history_executable_evidence_required");
@@ -54034,7 +54063,8 @@ function slicedSnapshot(result, program, pool2, tree, programData) {
54034
54063
  owner: value.owner,
54035
54064
  executable: value.executable,
54036
54065
  data,
54037
- newestSignature: newest.signature
54066
+ newestSignature: newest.signature,
54067
+ newestSignatureSlot: newest.slot
54038
54068
  })
54039
54069
  }));
54040
54070
  }
@@ -54162,7 +54192,8 @@ function parseFinalizedPool(response, program, pool2) {
54162
54192
  SNAPSHOT_POOL_STATES.set(snapshot, Object.freeze({
54163
54193
  programId: b58(program),
54164
54194
  pool: pool2.toBase58(),
54165
- state: Object.freeze({ ...state, owner })
54195
+ state: Object.freeze({ ...state, owner }),
54196
+ readAt: Date.now()
54166
54197
  }));
54167
54198
  }
54168
54199
  return snapshot;
@@ -54298,12 +54329,21 @@ async function programDataCoverageFor(args) {
54298
54329
  let priorRefused = false;
54299
54330
  let cause;
54300
54331
  const key = coverageKey({ program, initialization, deploymentIdentity });
54332
+ if (key !== void 0 && prior?.key === key && typeof prior.newestSignature === "string" && Number.isSafeInteger(prior.newestSignatureSlot) && typeof prior.coverage?.throughFinalizedSlot === "bigint" && BigInt(prior.newestSignatureSlot) <= BigInt(snapshotSlot) && prior.coverage.throughFinalizedSlot > BigInt(snapshotSlot)) {
54333
+ markPhase("attest-reuse-older-snapshot");
54334
+ return { coverage: Object.freeze({ ...prior.coverage, throughFinalizedSlot: BigInt(snapshotSlot) }), attestation: prior, reused: true };
54335
+ }
54301
54336
  if (key !== void 0 && prior?.key === key && typeof prior.newestSignature === "string" && prior.coverage?.throughFinalizedSlot <= BigInt(snapshotSlot)) {
54302
54337
  const address5 = new import_web396.PublicKey(prior.coverage.programDataAddress);
54303
54338
  const deployedAtSlot = BigInt(prior.coverage.deployedAtSlot);
54304
- const reuse = (signature2) => {
54339
+ const reuse = (signature2, signatureSlot) => {
54305
54340
  const coverage = Object.freeze({ ...prior.coverage, throughFinalizedSlot: BigInt(snapshotSlot) });
54306
- return { coverage, attestation: { key, newestSignature: signature2, coverage }, reused: true };
54341
+ return { coverage, attestation: {
54342
+ key,
54343
+ newestSignature: signature2,
54344
+ ...Number.isSafeInteger(signatureSlot) && signatureSlot <= snapshotSlot ? { newestSignatureSlot: signatureSlot } : {},
54345
+ coverage
54346
+ }, reused: true };
54307
54347
  };
54308
54348
  const pooled = reuseAnswer !== void 0 && reuseAnswer.slot === snapshotSlot && reuseAnswer.address === address5.toBase58() ? reuseAnswer : void 0;
54309
54349
  if (pooled !== void 0) {
@@ -54311,7 +54351,7 @@ async function programDataCoverageFor(args) {
54311
54351
  assertProgramDataHeader(pooled.slot, pooled, { snapshotSlot, deployedAtSlot });
54312
54352
  if (pooled.newestSignature === prior.newestSignature) {
54313
54353
  markPhase("attest-reuse-in-pool-read");
54314
- return reuse(pooled.newestSignature);
54354
+ return reuse(pooled.newestSignature, pooled.newestSignatureSlot);
54315
54355
  }
54316
54356
  cause = "programdata_newest_signature_changed";
54317
54357
  } catch (error) {
@@ -54329,7 +54369,7 @@ async function programDataCoverageFor(args) {
54329
54369
  }),
54330
54370
  newestSignature(reuseConnection, address5, snapshotSlot)
54331
54371
  ]);
54332
- if (newest.signature === prior.newestSignature) return reuse(newest.signature);
54372
+ if (newest.signature === prior.newestSignature) return reuse(newest.signature, newest.slot);
54333
54373
  cause = "programdata_newest_signature_changed";
54334
54374
  break;
54335
54375
  } catch (error) {
@@ -54375,7 +54415,7 @@ async function programDataCoverageFor(args) {
54375
54415
  const newest = await newestSignature(connection, new import_web396.PublicKey(coverage.programDataAddress), snapshotSlot);
54376
54416
  return {
54377
54417
  coverage,
54378
- attestation: key !== void 0 && newest.slot <= snapshotSlot ? { key, newestSignature: newest.signature, coverage } : void 0,
54418
+ attestation: key !== void 0 && newest.slot <= snapshotSlot ? { key, newestSignature: newest.signature, newestSignatureSlot: newest.slot, coverage } : void 0,
54379
54419
  reused: false
54380
54420
  };
54381
54421
  })();
@@ -57401,7 +57441,7 @@ function withBoundedOwnReads(connection) {
57401
57441
  if (typeof value !== "function") return value;
57402
57442
  if (BOUNDED_OWN_METHODS.has(property)) return (...args) => boundedOwnRead(() => value.apply(target, args));
57403
57443
  if (property === "_rpcRequest") {
57404
- return (...args) => args[0] === P03_POOL_SLICES_METHOD ? boundedOwnRead(() => value.apply(target, args)) : value.apply(target, args);
57444
+ return (...args) => args[0] === P03_POOL_SLICES_METHOD ? boundedOwnRead((stalled) => hedgedOwnPoolSlicesRead(target, args[1], { stalled })) : value.apply(target, args);
57405
57445
  }
57406
57446
  return value.bind(target);
57407
57447
  }
@@ -57452,8 +57492,15 @@ async function readPages(history, pool2, needed, first, { wakeSlot } = {}) {
57452
57492
  }
57453
57493
  return { records: records.slice(0, needed), imports, initialization, syncedSlot };
57454
57494
  }
57455
- async function readCompactPoolSnapshot({ connection, programId, pool: pool2 }) {
57456
- return readFinalizedPool(withBoundedOwnReads(connection), new import_web397.PublicKey(programId), new import_web397.PublicKey(pool2), { treeSlices: true });
57495
+ function startCompactPoolSnapshot({ connection, programId, pool: pool2 }) {
57496
+ const own = withBoundedOwnReads(connection);
57497
+ const program = new import_web397.PublicKey(programId);
57498
+ const poolKey = new import_web397.PublicKey(pool2);
57499
+ const sliced = readFinalizedPoolSliced(own, program, poolKey).catch(() => void 0);
57500
+ const full = sliced.then((snapshot) => snapshot ?? readFinalizedPool(own, program, poolKey));
57501
+ full.catch(() => {
57502
+ });
57503
+ return { sliced, full };
57457
57504
  }
57458
57505
  function requestCompactFirstPage({ history, pool: pool2 }) {
57459
57506
  try {
@@ -57521,15 +57568,40 @@ async function ownTransaction(own, signature2) {
57521
57568
  }
57522
57569
  async function hedgedOwnTransactionRead(own, signature2, { stalled, hedge = inTorRun, afterMs = SPOT_HEDGE_AFTER_MS } = {}) {
57523
57570
  const params = [signature2, { commitment: "finalized", maxSupportedTransactionVersion: 1, encoding: "base64" }];
57524
- if (typeof own.abortableRpcRequest !== "function") return own._rpcRequest("getTransaction", params);
57525
- const id = `spot-${spotReadId += 1}`;
57571
+ return hedgedOwnRead(own, "getTransaction", params, {
57572
+ stalled,
57573
+ hedge,
57574
+ afterMs,
57575
+ id: `spot-${spotReadId += 1}`,
57576
+ lane: SPOT_HEDGE_LANE,
57577
+ mark: "spot-hedge",
57578
+ passes: (response) => {
57579
+ checkedOwnTransaction(response, signature2);
57580
+ }
57581
+ });
57582
+ }
57583
+ function hedgedOwnPoolSlicesRead(own, params, { stalled, hedge = inTorRun, afterMs = POOL_HEDGE_AFTER_MS } = {}) {
57584
+ return hedgedOwnRead(own, P03_POOL_SLICES_METHOD, params, {
57585
+ stalled,
57586
+ hedge,
57587
+ afterMs,
57588
+ id: `pool-${poolReadId += 1}`,
57589
+ lane: POOL_HEDGE_LANE,
57590
+ mark: "pool-hedge",
57591
+ passes: (response) => {
57592
+ if (response === null || typeof response !== "object" || !("result" in response || "error" in response)) throw new Error("no answer");
57593
+ }
57594
+ });
57595
+ }
57596
+ async function hedgedOwnRead(own, method, params, { stalled, hedge, afterMs, id, lane: hedgeLane, mark, passes: check }) {
57597
+ if (typeof own.abortableRpcRequest !== "function") return own._rpcRequest(method, params);
57526
57598
  const copies = [];
57527
57599
  const send3 = (lane) => {
57528
57600
  const controller = new AbortController();
57529
57601
  const signal = stalled === void 0 ? controller.signal : AbortSignal.any([stalled, controller.signal]);
57530
57602
  const copy = { controller, lane, outcome: void 0 };
57531
57603
  copy.read = own.abortableRpcRequest(
57532
- "getTransaction",
57604
+ method,
57533
57605
  params,
57534
57606
  signal,
57535
57607
  void 0,
@@ -57556,14 +57628,14 @@ async function hedgedOwnTransactionRead(own, signature2, { stalled, hedge = inTo
57556
57628
  const follow = (copy, which) => copy.read.then((response) => {
57557
57629
  let passes = false;
57558
57630
  try {
57559
- checkedOwnTransaction(response, signature2);
57631
+ check(response);
57560
57632
  passes = true;
57561
57633
  } catch {
57562
57634
  passes = false;
57563
57635
  }
57564
57636
  copy.outcome = { response, passes };
57565
57637
  if (passes && !done) {
57566
- if (copies.length > 1) markPhase(`spot-hedge-won-${which}`);
57638
+ if (copies.length > 1) markPhase(`${mark}-won-${which}`);
57567
57639
  finish(() => resolve38(response));
57568
57640
  return;
57569
57641
  }
@@ -57580,8 +57652,8 @@ async function hedgedOwnTransactionRead(own, signature2, { stalled, hedge = inTo
57580
57652
  clearTimeout(timer);
57581
57653
  timer = void 0;
57582
57654
  if (done || copies.length > 1) return;
57583
- markPhase("spot-hedge-sent");
57584
- follow(send3(SPOT_HEDGE_LANE), "hedge");
57655
+ markPhase(`${mark}-sent`);
57656
+ follow(send3(hedgeLane), "hedge");
57585
57657
  };
57586
57658
  follow(send3(void 0), "first");
57587
57659
  timer = hedging ? setTimeout(sendHedge, afterMs) : void 0;
@@ -58234,7 +58306,7 @@ async function tryCompactP03HistoryReport(options) {
58234
58306
  return { ok: false, reason, ...detail ? { detail } : {}, error };
58235
58307
  }
58236
58308
  }
58237
- 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;
58309
+ var import_web397, P03_COMPACT_HISTORY_SOURCE_MODEL, P03_COMPACT_PAGE, P03_COMPACT_SPOT_CHECKS, FIELD_MODULUS5, SUBTREE_LEAVES3, LOCAL_DEPTH2, OUTER_DEPTH2, PRIMARY_PROOF_BYTES2, FIELD_BYTES3, ED25519_SPKI_PREFIX2, VERSION_1_PREFIX2, HEX64, BASE58, REPLAY_STORE_INDEXED2, PROFILES2, MOVE_HEAD_BYTES2, MOVE_INSERTED_VALUES2, refuse3, hash4, bitAt, zeroRootsMemo, lastFolds, PRE_FOLD_SLICE_MS, preFolds, hex64, droppedPools, verifyQuietMs, VERIFY_SLICE_MS, VERIFY_POLL_MS, verifying, unrefTurn, isSignature, isIndex, IMPORT_KEYS, IMPORT_MAX_VALUES, LIST_ATTEMPTS, pageZeroInFlight, OWN_READ_TIMEOUT_MS, BOUNDED_OWN_METHODS, SPOT_HEDGE_AFTER_MS, SPOT_HEDGE_LANE, spotReadId, POOL_HEDGE_AFTER_MS, POOL_HEDGE_LANE, poolReadId, compactReportsRunning, compactHistoryReadsRunning;
58238
58310
  var init_compact = __esm({
58239
58311
  "wallet/src/history/compact.mjs"() {
58240
58312
  "use strict";
@@ -58370,6 +58442,9 @@ var init_compact = __esm({
58370
58442
  SPOT_HEDGE_AFTER_MS = 4e3;
58371
58443
  SPOT_HEDGE_LANE = "spot-hedge";
58372
58444
  spotReadId = 0;
58445
+ POOL_HEDGE_AFTER_MS = 5e3;
58446
+ POOL_HEDGE_LANE = "pool-hedge";
58447
+ poolReadId = 0;
58373
58448
  compactReportsRunning = 0;
58374
58449
  compactHistoryReadsRunning = () => compactReportsRunning;
58375
58450
  }
@@ -58988,7 +59063,7 @@ async function loadWalletP03History(args) {
58988
59063
  }
58989
59064
  if (runKey !== void 0 && recentScope.getStore() !== void 0 && strictScope.getStore() !== true && args.forceRead !== true) {
58990
59065
  const recent = recentLoads.get(runKey);
58991
- if (recent !== void 0 && Date.now() - recent.startedAt <= HISTORY_PREWARM_JOIN_MS) {
59066
+ if (recent !== void 0 && Date.now() - recentAgeStart(recent) <= HISTORY_PREWARM_JOIN_MS) {
58992
59067
  PREWARMED_REPORTS.add(recent.report);
58993
59068
  PAYMENT_TAKEN_REPORTS.add(recent.report);
58994
59069
  markPhase("walk-recent");
@@ -59022,7 +59097,7 @@ function recentBeforePrewarm(runKey, prewarm) {
59022
59097
  const accept = recentScope.getStore()?.accept;
59023
59098
  if (typeof accept !== "function" || prewarm.settled) return void 0;
59024
59099
  const recent = recentLoads.get(runKey);
59025
- if (recent === void 0 || Date.now() - recent.startedAt > HISTORY_PREWARM_JOIN_MS) return void 0;
59100
+ if (recent === void 0 || Date.now() - recentAgeStart(recent) > HISTORY_PREWARM_JOIN_MS) return void 0;
59026
59101
  let accepted = false;
59027
59102
  try {
59028
59103
  accepted = accept(recent.report) === true;
@@ -59167,11 +59242,11 @@ async function walkWalletP03HistoryNow({ store, connection: given, programId, po
59167
59242
  if (typeof index === "bigint") movedIndex = index + SUBTREE_LEAVES4;
59168
59243
  } else if (earlier !== void 0) {
59169
59244
  markPhase("refresh-start");
59170
- const refreshing = refreshFinalizedP03HistorySnapshot({ connection, programId, pool: pool2, history: earlier });
59245
+ let slicedPreRead;
59171
59246
  if (compactNext) {
59172
- poolPreRead = readCompactPoolSnapshot({ connection, programId, pool: pool2 });
59173
- poolPreRead.catch(() => {
59174
- });
59247
+ const started = startCompactPoolSnapshot({ connection, programId, pool: pool2 });
59248
+ slicedPreRead = started.sliced;
59249
+ poolPreRead = started.full;
59175
59250
  markPhase("compact-pool-prestarted");
59176
59251
  if (!inTorRun() && Date.now() - remembered.at > PAGE0_PREREAD_AFTER_MS) {
59177
59252
  firstPreRead = requestCompactFirstPage({ history: connection.historyRpcSource, pool: pool2 });
@@ -59184,11 +59259,24 @@ async function walkWalletP03HistoryNow({ store, connection: given, programId, po
59184
59259
  } catch {
59185
59260
  }
59186
59261
  }
59262
+ let fromSliced = false;
59263
+ const refreshing = (async () => {
59264
+ if (slicedPreRead !== void 0) {
59265
+ const decided = await refreshFinalizedP03HistoryFromSliced({ connection, programId, pool: pool2, history: earlier, snapshot: await slicedPreRead });
59266
+ if (decided !== void 0) {
59267
+ fromSliced = true;
59268
+ markPhase("refresh-from-sliced");
59269
+ return decided;
59270
+ }
59271
+ markPhase("refresh-sliced-undecided");
59272
+ }
59273
+ return refreshFinalizedP03HistorySnapshot({ connection, programId, pool: pool2, history: earlier });
59274
+ })();
59187
59275
  try {
59188
59276
  const refreshed = await refreshing;
59189
59277
  markPhase("walk-refreshed");
59190
59278
  rememberRunReport(runKey, refreshed);
59191
- writeStderr("history: the pool made no transition since this run's last walk; that history was moved to the current pool account (your own RPC read the pool account and the program's deployment account; the history source answered one signature read)\n");
59279
+ writeStderr("history: the pool made no transition since this run's last walk; that history was moved to the current pool account " + (fromSliced ? "(your own RPC read the pool account and the program's deployment account in one request)\n" : "(your own RPC read the pool account and the program's deployment account; the history source answered one signature read)\n"));
59192
59280
  return refreshed;
59193
59281
  } catch (error) {
59194
59282
  markPhase("refresh-missed");
@@ -59411,7 +59499,7 @@ function reportHistoryRpc(split5, source, result, crossChecked) {
59411
59499
  writeStderr(`history: ${who} answered ${list(split5.history)}; your own RPC answered ${list(split5.own)} (the pool account the history must match, and the cross-check)${window2}${integrity}
59412
59500
  `);
59413
59501
  }
59414
- var prepareReport, strictScope, withStrictHistorySource, recentScope, withRecentWalletHistory, recentLoads, forgetRecentWalletHistory, proofBuiltAt, historyCacheKey, latestPrewarm, HOME_MARKS_SETTLED_MS, HISTORY_PREWARM_JOIN_MS, SHARED_WALK_WAIT_MS, PAGE0_PREREAD_AFTER_MS, SUBTREE_LEAVES4, prewarmedWalks, sharedWalks, PREWARMED_REPORTS, PAYMENT_TAKEN_REPORTS, isPrewarmedWalletHistory, REPORT_STARTED_AT, walkStartedAtOf, COMPACT_BEHIND_POLL_MS, COMPACT_BEHIND_READ_MS, COMPACT_BEHIND_TOR_READ_MS, COMPACT_BEHIND_REFUSAL_MAX_BYTES, COMPACT_BEHIND_PAGE_BODY_MS, COMPACT_BEHIND_RETRY_MS, lastRunReports, writeStderr, announcedSources;
59502
+ var prepareReport, strictScope, withStrictHistorySource, recentScope, withRecentWalletHistory, recentLoads, recentAgeStart, forgetRecentWalletHistory, proofBuiltAt, historyCacheKey, latestPrewarm, HOME_MARKS_SETTLED_MS, HISTORY_PREWARM_JOIN_MS, SHARED_WALK_WAIT_MS, PAGE0_PREREAD_AFTER_MS, SUBTREE_LEAVES4, prewarmedWalks, sharedWalks, PREWARMED_REPORTS, PAYMENT_TAKEN_REPORTS, isPrewarmedWalletHistory, REPORT_STARTED_AT, walkStartedAtOf, COMPACT_BEHIND_POLL_MS, COMPACT_BEHIND_READ_MS, COMPACT_BEHIND_TOR_READ_MS, COMPACT_BEHIND_REFUSAL_MAX_BYTES, COMPACT_BEHIND_PAGE_BODY_MS, COMPACT_BEHIND_RETRY_MS, lastRunReports, writeStderr, announcedSources;
59415
59503
  var init_walletHistory = __esm({
59416
59504
  "wallet/src/history/walletHistory.mjs"() {
59417
59505
  "use strict";
@@ -59433,6 +59521,7 @@ var init_walletHistory = __esm({
59433
59521
  recentScope = new AsyncLocalStorage2();
59434
59522
  withRecentWalletHistory = (fn, { accept } = {}) => recentScope.run({ accept }, fn);
59435
59523
  recentLoads = /* @__PURE__ */ new Map();
59524
+ recentAgeStart = (recent) => poolReadAtOf(recent.report) ?? recent.startedAt;
59436
59525
  forgetRecentWalletHistory = () => {
59437
59526
  recentLoads.clear();
59438
59527
  proofBuiltAt = Date.now();
@@ -73847,6 +73936,7 @@ async function runRecoveredP03NoteExit({
73847
73936
  pool: pool2,
73848
73937
  history
73849
73938
  });
73939
+ markPhase("exit-anchor-refreshed");
73850
73940
  timestamp = await readChainTime();
73851
73941
  epoch = BigInt(Math.floor(timestamp / 300));
73852
73942
  }
@@ -73988,6 +74078,7 @@ async function runRecoveredP03NoteExit({
73988
74078
  epoch = BigInt(Math.floor(timestamp / 300));
73989
74079
  }
73990
74080
  await ensureCurrentAnchor();
74081
+ markPhase("exit-anchor-current");
73991
74082
  const buildRecoveryPath = deps.buildRecoveryPath ?? buildFinalizedP03RecoveryPath;
73992
74083
  const prepareFold = deps.buildRecoveryPath === void 0 ? prepareFinalizedP03RecoveryFold : async () => {
73993
74084
  };
@@ -74070,8 +74161,10 @@ async function runRecoveredP03NoteExit({
74070
74161
  store.writeWal(walName2, wal);
74071
74162
  }
74072
74163
  let proved = wal.proved;
74164
+ markPhase("exit-request-built");
74073
74165
  if (!proved) {
74074
74166
  proved = await proveExit(request);
74167
+ markPhase("exit-proved");
74075
74168
  assertProvedExitBinding(proved, request);
74076
74169
  wal = {
74077
74170
  ...wal,
@@ -74099,6 +74192,7 @@ async function runRecoveredP03NoteExit({
74099
74192
  memoBundleHex: proved.output.memoBundleHex,
74100
74193
  recipientTokenAccount: recipient.toBase58()
74101
74194
  }) : await selfBroadcastExit();
74195
+ markPhase(relaySubmit ? "exit-relay-answered" : "exit-sent");
74102
74196
  async function selfBroadcastExit() {
74103
74197
  if (poolState2.replayStore === REPLAY_STORE.indexedTree) return selfBroadcastE1Exit();
74104
74198
  const replayValues = [proved.primary.publicInputBytesHex[3]];
@@ -74195,6 +74289,7 @@ async function runRecoveredP03NoteExit({
74195
74289
  store.writeWal(walName2, wal);
74196
74290
  for (let attempt = 1; ; attempt += 1) {
74197
74291
  history = await walkHistory();
74292
+ markPhase("exit-post-walk");
74198
74293
  poolState2 = await readPool2(connection, pool2, "finalized");
74199
74294
  if (!poolState2 || !poolState2.owner.equals(chainProgramId) || poolState2.version !== 3) {
74200
74295
  throw new Error("finalized note-exit pool postcondition invalid");
@@ -74990,6 +75085,7 @@ var init_shielded_wallet = __esm({
74990
75085
  init_settlement_receipt();
74991
75086
  init_safe_exit();
74992
75087
  init_walletHistory();
75088
+ init_phaseTiming();
74993
75089
  init_chain2();
74994
75090
  init_compressedReplay();
74995
75091
  init_e1Exit();
@@ -108644,7 +108740,7 @@ function balanceLine(a) {
108644
108740
  const pub = usdcText(a.unshieldedAtomic);
108645
108741
  const landing = usdcText(a.landingAtomic);
108646
108742
  if (positive(landing) && !a.refreshError) {
108647
- const line = `${landing} USDC you added landed and is being counted. Ask again in about 30 seconds.`;
108743
+ const line = `${landing} USDC you added landed and is being counted. It needs no step from you.`;
108648
108744
  return balance !== void 0 && a.refreshing !== true ? `You have ${balance} USDC private; ${line}` : line;
108649
108745
  }
108650
108746
  const arriving = addFundsHeldSay(a.addFunds);
@@ -119278,7 +119374,7 @@ ${canonical5}`;
119278
119374
  const balance = {
119279
119375
  name: "wallet_balance",
119280
119376
  title: "Balance",
119281
- description: `Use this when the user asks "what is my balance" or "how much USDC do I have": it answers ONE balance (balanceAtomic, what x402_pay can spend) and the public (unshielded) USDC. Pays nothing and signs nothing. balanceAtomic is one number; breakdown names its parts (breakdown.shieldedAtomic is what wallet_unshield can send; privateSendPendingAtomic is the part of a running private send (wallet_unshield with parts or max_delay_minutes) not sent yet, already taken off shieldedAtomic; refundsInFlightAtomic is a Shinjuku refund on its way back; setAsideAtomic (only when not 0) is value an older version of this wallet set aside to pay sellers; during a pool move, pools lists each pool's part and movingAtomic is value on its way from the old pool to the new one; the move field shows the move, poolSwitches each switch). UNSHIELDED (unshieldedAtomic) is the plain public USDC on the wallet's own Solana key (ownAddress), the USDC wallet_shield makes private; unshieldedSolLamports is that key's SOL, information only: wallet_shield needs none (the facilitator's relayer pays every fee and rent). When the local balance is stale (a new deposit, a received payment), it reads the chain by itself first; when that takes longer than about 20 s it answers the last balance with refreshing: true and finishes in the background (call wallet_balance again in 30 s). A balance with refreshing: true and refreshReason is exact (payment_settling: a payment settles and the number counts it; account_join: the wallet joins its own balance parts and the number counts them; pool_move: value from the old pool arrives and the number counts it; first_check: a new wallet's first history check, the number is its own landed deposits). status reading (balanceAtomic null): the first balance read of a wallet that may hold money is not done; call wallet_balance again in 30 s. If the public read fails, unshieldedAtomic is null with unshieldedReason; the rest still answers. ownKeyTokens (only when there are any): the other tokens on ownAddress (not its USDC), each { mint, amountAtomic, decimals, amount }, at most 10 (ownKeyTokensMore counts the rest); a token is its mint, never a name or symbol; wallet_transfer_token with that mint as token_mint sells one and sends the USDC privately. earlierDeposits (only when there are any): USDC found at a one-time deposit address of an earlier pool, each with a notice line to tell the user; the wallet moves it into the current pool by itself. addFunds (only when there are any): each wallet_add_funds address still open, with its state and the USDC known to wait there (heldAtomic; null with heldNote when the address was not checked yet). landingAtomic (only when not 0): USDC you added whose deposit landed on chain and that balanceAtomic does not count yet; this call finishes it and waits about 20 s for it, past that it is being counted: call wallet_balance again in 30 s. session shows the spending limits (null or "none": no limit), what is left, where the limits come from, and how to change them (session.summary). verbose: true adds \`internal\` (accounts, notes, and other engineering numbers); the default answer leaves them out. To add money, use wallet_add_funds. Amounts are atomic units (USDC: 1000000 = 1 USDC); say and usdc give them in USDC.`,
119377
+ description: `Use this when the user asks "what is my balance" or "how much USDC do I have": it answers ONE balance (balanceAtomic, what x402_pay can spend) and the public (unshielded) USDC. Pays nothing and signs nothing. balanceAtomic is one number; breakdown names its parts (breakdown.shieldedAtomic is what wallet_unshield can send; privateSendPendingAtomic is the part of a running private send (wallet_unshield with parts or max_delay_minutes) not sent yet, already taken off shieldedAtomic; refundsInFlightAtomic is a Shinjuku refund on its way back; setAsideAtomic (only when not 0) is value an older version of this wallet set aside to pay sellers; during a pool move, pools lists each pool's part and movingAtomic is value on its way from the old pool to the new one; the move field shows the move, poolSwitches each switch). UNSHIELDED (unshieldedAtomic) is the plain public USDC on the wallet's own Solana key (ownAddress), the USDC wallet_shield makes private; unshieldedSolLamports is that key's SOL, information only: wallet_shield needs none (the facilitator's relayer pays every fee and rent). When the local balance is stale (a new deposit, a received payment), it reads the chain by itself first; when that takes longer than about 20 s it answers the last balance with refreshing: true and finishes in the background (call wallet_balance again in 30 s). A balance with refreshing: true and refreshReason is exact (payment_settling: a payment settles and the number counts it; account_join: the wallet joins its own balance parts and the number counts them; pool_move: value from the old pool arrives and the number counts it; first_check: a new wallet's first history check, the number is its own landed deposits). status reading (balanceAtomic null): the first balance read of a wallet that may hold money is not done; call wallet_balance again in 30 s. If the public read fails, unshieldedAtomic is null with unshieldedReason; the rest still answers. ownKeyTokens (only when there are any): the other tokens on ownAddress (not its USDC), each { mint, amountAtomic, decimals, amount }, at most 10 (ownKeyTokensMore counts the rest); a token is its mint, never a name or symbol; wallet_transfer_token with that mint as token_mint sells one and sends the USDC privately. earlierDeposits (only when there are any): USDC found at a one-time deposit address of an earlier pool, each with a notice line to tell the user; the wallet moves it into the current pool by itself. addFunds (only when there are any): each wallet_add_funds address still open, with its state and the USDC known to wait there (heldAtomic; null with heldNote when the address was not checked yet). landingAtomic (only when not 0): USDC you added whose deposit landed on chain and that balanceAtomic does not count yet; this call finishes it and waits about 20 s for it, past that it is being counted: call wallet_balance again as next says (at once in the same turn when this call waited its 20 s, else in 30 s). session shows the spending limits (null or "none": no limit), what is left, where the limits come from, and how to change them (session.summary). verbose: true adds \`internal\` (accounts, notes, and other engineering numbers); the default answer leaves them out. To add money, use wallet_add_funds. Amounts are atomic units (USDC: 1000000 = 1 USDC); say and usdc give them in USDC.`,
119282
119378
  inputSchema: { type: "object", properties: {
119283
119379
  verbose: { type: "boolean", description: "Optional. true adds `internal`: the engineering numbers (funded accounts, notes, payments without waiting, a 0 set-aside value). Default false." }
119284
119380
  }, additionalProperties: false },
@@ -119479,7 +119575,8 @@ ${canonical5}`;
119479
119575
  if (typeof amount === "bigint" && amount > 0n) landingAtomic += amount;
119480
119576
  }
119481
119577
  }
119482
- 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;
119578
+ const landedWaitedFull = Date.now() - balanceStartedAt >= balanceRefreshWaitMs;
119579
+ const landedNext = landingAtomic > 0n && !refresh.refreshError ? landedWaitedFull ? `${usdcText2(landingAtomic)} USDC you added landed on chain and is being counted (landingAtomic, not in balanceAtomic yet): call wallet_balance again now, in this same turn; that call waits up to ${waitSeconds} s for it. Do not end the turn or ask the user: it needs no step from them` : `${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;
119483
119580
  if (landedNext) next = landedNext;
119484
119581
  const stalled = [...resumeRefusals].map(([requestId, error2]) => `"${requestId}" (${error2})`);
119485
119582
  if (stalled.length && one.breakdown?.privateSendPendingAtomic !== "0") {