shinjuku-shielded 0.3.35 → 0.3.37

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": "fc7329d0267d82e7f06546009c64924d0ec713165c3bfe270512ba0672b94cbd",
5
- "bytes": 11187416,
6
- "sourceCommit": "dcbbb1497a0fcf92d4e0ff9bd78fb81b72075631",
4
+ "sha256": "1335e815f99108526e1a9d4e93f53a94d95910ea150e404987f09826c39fc547",
5
+ "bytes": 11195840,
6
+ "sourceCommit": "c27f02e8ca3ec7ba4862c1292aad35ed9d766934",
7
7
  "sourceDirty": false,
8
8
  "installRecordMatchesLockfile": true,
9
9
  "releaseRule": "valid only when two fresh npm ci --ignore-scripts builds on different OSes give the same sha256; installRecordMatchesLockfile true means every entry npm installed equals its package-lock.json entry and every entry not marked optional, devOptional included, is installed: an optional entry (a package for another platform) may be absent",
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "shinjuku-shielded",
3
- "version": "0.3.35",
3
+ "version": "0.3.37",
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": "fc7329d0",
7
- "shinjukuSha256": "fc7329d0267d82e7f06546009c64924d0ec713165c3bfe270512ba0672b94cbd",
6
+ "shinjukuRelease": "1335e815",
7
+ "shinjukuSha256": "1335e815f99108526e1a9d4e93f53a94d95910ea150e404987f09826c39fc547",
8
8
  "license": "SEE LICENSE IN LICENSE.txt",
9
9
  "author": "Shinjuku Shielded",
10
10
  "homepage": "https://github.com/ShinjukuStaition/shinjuku-mcp#readme",
@@ -18266,7 +18266,7 @@ var require_websocket = __commonJS({
18266
18266
  var http2 = __require("http");
18267
18267
  var net2 = __require("net");
18268
18268
  var tls = __require("tls");
18269
- var { randomBytes: randomBytes30, createHash: createHash38 } = __require("crypto");
18269
+ var { randomBytes: randomBytes30, createHash: createHash39 } = __require("crypto");
18270
18270
  var { Duplex, Readable } = __require("stream");
18271
18271
  var { URL: URL4 } = __require("url");
18272
18272
  var PerMessageDeflate = require_permessage_deflate();
@@ -18934,7 +18934,7 @@ var require_websocket = __commonJS({
18934
18934
  abortHandshake(websocket, socket, "Invalid Upgrade header");
18935
18935
  return;
18936
18936
  }
18937
- const digest2 = createHash38("sha1").update(key + GUID).digest("base64");
18937
+ const digest2 = createHash39("sha1").update(key + GUID).digest("base64");
18938
18938
  if (res.headers["sec-websocket-accept"] !== digest2) {
18939
18939
  abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
18940
18940
  return;
@@ -19303,7 +19303,7 @@ var require_websocket_server = __commonJS({
19303
19303
  var EventEmitter = __require("events");
19304
19304
  var http2 = __require("http");
19305
19305
  var { Duplex } = __require("stream");
19306
- var { createHash: createHash38 } = __require("crypto");
19306
+ var { createHash: createHash39 } = __require("crypto");
19307
19307
  var extension3 = require_extension();
19308
19308
  var PerMessageDeflate = require_permessage_deflate();
19309
19309
  var subprotocol = require_subprotocol();
@@ -19610,7 +19610,7 @@ var require_websocket_server = __commonJS({
19610
19610
  );
19611
19611
  }
19612
19612
  if (this._state > RUNNING) return abortHandshake(socket, 503);
19613
- const digest2 = createHash38("sha1").update(key + GUID).digest("base64");
19613
+ const digest2 = createHash39("sha1").update(key + GUID).digest("base64");
19614
19614
  const headers = [
19615
19615
  "HTTP/1.1 101 Switching Protocols",
19616
19616
  "Upgrade: websocket",
@@ -49186,6 +49186,36 @@ var init_book = __esm({
49186
49186
  }
49187
49187
  });
49188
49188
 
49189
+ // wallet/src/fetch/keepAlive.mjs
49190
+ function proxiedRun() {
49191
+ const env = process.env;
49192
+ return Boolean(env.SHINJUKU_WALLET_PROXIED || env.NODE_USE_ENV_PROXY || env.HTTPS_PROXY || env.HTTP_PROXY || env.https_proxy || env.http_proxy);
49193
+ }
49194
+ function keepAliveDispatcher() {
49195
+ if (shared !== void 0) return shared;
49196
+ try {
49197
+ if (proxiedRun()) return void 0;
49198
+ const global2 = globalThis[GLOBAL_DISPATCHER];
49199
+ if (global2?.constructor?.name !== "Agent") return void 0;
49200
+ shared = new global2.constructor({ keepAliveTimeout: KEEP_ALIVE_MS, keepAliveMaxTimeout: KEEP_ALIVE_MS });
49201
+ return shared;
49202
+ } catch {
49203
+ return void 0;
49204
+ }
49205
+ }
49206
+ function keepAliveInit(init = {}) {
49207
+ const dispatcher = keepAliveDispatcher();
49208
+ return dispatcher === void 0 ? init : { ...init, dispatcher };
49209
+ }
49210
+ var GLOBAL_DISPATCHER, KEEP_ALIVE_MS, shared;
49211
+ var init_keepAlive = __esm({
49212
+ "wallet/src/fetch/keepAlive.mjs"() {
49213
+ "use strict";
49214
+ GLOBAL_DISPATCHER = /* @__PURE__ */ Symbol.for("undici.globalDispatcher.1");
49215
+ KEEP_ALIVE_MS = 2e4;
49216
+ }
49217
+ });
49218
+
49189
49219
  // wallet/vendor/shielded-x402-model/src/reference.mjs
49190
49220
  import { dirname as dirname5, join as join6 } from "node:path";
49191
49221
  import { fileURLToPath as fileURLToPath3 } from "node:url";
@@ -49756,11 +49786,12 @@ var init_anchorClock = __esm({
49756
49786
  // wallet/src/chain.mjs
49757
49787
  import { createHash as createHash7, createPublicKey, randomInt, verify as verifySignature } from "node:crypto";
49758
49788
  function connect2(rpcUrl, commitment = "finalized", { timeoutMs } = {}) {
49759
- const fetch2 = timeoutMs === void 0 ? rpcFetch : async (input, init) => {
49789
+ const pooled = (input, init) => rpcFetch(input, keepAliveInit(init));
49790
+ const fetch2 = timeoutMs === void 0 ? pooled : async (input, init) => {
49760
49791
  const circuit = torCircuit();
49761
49792
  const timeout = AbortSignal.timeout(timeoutMs);
49762
49793
  try {
49763
- const response = await rpcFetch(input, { ...init, signal: init?.signal ? AbortSignal.any([init.signal, timeout]) : timeout });
49794
+ const response = await pooled(input, { ...init, signal: init?.signal ? AbortSignal.any([init.signal, timeout]) : timeout });
49764
49795
  const body = await response.text();
49765
49796
  const headers = new Headers(response.headers);
49766
49797
  headers.delete("content-encoding");
@@ -49771,7 +49802,23 @@ function connect2(rpcUrl, commitment = "finalized", { timeoutMs } = {}) {
49771
49802
  throw error;
49772
49803
  }
49773
49804
  };
49774
- return countRpcCalls(new import_web395.Connection(rpcUrl, { commitment, fetch: fetch2, disableRetryOnRateLimit: true }));
49805
+ const connection = countRpcCalls(new import_web395.Connection(rpcUrl, { commitment, fetch: fetch2, disableRetryOnRateLimit: true }));
49806
+ let nextId = 0;
49807
+ Object.defineProperty(connection, "abortableRpcRequest", {
49808
+ value: async (method, params, signal) => {
49809
+ const response = await fetch2(rpcUrl, {
49810
+ method: "POST",
49811
+ signal,
49812
+ headers: { "content-type": "application/json" },
49813
+ body: JSON.stringify({ jsonrpc: "2.0", id: `abortable-${nextId += 1}`, method, params })
49814
+ });
49815
+ return response.json();
49816
+ },
49817
+ enumerable: false,
49818
+ writable: false,
49819
+ configurable: true
49820
+ });
49821
+ return connection;
49775
49822
  }
49776
49823
  function countRpcCalls(connection) {
49777
49824
  const counters = Object.fromEntries(COUNTED_RPC_METHODS.map((name) => [name, 0]));
@@ -50040,11 +50087,11 @@ function connectSplit(own, historyUrl, commitment = "finalized", { pause: pause3
50040
50087
  const now = Date.now();
50041
50088
  if (behindSince === void 0) {
50042
50089
  behindSince = now;
50043
- notice(strictAfterSlot === void 0 ? `history: the history source is behind the chain (JSON-RPC -32016: it has not reached the slot your own RPC read the pool account at); asking again after 0.5 s, 1 s, 2 s, then every 5 s, for at most ${HISTORY_RPC_BEHIND_WAIT_MS / 1e3} s
50044
- ` : `history: the pool account changed after slot ${strictAfterSlot}, the newest slot the history source had reached (its history did not rebuild the pool account your own RPC reads); asking it again after 0.5 s, 1 s, 2 s, then every 5 s, for at most ${HISTORY_RPC_BEHIND_WAIT_MS / 1e3} s
50090
+ notice(strictAfterSlot === void 0 ? `history: the history source is behind the chain (JSON-RPC -32016: it has not reached the slot your own RPC read the pool account at); asking again every 0.15 s for about 2 s, then after 0.5 s, 1 s, 2 s, then every 5 s, for at most ${HISTORY_RPC_BEHIND_WAIT_MS / 1e3} s
50091
+ ` : `history: the pool account changed after slot ${strictAfterSlot}, the newest slot the history source had reached (its history did not rebuild the pool account your own RPC reads); asking it again every 0.15 s for about 2 s, then after 0.5 s, 1 s, 2 s, then every 5 s, for at most ${HISTORY_RPC_BEHIND_WAIT_MS / 1e3} s
50045
50092
  `);
50046
50093
  }
50047
- const delay3 = HISTORY_RPC_BEHIND_RETRY_STEPS_MS[Math.min(behindWaits, HISTORY_RPC_BEHIND_RETRY_STEPS_MS.length - 1)];
50094
+ const delay3 = behindWaits < HISTORY_RPC_BEHIND_FAST_TRIES ? HISTORY_RPC_BEHIND_FAST_MS : HISTORY_RPC_BEHIND_RETRY_STEPS_MS[Math.min(behindWaits - HISTORY_RPC_BEHIND_FAST_TRIES, HISTORY_RPC_BEHIND_RETRY_STEPS_MS.length - 1)];
50048
50095
  if (now - behindSince + delay3 > HISTORY_RPC_BEHIND_WAIT_MS) return false;
50049
50096
  behindWaits += 1;
50050
50097
  await pause3(delay3);
@@ -50571,13 +50618,14 @@ function depositIntentAddress2({ programId, pool: pool2, depositPublicInputBytes
50571
50618
  programId
50572
50619
  )[0];
50573
50620
  }
50574
- var import_web395, POOL_STATE_LEN2, POOL_STATE_LEN_RING2, ANCHOR_MODE_RING2, ANCHOR_RING_SLOTS2, ANCHOR_RING_HEADER2, ANCHOR_RING_FIRST_SLOT2, ANCHOR_RING_SLOT_LEN2, POOL_STATE_LEN_V22, BUFFER_HEADER_LEN2, MEMO_BUNDLE_BYTES2, PAYLOAD_LENGTH2, PAYLOAD_LENGTH_V22, TRANSITION_KIND2, INSTRUCTION2, COUNTED_RPC_METHODS, HISTORY_RPC_METHODS, PINNED_HISTORY_PROXIES, PINNED_HISTORY_HTTPS, HISTORY_RPC_OWN, historyRpcErrors, HISTORY_RPC_BEHIND_WAIT_MS, HISTORY_RPC_REQUEST_TIMEOUT_MS, HISTORY_RPC_BEHIND_RETRY_STEPS_MS, HISTORY_RPC_BEHIND_CODE, ED25519_SPKI_PREFIX, SIGNATURE_BYTES, VERSION_1_PREFIX, HISTORY_CROSS_CHECK_COUNT, runTransactions, warmedSources, bytes323, MEMO_BATCH_MAX, MEMO_ATTEMPTS, MEMO_MAX_WAIT_SECONDS, MEMO_ANSWER_TIMEOUT_MS, MEMO_BODY_TIMEOUT_MS, pauseFor, noticeOnStderr, memoDigestHex, memoFailureText, prefetchedMemosByFetch, MEMO_PREFETCH_LIFE_MS;
50621
+ var import_web395, POOL_STATE_LEN2, POOL_STATE_LEN_RING2, ANCHOR_MODE_RING2, ANCHOR_RING_SLOTS2, ANCHOR_RING_HEADER2, ANCHOR_RING_FIRST_SLOT2, ANCHOR_RING_SLOT_LEN2, POOL_STATE_LEN_V22, BUFFER_HEADER_LEN2, MEMO_BUNDLE_BYTES2, PAYLOAD_LENGTH2, PAYLOAD_LENGTH_V22, TRANSITION_KIND2, INSTRUCTION2, COUNTED_RPC_METHODS, HISTORY_RPC_METHODS, PINNED_HISTORY_PROXIES, PINNED_HISTORY_HTTPS, HISTORY_RPC_OWN, historyRpcErrors, HISTORY_RPC_BEHIND_WAIT_MS, HISTORY_RPC_REQUEST_TIMEOUT_MS, HISTORY_RPC_BEHIND_FAST_MS, HISTORY_RPC_BEHIND_FAST_TRIES, HISTORY_RPC_BEHIND_RETRY_STEPS_MS, HISTORY_RPC_BEHIND_CODE, ED25519_SPKI_PREFIX, SIGNATURE_BYTES, VERSION_1_PREFIX, HISTORY_CROSS_CHECK_COUNT, runTransactions, warmedSources, bytes323, MEMO_BATCH_MAX, MEMO_ATTEMPTS, MEMO_MAX_WAIT_SECONDS, MEMO_ANSWER_TIMEOUT_MS, MEMO_BODY_TIMEOUT_MS, pauseFor, noticeOnStderr, memoDigestHex, memoFailureText, prefetchedMemosByFetch, MEMO_PREFETCH_LIFE_MS;
50575
50622
  var init_chain2 = __esm({
50576
50623
  "wallet/src/chain.mjs"() {
50577
50624
  "use strict";
50578
50625
  import_web395 = __toESM(require_index_cjs(), 1);
50579
50626
  init_esm2();
50580
50627
  init_proxy();
50628
+ init_keepAlive();
50581
50629
  init_compressedReplay();
50582
50630
  init_reference2();
50583
50631
  init_anchorClock();
@@ -50660,6 +50708,8 @@ var init_chain2 = __esm({
50660
50708
  historyRpcErrors = /* @__PURE__ */ new WeakSet();
50661
50709
  HISTORY_RPC_BEHIND_WAIT_MS = 6e4;
50662
50710
  HISTORY_RPC_REQUEST_TIMEOUT_MS = 2e4;
50711
+ HISTORY_RPC_BEHIND_FAST_MS = 150;
50712
+ HISTORY_RPC_BEHIND_FAST_TRIES = 12;
50663
50713
  HISTORY_RPC_BEHIND_RETRY_STEPS_MS = Object.freeze([500, 1e3, 2e3, 5e3]);
50664
50714
  HISTORY_RPC_BEHIND_CODE = -32016;
50665
50715
  ED25519_SPKI_PREFIX = Buffer.from("302a300506032b6570032100", "hex");
@@ -52614,11 +52664,11 @@ async function refreshFinalizedP03HistorySnapshot({
52614
52664
  if (authenticated.programId !== program.toBase58() || authenticated.pool !== poolKey.toBase58()) {
52615
52665
  throw new Error("p03_history_refresh_binding_invalid");
52616
52666
  }
52617
- const snapshot = await readFinalizedPool(connection, program, poolKey);
52618
- if (snapshot.terminal !== authenticated.finalizedPoolSnapshot.terminal || snapshot.currentIndex !== authenticated.finalizedPoolSnapshot.currentIndex || snapshot.currentRoot !== authenticated.finalizedPoolSnapshot.currentRoot || !sameP03PoolPolicy(snapshot, authenticated.finalizedPoolSnapshot.policy) || !sameE1Tree(snapshot, authenticated.finalizedPoolSnapshot.e1Tree)) {
52667
+ const snapshot = await readFinalizedPoolForRefresh(connection, program, poolKey);
52668
+ 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)) {
52619
52669
  throw Object.assign(
52620
52670
  new Error("p03_history_refresh_transition_detected"),
52621
- { snapshot, snapshotBinding: { programId: program.toBase58(), pool: poolKey.toBase58() } }
52671
+ { currentIndex: snapshot.currentIndex, snapshotBinding: { programId: program.toBase58(), pool: poolKey.toBase58() } }
52622
52672
  );
52623
52673
  }
52624
52674
  const priorCoverage = authenticated.deploymentCoverage;
@@ -52704,6 +52754,27 @@ async function readFinalizedPool(connection, program, pool2) {
52704
52754
  })
52705
52755
  });
52706
52756
  }
52757
+ async function readFinalizedPoolForRefresh(connection, program, pool2) {
52758
+ if (typeof connection.getMultipleAccountsInfoAndContext !== "function") return readFinalizedPool(connection, program, pool2);
52759
+ const tree = new import_web396.PublicKey(e1TreeAddress(pool2.toBase58(), program.toBase58()));
52760
+ const both = await retryTransientRpc(() => connection.getMultipleAccountsInfoAndContext(
52761
+ [pool2, tree],
52762
+ { commitment: "finalized", dataSlice: { offset: 0, length: REFRESH_READ_BYTES } }
52763
+ ));
52764
+ if (!Array.isArray(both?.value) || both.value.length !== 2) throw new Error("p03_history_e1_tree_read_invalid");
52765
+ if (both.value[0]?.data && Buffer.from(both.value[0].data).length >= REFRESH_READ_BYTES) return readFinalizedPool(connection, program, pool2);
52766
+ const snapshot = parseFinalizedPool({ context: both.context, value: both.value[0] }, program);
52767
+ if (snapshot.replayStore !== REPLAY_STORE_INDEXED) return snapshot;
52768
+ const treeAccount = both.value[1];
52769
+ return Object.freeze({
52770
+ ...snapshot,
52771
+ e1TreeHeader: Object.freeze({
52772
+ address: tree.toBase58(),
52773
+ ownerProgramId: treeAccount ? canonicalKey(treeAccount.owner, "e1_tree_owner").toBase58() : null,
52774
+ data: treeAccount ? Buffer.from(treeAccount.data) : null
52775
+ })
52776
+ });
52777
+ }
52707
52778
  function parseFinalizedPool(response, program) {
52708
52779
  const value = response?.value;
52709
52780
  const slot3 = response?.context?.slot;
@@ -53250,20 +53321,26 @@ async function retryTransientRpc(operation, {
53250
53321
  attempts = TRANSIENT_RPC_ATTEMPTS,
53251
53322
  baseDelayMs = TRANSIENT_RPC_BASE_DELAY_MS
53252
53323
  } = {}) {
53253
- let lastError;
53254
- for (let attempt = 0; attempt < attempts; attempt += 1) {
53324
+ const budgetMs = baseDelayMs * (2 ** Math.max(0, attempts - 1) - 1);
53325
+ let waitedMs = 0;
53326
+ let transportRetries = 0;
53327
+ let laggingRetries = 0;
53328
+ for (; ; ) {
53255
53329
  try {
53256
53330
  return await operation();
53257
53331
  } catch (error) {
53258
53332
  if (!isTransientRpcError(error)) throw error;
53259
- lastError = error;
53333
+ if (error?.code === -32016 && historyRpcFailed(error)) throw error;
53260
53334
  markPhase(`rpc-retry-${transientCause(error)}`);
53261
- if (attempt + 1 < attempts) {
53262
- await new Promise((resolve38) => setTimeout(resolve38, baseDelayMs * 2 ** attempt));
53263
- }
53335
+ const lagging = error instanceof import_web396.SolanaJSONRPCError && LAGGING_NODE_RPC_CODES.has(error.code);
53336
+ const delayMs = lagging ? baseDelayMs * LAGGING_NODE_STEP_OF_BASE : baseDelayMs * 2 ** transportRetries;
53337
+ if (waitedMs + delayMs > budgetMs || lagging && laggingRetries >= LAGGING_NODE_MAX_RETRIES) throw error;
53338
+ if (lagging) laggingRetries += 1;
53339
+ else transportRetries += 1;
53340
+ waitedMs += delayMs;
53341
+ await new Promise((resolve38) => setTimeout(resolve38, delayMs));
53264
53342
  }
53265
53343
  }
53266
- throw lastError;
53267
53344
  }
53268
53345
  function reuseRefusalCause(error) {
53269
53346
  const message = String(error?.message ?? error);
@@ -53424,19 +53501,16 @@ function assertP03E1TreeComplete({ program, pool: pool2, poolSnapshot, settles,
53424
53501
  if (Buffer.from(header.root).toString("hex") !== root) mismatch("root");
53425
53502
  return Object.freeze({ state: "open", address: tree.address, slot: BigInt(poolSnapshot.slot), root, leaves });
53426
53503
  }
53427
- function sameE1Tree(snapshot, verified) {
53504
+ function sameE1TreeHeader(snapshot, verified, program, pool2) {
53428
53505
  if (verified === void 0) return snapshot.replayStore !== REPLAY_STORE_INDEXED;
53429
- const tree = snapshot.e1TreeAccount;
53506
+ const tree = snapshot.e1TreeHeader;
53430
53507
  if (!tree || tree.address !== verified.address) return false;
53431
53508
  const empty = tree.data === null || tree.ownerProgramId === null || tree.ownerProgramId === SYSTEM_PROGRAM && tree.data.every((byte) => byte === 0);
53432
53509
  if (verified.state === "closed") return empty;
53433
- if (empty || tree.data.length !== E1.treeBytes) return false;
53434
- try {
53435
- const header = readE1TreeAccount(tree.data);
53436
- return header.leaves === verified.leaves && Buffer.from(header.root).toString("hex") === verified.root;
53437
- } catch {
53438
- return false;
53439
- }
53510
+ if (empty || tree.ownerProgramId !== program.toBase58() || tree.data.length < E1_TREE_HEADER_BYTES || !Number.isSafeInteger(verified.leaves) || verified.leaves < 1) return false;
53511
+ const data = tree.data;
53512
+ if (data.subarray(0, 8).toString("latin1") !== "SX402T01" || !data.subarray(8, 40).equals(pool2.toBuffer()) || data[40] !== 1 || data[41] !== E1.depth || data.readUInt16LE(42) !== E1.bufferSize || data[44] !== E1.canopyDepth || data[45] !== 0 || data[46] !== 0 || data[47] !== 0) return false;
53513
+ return data.readBigUInt64LE(56) === BigInt(2 * verified.leaves - 1);
53440
53514
  }
53441
53515
  function assertIndexedSettlementCpis(cpis, kind) {
53442
53516
  const exit = kind === "withdraw" || kind === "note-exit";
@@ -54212,7 +54286,7 @@ function base58Decode(value) {
54212
54286
  while (zeros < value.length && value[zeros] === "1") zeros += 1;
54213
54287
  return Uint8Array.from(Buffer.concat([Buffer.alloc(zeros), body]));
54214
54288
  }
54215
- var import_web396, REPLAY_STORE_INDEXED, CLOSE_REPLAY_TREE_TAG, EXTEND_ANCHOR_RING_TAG, 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, reviewedExecutables, isProgramDataIdentityError, ASSUMED_ORIGINAL_EXECUTABLE, AUTHENTICATED_HISTORY_REPORTS, HISTORY_ATTESTATIONS, 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, HISTORY_FETCH_CONCURRENCY, HISTORY_BULK_TRANSACTIONS, HISTORY_BULK_ADDRESSES, TRANSIENT_RPC_ATTEMPTS, TRANSIENT_RPC_BASE_DELAY_MS, LAGGING_NODE_RPC_CODES;
54289
+ var import_web396, REPLAY_STORE_INDEXED, CLOSE_REPLAY_TREE_TAG, EXTEND_ANCHOR_RING_TAG, 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, reviewedExecutables, isProgramDataIdentityError, ASSUMED_ORIGINAL_EXECUTABLE, AUTHENTICATED_HISTORY_REPORTS, HISTORY_ATTESTATIONS, 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, 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_RPC_CODES;
54216
54290
  var init_walk = __esm({
54217
54291
  "wallet/src/history/walk.mjs"() {
54218
54292
  "use strict";
@@ -54448,11 +54522,15 @@ var init_walk = __esm({
54448
54522
  P03_INLINE_SETTLEMENT_TAGS = Object.freeze([24, 25, 26, 32]);
54449
54523
  P03_PAYMENT_REPLAY_INDICES = PROFILES[4].replayIndices;
54450
54524
  NO_CONTEXTS = Object.freeze([]);
54525
+ REFRESH_READ_BYTES = 4096;
54526
+ E1_TREE_HEADER_BYTES = 80;
54451
54527
  HISTORY_FETCH_CONCURRENCY = 4;
54452
54528
  HISTORY_BULK_TRANSACTIONS = 256;
54453
54529
  HISTORY_BULK_ADDRESSES = 256;
54454
54530
  TRANSIENT_RPC_ATTEMPTS = 6;
54455
54531
  TRANSIENT_RPC_BASE_DELAY_MS = 250;
54532
+ LAGGING_NODE_STEP_OF_BASE = 1.6;
54533
+ LAGGING_NODE_MAX_RETRIES = 10;
54456
54534
  LAGGING_NODE_RPC_CODES = /* @__PURE__ */ new Set([-32004, -32016]);
54457
54535
  }
54458
54536
  });
@@ -55363,10 +55441,15 @@ async function readCompactP03History({
55363
55441
  // it verified. Both are bound again below like served ones.
55364
55442
  served,
55365
55443
  initialization: knownInitialization,
55366
- // walletHistory.mjs: the finalized pool account (readFinalizedPool) that a refresh read on this
55367
- // same own RPC moments ago and refused as moved (p03_history_refresh_transition_detected
55368
- // carries it). Folded to instead of a second read of the pool account, and the page request
55369
- // starts at once unless the cached records already reach its index.
55444
+ // walletHistory.mjs: the pool's current index that a refresh read on this same own RPC moments
55445
+ // ago and refused as moved (p03_history_refresh_transition_detected carries it; that read held
55446
+ // only the tree's header). The page request starts at once, beside the pool account read below,
55447
+ // unless the cached records already reach that index.
55448
+ knownIndex,
55449
+ // walletHistory.mjs compactFirst: the full pool account (readFinalizedPool, tree included) that
55450
+ // an earlier try of this same load read and folded nothing to because the source was behind
55451
+ // (p03_compact_history_source_behind carries it as behindSnapshot). Folded to again instead of
55452
+ // a second read of the pool account and its 386 KB tree; every check below runs on it as before.
55370
55453
  knownSnapshot,
55371
55454
  // compactP03HistoryReport: run beside the spot checks once the initialization is verified
55372
55455
  // ({ snapshot, initialization, contexts }); its result comes back as `alongside`.
@@ -55386,8 +55469,9 @@ async function readCompactP03History({
55386
55469
  throw refuse3("p03_compact_history_connection_invalid");
55387
55470
  }
55388
55471
  own = withBoundedOwnReads(own);
55389
- const cachedReachesKnown = knownSnapshot !== void 0 && served !== void 0 && Array.isArray(served.records) && Boolean(served.initialization) && BigInt(served.records.length) * SUBTREE_LEAVES3 >= knownSnapshot.currentIndex;
55390
- const first = served === void 0 || knownSnapshot !== void 0 && !cachedReachesKnown ? requestPage(source, poolString, 0) : void 0;
55472
+ const hintIndex = knownSnapshot?.currentIndex ?? knownIndex;
55473
+ const cachedReachesKnown = hintIndex !== void 0 && served !== void 0 && Array.isArray(served.records) && Boolean(served.initialization) && BigInt(served.records.length) * SUBTREE_LEAVES3 >= hintIndex;
55474
+ const first = served === void 0 || hintIndex !== void 0 && !cachedReachesKnown ? requestPage(source, poolString, 0) : void 0;
55391
55475
  if (first !== void 0) markPhase("compact-page0-sent");
55392
55476
  const snapshot = knownSnapshot ?? await readFinalizedPool(own, program, poolKey);
55393
55477
  markPhase(knownSnapshot !== void 0 ? "compact-pool-reused" : "compact-pool");
@@ -55402,7 +55486,10 @@ async function readCompactP03History({
55402
55486
  initialization: served.initialization,
55403
55487
  syncedSlot: served.syncedSlot,
55404
55488
  cached: true
55405
- } : await readPages(source, poolString, count2, first, { wakeSlot: snapshot.slot });
55489
+ } : await readPages(source, poolString, count2, first, { wakeSlot: snapshot.slot }).catch((error) => {
55490
+ if (error?.compactHistoryRefusal === "p03_compact_history_source_behind") error.behindSnapshot = snapshot;
55491
+ throw error;
55492
+ });
55406
55493
  markPhase(page.cached === true ? "compact-list-cached" : "compact-list");
55407
55494
  const binding = {
55408
55495
  programId: programString,
@@ -55527,6 +55614,7 @@ async function compactP03HistoryReport({
55527
55614
  forceRead = false,
55528
55615
  freshMs = 0,
55529
55616
  priorAttestation,
55617
+ knownIndex,
55530
55618
  knownSnapshot,
55531
55619
  onList
55532
55620
  }) {
@@ -55596,6 +55684,7 @@ async function compactP03HistoryReport({
55596
55684
  programId,
55597
55685
  pool: pool2,
55598
55686
  alongside: attest,
55687
+ ...knownIndex !== void 0 ? { knownIndex } : {},
55599
55688
  ...knownSnapshot !== void 0 ? { knownSnapshot } : {},
55600
55689
  ...onList !== void 0 ? { onList } : {},
55601
55690
  ...warm ? { served: cached.served } : {},
@@ -56370,19 +56459,26 @@ async function loadWalletP03HistoryNow({ store, connection: given, programId, po
56370
56459
  const runKey = lastRunReportKey(store, programId, pool2, deploymentIdentity, cache);
56371
56460
  const remembered = runKey === void 0 || forceRead ? void 0 : lastRunReports.get(runKey);
56372
56461
  const earlier = remembered !== void 0 && Date.now() - remembered.at <= HISTORY_WARM_FRESH_MS ? remembered.report : void 0;
56373
- let movedSnapshot;
56462
+ let movedIndex;
56374
56463
  if (earlier !== void 0) {
56375
56464
  markPhase("refresh-start");
56465
+ const refreshing = refreshFinalizedP03HistorySnapshot({ connection, programId, pool: pool2, history: earlier });
56466
+ if (typeof onCompactList === "function" && Array.isArray(earlier.contexts)) {
56467
+ try {
56468
+ onCompactList(earlier.contexts);
56469
+ } catch {
56470
+ }
56471
+ }
56376
56472
  try {
56377
- const refreshed = await refreshFinalizedP03HistorySnapshot({ connection, programId, pool: pool2, history: earlier });
56473
+ const refreshed = await refreshing;
56378
56474
  markPhase("walk-refreshed");
56379
56475
  rememberRunReport(runKey, refreshed);
56380
56476
  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");
56381
56477
  return refreshed;
56382
56478
  } catch (error) {
56383
56479
  markPhase("refresh-missed");
56384
- if (error?.message === "p03_history_refresh_transition_detected" && error.snapshot && error.snapshotBinding?.programId === String(programId) && error.snapshotBinding?.pool === String(pool2)) {
56385
- movedSnapshot = error.snapshot;
56480
+ if (error?.message === "p03_history_refresh_transition_detected" && typeof error.currentIndex === "bigint" && error.snapshotBinding?.programId === String(programId) && error.snapshotBinding?.pool === String(pool2)) {
56481
+ movedIndex = error.currentIndex;
56386
56482
  }
56387
56483
  floor?.reset();
56388
56484
  if (strict) floor?.strict();
@@ -56397,7 +56493,7 @@ async function loadWalletP03HistoryNow({ store, connection: given, programId, po
56397
56493
  pool: pool2,
56398
56494
  deploymentIdentity,
56399
56495
  forceRead,
56400
- knownSnapshot: movedSnapshot,
56496
+ knownIndex: movedIndex,
56401
56497
  onCompactList
56402
56498
  });
56403
56499
  if (compact !== void 0) {
@@ -56439,7 +56535,7 @@ async function loadWalletP03HistoryNow({ store, connection: given, programId, po
56439
56535
  if (runKey !== void 0) rememberRunReport(runKey, result.report);
56440
56536
  return result.report;
56441
56537
  }
56442
- async function compactFirst({ store, connection, source, programId, pool: pool2, deploymentIdentity, forceRead, knownSnapshot, onCompactList }) {
56538
+ async function compactFirst({ store, connection, source, programId, pool: pool2, deploymentIdentity, forceRead, knownIndex, onCompactList }) {
56443
56539
  const started = Date.now();
56444
56540
  let behindNoticed = false;
56445
56541
  let behindTries = 0;
@@ -56463,8 +56559,9 @@ async function compactFirst({ store, connection, source, programId, pool: pool2,
56463
56559
  }
56464
56560
  }
56465
56561
  };
56562
+ let behindSnapshot;
56466
56563
  for (let tries = 0; ; tries += 1) {
56467
- const result = await tryCompactP03HistoryReport(tries === 0 && knownSnapshot !== void 0 ? { ...options, knownSnapshot } : options);
56564
+ const result = await tryCompactP03HistoryReport(behindSnapshot !== void 0 ? { ...options, knownSnapshot: behindSnapshot } : tries === 0 && knownIndex !== void 0 ? { ...options, knownIndex } : options);
56468
56565
  if (result.ok) {
56469
56566
  markPhase("walk-compact");
56470
56567
  const who = source === "pinned" ? "the pinned history proxy" : "--history-rpc";
@@ -56478,12 +56575,13 @@ async function compactFirst({ store, connection, source, programId, pool: pool2,
56478
56575
  if (result.reason === "p03_compact_history_source_behind" && Date.now() - started + behindDelay <= HISTORY_RPC_BEHIND_WAIT_MS) {
56479
56576
  if (!behindNoticed) {
56480
56577
  behindNoticed = true;
56481
- writeStderr(`history: the history proxy has fewer transitions than the pool account your own RPC read (it is behind the chain); asking it again after 0.5 s, 1 s, 2 s, then every 5 s, for at most ${HISTORY_RPC_BEHIND_WAIT_MS / 1e3} s
56578
+ writeStderr(`history: the history proxy has fewer transitions than the pool account your own RPC read (it is behind the chain); asking it again the first time as soon as it reaches that slot (checked every 0.15 s) or after 0.5 s, then after 1 s, 2 s, then every 5 s, for at most ${HISTORY_RPC_BEHIND_WAIT_MS / 1e3} s
56482
56579
  `);
56483
56580
  }
56484
56581
  markPhase("compact-behind-wait");
56485
56582
  behindTries += 1;
56486
- await new Promise((resolve38) => setTimeout(resolve38, behindDelay));
56583
+ behindSnapshot = result.error?.behindSnapshot;
56584
+ await waitForCompactSource(options.history, pool2, behindTries === 1 ? behindSnapshot?.slot : void 0, behindDelay);
56487
56585
  continue;
56488
56586
  }
56489
56587
  writeStderr(`history: the compact transition list was refused (${result.reason}${result.detail ? `; cause ${result.detail}` : ""}); walking the pool history instead
@@ -56491,6 +56589,30 @@ async function compactFirst({ store, connection, source, programId, pool: pool2,
56491
56589
  return void 0;
56492
56590
  }
56493
56591
  }
56592
+ async function waitForCompactSource(source, pool2, slot3, budgetMs) {
56593
+ const sleep5 = (ms) => new Promise((resolve38) => setTimeout(resolve38, ms));
56594
+ if (!Number.isSafeInteger(slot3) || typeof source?._rpcRequest !== "function") return sleep5(budgetMs);
56595
+ const until = Date.now() + budgetMs;
56596
+ for (; ; ) {
56597
+ const abort = new AbortController();
56598
+ const params = [pool2, { commitment: "finalized", fromOrdinal: 0, toOrdinal: 1, minContextSlot: slot3 }];
56599
+ const read = (typeof source.abortableRpcRequest === "function" ? source.abortableRpcRequest("getP03Transitions", params, abort.signal) : source._rpcRequest("getP03Transitions", params)).catch(() => ({ failed: true }));
56600
+ let timer;
56601
+ const answer = await Promise.race([read, new Promise((resolve38) => {
56602
+ timer = setTimeout(resolve38, Math.max(COMPACT_BEHIND_READ_MS, until - Date.now()));
56603
+ })]);
56604
+ clearTimeout(timer);
56605
+ if (answer === void 0) abort.abort();
56606
+ if (answer?.result !== void 0) {
56607
+ markPhase("compact-behind-caught-up");
56608
+ return void 0;
56609
+ }
56610
+ if (answer !== void 0 && answer?.error?.code !== -32016) return sleep5(Math.max(0, until - Date.now()));
56611
+ const left = until - Date.now();
56612
+ if (left <= 0) return void 0;
56613
+ await sleep5(Math.min(COMPACT_BEHIND_POLL_MS, left));
56614
+ }
56615
+ }
56494
56616
  function lastRunReportKey(store, programId, pool2, deploymentIdentity, cache) {
56495
56617
  if (cache !== void 0 || !store || typeof store !== "object" || !deploymentIdentity) return void 0;
56496
56618
  if (typeof store.path !== "string" || store.path.length === 0) return void 0;
@@ -56540,7 +56662,7 @@ function reportHistoryRpc(split5, source, result, crossChecked) {
56540
56662
  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}
56541
56663
  `);
56542
56664
  }
56543
- var strictScope, withStrictHistorySource, recentScope, withRecentWalletHistory, recentLoads, forgetRecentWalletHistory, historyCacheKey, HISTORY_PREWARM_JOIN_MS, prewarmedWalks, PREWARMED_REPORTS, isPrewarmedWalletHistory, COMPACT_BEHIND_RETRY_MS, lastRunReports, writeStderr, announcedSources;
56665
+ var strictScope, withStrictHistorySource, recentScope, withRecentWalletHistory, recentLoads, forgetRecentWalletHistory, historyCacheKey, HISTORY_PREWARM_JOIN_MS, prewarmedWalks, PREWARMED_REPORTS, isPrewarmedWalletHistory, COMPACT_BEHIND_POLL_MS, COMPACT_BEHIND_READ_MS, COMPACT_BEHIND_RETRY_MS, lastRunReports, writeStderr, announcedSources;
56544
56666
  var init_walletHistory = __esm({
56545
56667
  "wallet/src/history/walletHistory.mjs"() {
56546
56668
  "use strict";
@@ -56565,6 +56687,8 @@ var init_walletHistory = __esm({
56565
56687
  prewarmedWalks = /* @__PURE__ */ new Map();
56566
56688
  PREWARMED_REPORTS = /* @__PURE__ */ new WeakSet();
56567
56689
  isPrewarmedWalletHistory = (report) => report !== null && typeof report === "object" && PREWARMED_REPORTS.has(report);
56690
+ COMPACT_BEHIND_POLL_MS = 150;
56691
+ COMPACT_BEHIND_READ_MS = 1e3;
56568
56692
  COMPACT_BEHIND_RETRY_MS = [500, 1e3, 2e3, 5e3];
56569
56693
  lastRunReports = /* @__PURE__ */ new Map();
56570
56694
  writeStderr = (text3) => {
@@ -59915,6 +60039,12 @@ function workerCount() {
59915
60039
  }
59916
60040
  return Math.max(1, Math.min(MAX_WORKERS, cores - 1));
59917
60041
  }
60042
+ function warmMemoDecryptPool() {
60043
+ try {
60044
+ workers();
60045
+ } catch {
60046
+ }
60047
+ }
59918
60048
  function workers() {
59919
60049
  if (pool !== void 0) return pool.broken ? void 0 : pool;
59920
60050
  pool = { list: [], pending: /* @__PURE__ */ new Map(), broken: false };
@@ -60205,15 +60335,28 @@ var init_successorHistories = __esm({
60205
60335
  });
60206
60336
 
60207
60337
  // wallet/src/recovery/recover.mjs
60338
+ import { createHash as createHash15 } from "node:crypto";
60208
60339
  import { join as join10, resolve as resolve10 } from "node:path";
60209
60340
  import { fileURLToPath as fileURLToPath5 } from "node:url";
60210
60341
  function pinnedGenerator2(profileVector) {
60211
60342
  if (profileVector?.payerKeys?.generator) return profileVector.payerKeys.generator;
60212
- const committed2 = JSON.parse(readFileSync(
60213
- join10(MODEL_DIR, "vectors", "rust-vectors.json"),
60214
- "utf8"
60215
- ));
60216
- return committed2.payerKeys.generator;
60343
+ if (!committedGenerator) {
60344
+ const committed2 = JSON.parse(readFileSync(
60345
+ join10(MODEL_DIR, "vectors", "rust-vectors.json"),
60346
+ "utf8"
60347
+ ));
60348
+ committedGenerator = Object.freeze(committed2.payerKeys.generator);
60349
+ }
60350
+ return committedGenerator;
60351
+ }
60352
+ function replayValueOf(kind, poolDomain, commitment, eta, leafIndex) {
60353
+ const key = createHash15("sha256").update(kind === "account" ? `account|${String(commitment)}|${String(eta)}|${String(leafIndex)}` : `note|${String(poolDomain)}|${String(commitment)}|${String(eta)}|${String(leafIndex)}`).digest("base64");
60354
+ const known = REPLAY_VALUES.get(key);
60355
+ if (known !== void 0) return known;
60356
+ const value = kind === "account" ? accountNullifier(commitment, eta, leafIndex) : noteNullifier2(poolDomain, commitment, eta, leafIndex);
60357
+ if (REPLAY_VALUES.size >= REPLAY_VALUES_MAX) REPLAY_VALUES.clear();
60358
+ REPLAY_VALUES.set(key, value);
60359
+ return value;
60217
60360
  }
60218
60361
  function assertFinalizedRecoveryContext(context, digest2, programId, pool2) {
60219
60362
  const kinds = Object.freeze({ deposit: 1, payment: 2, withdraw: 3, "note-exit": 4, move: 5 });
@@ -60320,7 +60463,9 @@ async function syncedOutputs({ store, finalizedHistory: finalizedHistory2, diges
60320
60463
  if (!serviceUrl2) {
60321
60464
  throw new Error(`p03_memo_service_required: ${pending.length} transitions this wallet has not read come from the memo service; rerun with --service <facilitator URL>`);
60322
60465
  }
60323
- const wal = fresh ? /* @__PURE__ */ new Map() : walMemoBundles(store);
60466
+ if (!fresh) store.listWal();
60467
+ let wal;
60468
+ const walFor = () => wal ??= fresh ? /* @__PURE__ */ new Map() : walMemoBundles(store);
60324
60469
  const reader = deps.memoReader ?? createMemoReader(serviceUrl2, { fetchImpl: deps.fetchImpl ?? fetch, ...deps.pause ? { pause: deps.pause } : {} });
60325
60470
  (deps.notice ?? ((text3) => process.stderr.write(text3)))(
60326
60471
  `reading ${pending.length} memos from the memo service, ${Math.ceil(pending.length / MEMO_BATCH_MAX)} request(s)
@@ -60340,7 +60485,7 @@ async function syncedOutputs({ store, finalizedHistory: finalizedHistory2, diges
60340
60485
  for (const context of chunk) {
60341
60486
  const digest2 = hexOf2(context.memoDigest);
60342
60487
  const fromService = served.get(digest2);
60343
- const bytes2 = fromService ?? wal.get(digest2);
60488
+ const bytes2 = fromService ?? walFor().get(digest2);
60344
60489
  if (!bytes2) {
60345
60490
  absent2 += 1;
60346
60491
  continue;
@@ -60401,6 +60546,7 @@ function prefetchRecoveryMemos({ store, finalizedHistory: finalizedHistory2, ser
60401
60546
  if (pending.length === 0) return;
60402
60547
  createMemoReader(serviceUrl2, { fetchImpl: deps.fetchImpl ?? fetch, notice: () => {
60403
60548
  } }).prefetch(pending);
60549
+ warmMemoDecryptPool();
60404
60550
  } catch {
60405
60551
  }
60406
60552
  }
@@ -60493,7 +60639,13 @@ async function runRecover({ store, connection, programId, digests, serviceUrl: s
60493
60639
  const recovered = [];
60494
60640
  for (const { digest: digest2, context, outputs } of read.entries) {
60495
60641
  for (const output2 of outputs) {
60496
- const replayValue = output2.kind === "account" ? accountNullifier(output2.commitment, viewingAuthority.eta, output2.leafIndex) : noteNullifier2(context.poolDomain, output2.commitment, viewingAuthority.eta, output2.leafIndex);
60642
+ const replayValue = replayValueOf(
60643
+ output2.kind,
60644
+ context.poolDomain,
60645
+ output2.commitment,
60646
+ viewingAuthority.eta,
60647
+ output2.leafIndex
60648
+ );
60497
60649
  recovered.push({ ...output2, digest: digest2, replayValue });
60498
60650
  }
60499
60651
  }
@@ -60528,7 +60680,7 @@ async function runRecover({ store, connection, programId, digests, serviceUrl: s
60528
60680
  ...Array.isArray(digests) && digests.length > 0 ? { narrowedByDigests: true } : {}
60529
60681
  };
60530
60682
  }
60531
- var import_web3102, FIELD_MODULUS6, MODEL_DIR, seedBytes3, hexOf2;
60683
+ var import_web3102, FIELD_MODULUS6, MODEL_DIR, seedBytes3, committedGenerator, REPLAY_VALUES, REPLAY_VALUES_MAX, hexOf2;
60532
60684
  var init_recover = __esm({
60533
60685
  "wallet/src/recovery/recover.mjs"() {
60534
60686
  "use strict";
@@ -60548,6 +60700,8 @@ var init_recover = __esm({
60548
60700
  fileURLToPath5(new URL("../../vendor/shielded-x402-model/", new URL("__bundled_source__/wallet/src/recovery/recover.mjs", import.meta.url).href))
60549
60701
  );
60550
60702
  seedBytes3 = (state) => Uint8Array.from(Buffer.from(state.seedHex, "hex"));
60703
+ REPLAY_VALUES = /* @__PURE__ */ new Map();
60704
+ REPLAY_VALUES_MAX = 5e4;
60551
60705
  hexOf2 = (value) => String(value).replace(/^0x/, "").toLowerCase();
60552
60706
  }
60553
60707
  });
@@ -68288,14 +68442,14 @@ var init_solana_ed255192 = __esm({
68288
68442
  });
68289
68443
 
68290
68444
  // spikes/shielded-x402-solana/scripts/verify-production-parameter-bundle.mjs
68291
- import { createHash as createHash15 } from "node:crypto";
68445
+ import { createHash as createHash16 } from "node:crypto";
68292
68446
  import { dirname as dirname12, isAbsolute as isAbsolute4, relative as relative5, resolve as resolve11 } from "node:path";
68293
68447
  import { fileURLToPath as fileURLToPath6 } from "node:url";
68294
68448
  function fail13(message) {
68295
68449
  throw new Error(`production parameter bundle rejected: ${message}`);
68296
68450
  }
68297
68451
  function sha2567(bytes2) {
68298
- return createHash15("sha256").update(bytes2).digest("hex");
68452
+ return createHash16("sha256").update(bytes2).digest("hex");
68299
68453
  }
68300
68454
  function assertHex2(value, bytes2, label) {
68301
68455
  if (typeof value !== "string" || !new RegExp(`^[0-9a-f]{${bytes2 * 2}}$`).test(value)) {
@@ -68769,7 +68923,7 @@ var init_production_proof_bundle2 = __esm({
68769
68923
 
68770
68924
  // spikes/shielded-x402-wallet/lib/p03-recovered-exit.mjs
68771
68925
  import { spawn as spawn3, spawnSync as spawnSync3 } from "node:child_process";
68772
- import { createHash as createHash16 } from "node:crypto";
68926
+ import { createHash as createHash17 } from "node:crypto";
68773
68927
  import { dirname as dirname13, isAbsolute as isAbsolute5, join as join11, relative as relative6, resolve as resolve13 } from "node:path";
68774
68928
  import { tmpdir as tmpdir2 } from "node:os";
68775
68929
  function fail14(reason) {
@@ -69170,7 +69324,7 @@ var init_p03_recovered_exit = __esm({
69170
69324
  init_pool_denomination();
69171
69325
  TOOLS_SCHEMA2 = "carbon-shielded-wallet/p03-public-proof-tools/v1";
69172
69326
  REQUEST_SCHEMA2 = "carbon-shielded-x402/p03-recovered-exit-request/v1";
69173
- sha2568 = (value) => createHash16("sha256").update(value).digest("hex");
69327
+ sha2568 = (value) => createHash17("sha256").update(value).digest("hex");
69174
69328
  jsonBytes2 = (value) => Buffer.from(`${JSON.stringify(value, null, 2)}
69175
69329
  `, "utf8");
69176
69330
  CHILD_MAX_BUFFER2 = 128 * 1024 * 1024;
@@ -69202,7 +69356,7 @@ var init_p03_recovered_exit = __esm({
69202
69356
  });
69203
69357
 
69204
69358
  // spikes/shielded-x402-wallet/bin/shielded-wallet.mjs
69205
- import { createHash as createHash17 } from "node:crypto";
69359
+ import { createHash as createHash18 } from "node:crypto";
69206
69360
  import { homedir } from "node:os";
69207
69361
  import { join as join12, resolve as resolve14 } from "node:path";
69208
69362
  import { fileURLToPath as fileURLToPath7 } from "node:url";
@@ -69689,7 +69843,7 @@ function contextHoldsPrimary(context, primaryHex) {
69689
69843
  const expected = contextPrimaryHex(context, primaryHex);
69690
69844
  if (expected === void 0) return false;
69691
69845
  if (context.primaryPayloadHex !== void 0) return context.primaryPayloadHex === expected;
69692
- return context.historySource === "compact" && typeof context.primaryPayloadSha256 === "string" && context.primaryPayloadSha256 === createHash17("sha256").update(Buffer.from(expected, "hex")).digest("hex");
69846
+ return context.historySource === "compact" && typeof context.primaryPayloadSha256 === "string" && context.primaryPayloadSha256 === createHash18("sha256").update(Buffer.from(expected, "hex")).digest("hex");
69693
69847
  }
69694
69848
  function releaseIfSpentByOtherPayment({ store, history, prior }) {
69695
69849
  const authenticated = assertAuthenticatedFinalizedP03History(history);
@@ -71272,7 +71426,7 @@ var init_poseidon_params_t_6 = __esm({
71272
71426
  });
71273
71427
 
71274
71428
  // src/server/payments/shielded/ShieldedSolanaP03QuoteCrypto.ts
71275
- import { createHash as createHash18 } from "node:crypto";
71429
+ import { createHash as createHash19 } from "node:crypto";
71276
71430
  function serializePinnedJson(value) {
71277
71431
  if (Array.isArray(value)) return `[${value.map(serializePinnedJson).join(", ")}]`;
71278
71432
  if (value !== null && typeof value === "object") {
@@ -71311,7 +71465,7 @@ function parseMatrix(value, rows, columns, label) {
71311
71465
  }
71312
71466
  function assertParameterArtifact(artifact, expected) {
71313
71467
  if (!isJsonValue(artifact)) throw new Error("p03_quote_crypto_parameter_artifact_invalid");
71314
- const digest2 = createHash18("sha256").update(serializePinnedJson(artifact)).digest("hex");
71468
+ const digest2 = createHash19("sha256").update(serializePinnedJson(artifact)).digest("hex");
71315
71469
  if (digest2 !== expected.sha256) throw new Error("p03_quote_crypto_parameter_hash_mismatch");
71316
71470
  if (!artifact || typeof artifact !== "object" || Array.isArray(artifact)) {
71317
71471
  throw new Error("p03_quote_crypto_parameter_shape_invalid");
@@ -71935,13 +72089,31 @@ function exitReservedNoteCommitments(store) {
71935
72089
  const selfPay2 = name.startsWith("self-pay-");
71936
72090
  if (!selfPay2 && !name.startsWith("note-exit-")) continue;
71937
72091
  if (name.startsWith("self-pay-merge-")) continue;
72092
+ const settledKey = selfPay2 ? void 0 : settledNoteExitKey(store, name);
72093
+ const before = settledKey === void 0 ? void 0 : walFileValidator(store, name);
72094
+ if (before !== void 0 && settledNoteExits.get(settledKey) === before) continue;
71938
72095
  const record = store.readWal(name);
72096
+ if (before !== void 0) {
72097
+ if (record?.state === "settled" && walFileValidator(store, name) === before) settledNoteExits.set(settledKey, before);
72098
+ else settledNoteExits.delete(settledKey);
72099
+ }
71939
72100
  const pending = selfPay2 ? record?.state === "paid" : ["selected", "proved", "confirmed"].includes(record?.state);
71940
72101
  if (!pending || typeof record?.noteCommitment !== "string" || !/^[0-9]{1,90}$/.test(record.noteCommitment)) continue;
71941
72102
  reserved.add(BigInt(record.noteCommitment).toString());
71942
72103
  }
71943
72104
  return reserved;
71944
72105
  }
72106
+ function settledNoteExitKey(store, name) {
72107
+ return typeof store?.walDirectory === "string" ? `${resolve15(store.walDirectory)}\0${name}` : void 0;
72108
+ }
72109
+ function walFileValidator(store, name) {
72110
+ try {
72111
+ const stat = statSync(join13(store.walDirectory, `${name}.json`), { bigint: true, throwIfNoEntry: false });
72112
+ return stat?.isFile() ? `${stat.ino}:${stat.size}:${stat.mtimeNs}:${stat.ctimeNs}` : void 0;
72113
+ } catch {
72114
+ return void 0;
72115
+ }
72116
+ }
71945
72117
  async function readFinalizedClock(connection) {
71946
72118
  const info = await connection.getAccountInfo(import_web3106.SYSVAR_CLOCK_PUBKEY, "finalized");
71947
72119
  const data = info?.data;
@@ -72319,7 +72491,7 @@ function assertProvedPaymentBinding(proved, { poolDomain, inputAccountCommitment
72319
72491
  fail15("proved_request_binding_invalid");
72320
72492
  }
72321
72493
  }
72322
- var import_web3106, MODEL_DIR3, seedBytes5, EARLY_CHAIN_TIME_MAX_AGE_MS;
72494
+ var import_web3106, MODEL_DIR3, seedBytes5, EARLY_CHAIN_TIME_MAX_AGE_MS, settledNoteExits;
72323
72495
  var init_prepareRecoveredPayment = __esm({
72324
72496
  "wallet/src/pay/prepareRecoveredPayment.mjs"() {
72325
72497
  "use strict";
@@ -72340,11 +72512,12 @@ var init_prepareRecoveredPayment = __esm({
72340
72512
  MODEL_DIR3 = resolve15(fileURLToPath8(new URL("../../vendor/shielded-x402-model/", new URL("__bundled_source__/wallet/src/pay/prepareRecoveredPayment.mjs", import.meta.url).href)));
72341
72513
  seedBytes5 = (state) => Uint8Array.from(Buffer.from(state.seedHex, "hex"));
72342
72514
  EARLY_CHAIN_TIME_MAX_AGE_MS = 3e4;
72515
+ settledNoteExits = /* @__PURE__ */ new Map();
72343
72516
  }
72344
72517
  });
72345
72518
 
72346
72519
  // wallet/src/pay/receiptTransaction.mjs
72347
- import { createHash as createHash19 } from "node:crypto";
72520
+ import { createHash as createHash20 } from "node:crypto";
72348
72521
  function sameQuoteCommitment(left, right) {
72349
72522
  const parse4 = (value) => {
72350
72523
  if (typeof value !== "string" || value.length > 77 || !/^(?:0|[1-9][0-9]*|0x[0-9a-f]{64})$/.test(value)) return void 0;
@@ -72368,7 +72541,7 @@ function contextPayloadMatches(context, payload2) {
72368
72541
  else fail16("receipt_history_proof_form_invalid");
72369
72542
  if (bytes2 === void 0) return false;
72370
72543
  if (context.primaryPayloadHex !== void 0) return context.primaryPayloadHex === bytes2.toString("hex");
72371
- return context.primaryPayloadSha256 === createHash19("sha256").update(bytes2).digest("hex");
72544
+ return context.primaryPayloadSha256 === createHash20("sha256").update(bytes2).digest("hex");
72372
72545
  }
72373
72546
  function submittedPayload(paymentHeader) {
72374
72547
  const payload2 = decodePaymentSignatureHeader(paymentHeader)?.payload;
@@ -91159,38 +91332,8 @@ var init_pay = __esm({
91159
91332
  }
91160
91333
  });
91161
91334
 
91162
- // wallet/src/fetch/keepAlive.mjs
91163
- function proxiedRun() {
91164
- const env = process.env;
91165
- return Boolean(env.SHINJUKU_WALLET_PROXIED || env.NODE_USE_ENV_PROXY || env.HTTPS_PROXY || env.HTTP_PROXY || env.https_proxy || env.http_proxy);
91166
- }
91167
- function keepAliveDispatcher() {
91168
- if (shared !== void 0) return shared;
91169
- try {
91170
- if (proxiedRun()) return void 0;
91171
- const global2 = globalThis[GLOBAL_DISPATCHER];
91172
- if (global2?.constructor?.name !== "Agent") return void 0;
91173
- shared = new global2.constructor({ keepAliveTimeout: KEEP_ALIVE_MS, keepAliveMaxTimeout: KEEP_ALIVE_MS });
91174
- return shared;
91175
- } catch {
91176
- return void 0;
91177
- }
91178
- }
91179
- function keepAliveInit(init = {}) {
91180
- const dispatcher = keepAliveDispatcher();
91181
- return dispatcher === void 0 ? init : { ...init, dispatcher };
91182
- }
91183
- var GLOBAL_DISPATCHER, KEEP_ALIVE_MS, shared;
91184
- var init_keepAlive = __esm({
91185
- "wallet/src/fetch/keepAlive.mjs"() {
91186
- "use strict";
91187
- GLOBAL_DISPATCHER = /* @__PURE__ */ Symbol.for("undici.globalDispatcher.1");
91188
- KEEP_ALIVE_MS = 2e4;
91189
- }
91190
- });
91191
-
91192
91335
  // wallet/src/pay/floatPay.mjs
91193
- import { createHash as createHash20, randomBytes as randomBytes11 } from "node:crypto";
91336
+ import { createHash as createHash21, randomBytes as randomBytes11 } from "node:crypto";
91194
91337
  import { fileURLToPath as fileURLToPath9 } from "node:url";
91195
91338
  function floatRecordOf(store, requestId) {
91196
91339
  try {
@@ -91380,7 +91523,7 @@ function canonicalBody({ requestId, resourceUrl, requirement, refundTo }) {
91380
91523
  const text3 = `{"requestId":${JSON.stringify(opaque)},"resourceUrl":${JSON.stringify(resourceUrl)},"requirement":${JSON.stringify(requirement)},"refundTo":${JSON.stringify(refundTo)}}`;
91381
91524
  const bytes2 = Buffer.from(text3, "utf8");
91382
91525
  if (bytes2.length > MAX_BODY_BYTES) fail18("p03_float_body_too_large");
91383
- return { bodyBase64: bytes2.toString("base64"), floatId: createHash20("sha256").update(bytes2).digest("hex") };
91526
+ return { bodyBase64: bytes2.toString("base64"), floatId: createHash21("sha256").update(bytes2).digest("hex") };
91384
91527
  }
91385
91528
  function floatAnswer(resultBase64, record, store) {
91386
91529
  let answer;
@@ -92106,6 +92249,7 @@ async function finalizePendingReceipt({ store, connection, programId, name, time
92106
92249
  const deadline = now() + timeoutMs;
92107
92250
  let gated = false;
92108
92251
  let strict = false;
92252
+ let gateClock;
92109
92253
  for (; ; ) {
92110
92254
  const record = store.readWal(name);
92111
92255
  if (!isPending(record)) return record;
@@ -92129,15 +92273,19 @@ async function finalizePendingReceipt({ store, connection, programId, name, time
92129
92273
  const answeredLongAgo = Number.isSafeInteger(record.answeredAtMs) && Date.now() - record.answeredAtMs >= FINALITY_GATE_SKIP_AFTER_MS;
92130
92274
  if (!answeredLongAgo) {
92131
92275
  strict = true;
92132
- const tip = (await finalizedClock(connection, "confirmed")).slot;
92133
- const target = tip > (await finalizedClock(connection)).slot ? tip + FINALITY_GATE_MARGIN_SLOTS : tip;
92134
- while ((await finalizedClock(connection)).slot < target && now() < deadline) {
92276
+ const [tipClock, finalClock] = await Promise.all([finalizedClock(connection, "confirmed"), finalizedClock(connection)]);
92277
+ const tip = tipClock.slot;
92278
+ const target = tip > finalClock.slot ? tip + FINALITY_GATE_MARGIN_SLOTS : tip;
92279
+ gateClock = finalClock;
92280
+ while (gateClock.slot < target && now() < deadline) {
92135
92281
  await sleep5(Math.min(pollMs, FINALITY_GATE_POLL_MS));
92282
+ gateClock = await finalizedClock(connection);
92136
92283
  }
92137
92284
  }
92138
92285
  markPhase("gate");
92139
92286
  }
92140
- const clock2 = await finalizedClock(connection);
92287
+ const clock2 = gateClock ?? await finalizedClock(connection);
92288
+ gateClock = void 0;
92141
92289
  const history = assertAuthenticatedFinalizedP03History(
92142
92290
  await (strict ? withStrictHistorySource(() => deps.walkHistory()) : deps.walkHistory())
92143
92291
  );
@@ -92848,7 +92996,7 @@ var init_payResource = __esm({
92848
92996
  });
92849
92997
 
92850
92998
  // wallet/src/pay/cli.mjs
92851
- import { createHash as createHash21 } from "node:crypto";
92999
+ import { createHash as createHash22 } from "node:crypto";
92852
93000
  import { resolve as resolve16 } from "node:path";
92853
93001
  import { fileURLToPath as fileURLToPath11 } from "node:url";
92854
93002
  async function main2(args = process.argv.slice(2)) {
@@ -92968,7 +93116,7 @@ function writePaidAnswer(path, resultBase64) {
92968
93116
  } catch {
92969
93117
  throw new Error("p03_resource_cli_out_unwritable_rerun_same_request");
92970
93118
  }
92971
- return { path, bytes: bytes2.length, sha256: createHash21("sha256").update(bytes2).digest("hex") };
93119
+ return { path, bytes: bytes2.length, sha256: createHash22("sha256").update(bytes2).digest("hex") };
92972
93120
  }
92973
93121
  function describeCliError(error, options = {}) {
92974
93122
  return describeError(error, { fallback: "p03_resource_cli_failed", nameUnknown: true, ...options });
@@ -94167,7 +94315,7 @@ var init_secp256k1 = __esm({
94167
94315
  });
94168
94316
 
94169
94317
  // src/server/storage/EncryptedJsonFile.ts
94170
- import { createCipheriv as createCipheriv3, createDecipheriv as createDecipheriv3, createHash as createHash23, randomBytes as randomBytes16 } from "node:crypto";
94318
+ import { createCipheriv as createCipheriv3, createDecipheriv as createDecipheriv3, createHash as createHash24, randomBytes as randomBytes16 } from "node:crypto";
94171
94319
  import { mkdir as mkdir3, open as open2, readFile as readFile4, rename as rename3, writeFile as writeFile2 } from "node:fs/promises";
94172
94320
  import { dirname as dirname18 } from "node:path";
94173
94321
  var EncryptedJsonFile, renameReplacing, renameReplacingSync, retryableWindowsRename, isEncryptedPayload, isMissingFile, isUnsupportedDirectorySync;
@@ -94293,7 +94441,7 @@ var init_EncryptedJsonFile = __esm({
94293
94441
  await pause3();
94294
94442
  }
94295
94443
  const text3 = parts.join("");
94296
- return { text: text3, sha256: createHash23("sha256").update(text3, "utf8").digest("hex") };
94444
+ return { text: text3, sha256: createHash24("sha256").update(text3, "utf8").digest("hex") };
94297
94445
  }
94298
94446
  const iv = randomBytes16(12);
94299
94447
  const cipher = createCipheriv3("aes-256-gcm", this.key(), iv);
@@ -94305,7 +94453,7 @@ var init_EncryptedJsonFile = __esm({
94305
94453
  sealed.push(cipher.final());
94306
94454
  const ciphertext = Buffer.concat(sealed);
94307
94455
  const head = `{"version":1,"algorithm":"aes-256-gcm","iv":"${iv.toString("base64")}","tag":"${cipher.getAuthTag().toString("base64")}","ciphertext":"`;
94308
- const hash12 = createHash23("sha256").update(head, "utf8");
94456
+ const hash12 = createHash24("sha256").update(head, "utf8");
94309
94457
  const encoded = [head];
94310
94458
  const window2 = 3 * 256 * 1024;
94311
94459
  for (let offset = 0; offset < ciphertext.length; offset += window2) {
@@ -94405,7 +94553,7 @@ var init_EncryptedJsonFile = __esm({
94405
94553
  if (decoded.length === 32) return decoded;
94406
94554
  } catch {
94407
94555
  }
94408
- return createHash23("sha256").update(value).digest();
94556
+ return createHash24("sha256").update(value).digest();
94409
94557
  }
94410
94558
  };
94411
94559
  renameReplacing = async (from, to) => {
@@ -94971,7 +95119,7 @@ var init_poseidon_params_t_3 = __esm({
94971
95119
  });
94972
95120
 
94973
95121
  // src/server/payments/shielded/ShieldedSolanaP03Poseidon.ts
94974
- import { createHash as createHash24 } from "node:crypto";
95122
+ import { createHash as createHash25 } from "node:crypto";
94975
95123
  function serializePinnedJson2(value) {
94976
95124
  if (Array.isArray(value)) return `[${value.map(serializePinnedJson2).join(", ")}]`;
94977
95125
  if (value !== null && typeof value === "object") {
@@ -95010,7 +95158,7 @@ function parseMatrix2(value, rows, columns, label) {
95010
95158
  }
95011
95159
  function assertShieldedSolanaP03PoseidonParameterArtifact(artifact) {
95012
95160
  if (!isJsonValue2(artifact)) throw new Error("p03_poseidon_parameter_artifact_invalid");
95013
- const digest2 = createHash24("sha256").update(serializePinnedJson2(artifact)).digest("hex");
95161
+ const digest2 = createHash25("sha256").update(serializePinnedJson2(artifact)).digest("hex");
95014
95162
  if (digest2 !== SHIELDED_SOLANA_P03_POSEIDON_PARAMETERS_SHA256) {
95015
95163
  throw new Error("p03_poseidon_parameter_hash_mismatch");
95016
95164
  }
@@ -95869,7 +96017,7 @@ var init_shieldedSellerAcceptance = __esm({
95869
96017
  });
95870
96018
 
95871
96019
  // wallet/src/seller/config.mjs
95872
- import { createHash as createHash25 } from "node:crypto";
96020
+ import { createHash as createHash26 } from "node:crypto";
95873
96021
  var import_web3119, fail26, sha2;
95874
96022
  var init_config = __esm({
95875
96023
  "wallet/src/seller/config.mjs"() {
@@ -95880,7 +96028,7 @@ var init_config = __esm({
95880
96028
  fail26 = (code) => {
95881
96029
  throw new Error(`p03_seller_${code}`);
95882
96030
  };
95883
- sha2 = (bytes2) => createHash25("sha256").update(bytes2).digest("hex");
96031
+ sha2 = (bytes2) => createHash26("sha256").update(bytes2).digest("hex");
95884
96032
  }
95885
96033
  });
95886
96034
 
@@ -112997,7 +113145,7 @@ __export(binding_exports, {
112997
113145
  commitmentsOpen: () => commitmentsOpen,
112998
113146
  transcript: () => transcript
112999
113147
  });
113000
- import { createHash as createHash31, randomBytes as randomBytes26 } from "node:crypto";
113148
+ import { createHash as createHash32, randomBytes as randomBytes26 } from "node:crypto";
113001
113149
  function transcript(t, contextCommitment, D5, T, cLo, cHi) {
113002
113150
  for (const [name, b] of [["programId", t.programId], ["pool", t.pool], ["mint", t.mint], ["vault", t.vault], ["counterparty", t.counterparty], ["T", T], ["C_lo", cLo], ["C_hi", cHi]]) {
113003
113151
  if (b.length !== 32) throw new Error(`transcript ${name} must be 32 bytes, got ${b.length}`);
@@ -113083,7 +113231,7 @@ var init_binding = __esm({
113083
113231
  bindCommitment = (v, k, rho) => sponge2([BIND_DOMAIN, v, k, rho]);
113084
113232
  TRANSCRIPT_LEN = 391;
113085
113233
  FORCED_TRANSCRIPT_LEN = 423;
113086
- challenge = (tr) => BigInt(`0x${createHash31("sha256").update(tr).digest().subarray(0, 24).toString("hex")}`);
113234
+ challenge = (tr) => BigInt(`0x${createHash32("sha256").update(tr).digest().subarray(0, 24).toString("hex")}`);
113087
113235
  }
113088
113236
  });
113089
113237
 
@@ -113666,7 +113814,7 @@ __export(witness_exports, {
113666
113814
  memoDigestHex: () => memoDigestHex2,
113667
113815
  treeAppendRequest: () => treeAppendRequest
113668
113816
  });
113669
- import { createHash as createHash32 } from "node:crypto";
113817
+ import { createHash as createHash33 } from "node:crypto";
113670
113818
  function depositRequest(p) {
113671
113819
  if (p.account.b !== p.bind.v || p.account.i !== 0n) throw new Error("a deposit account has b = v and i = 0");
113672
113820
  return {
@@ -113715,7 +113863,7 @@ var init_witness2 = __esm({
113715
113863
  WITNESS_SCHEMA = "carbon-shielded-x402/ctvault-v0b-witness/v1";
113716
113864
  dec = (x) => x.toString();
113717
113865
  acct = (a) => ({ d: dec(a.d), pDX: dec(a.pDX), i: dec(a.i), b: dec(a.b) });
113718
- memoDigestHex2 = (memo) => `0x${createHash32("sha256").update(memo, "utf8").digest("hex")}`;
113866
+ memoDigestHex2 = (memo) => `0x${createHash33("sha256").update(memo, "utf8").digest("hex")}`;
113719
113867
  bindFields = (b) => ({
113720
113868
  value: dec(b.v),
113721
113869
  blinding: dec(b.k),
@@ -114461,7 +114609,7 @@ var init_service2 = __esm({
114461
114609
  });
114462
114610
 
114463
114611
  // wallet/src/v0b/prover.mjs
114464
- import { createHash as createHash33 } from "node:crypto";
114612
+ import { createHash as createHash34 } from "node:crypto";
114465
114613
  import { join as join33, resolve as resolve32 } from "node:path";
114466
114614
  function parseParamsPins(text3) {
114467
114615
  const pins = {};
@@ -114576,7 +114724,7 @@ var init_prover2 = __esm({
114576
114724
  ExitCTV1: "carbon-shielded-exact/exit-ct-v1/CEREMONY-proof/v0b",
114577
114725
  TreeAppendV1: "carbon-shielded-exact/tree-append-v1/CEREMONY-proof/v0b"
114578
114726
  });
114579
- sha256File = (path) => createHash33("sha256").update(readFileSync(path)).digest("hex");
114727
+ sha256File = (path) => createHash34("sha256").update(readFileSync(path)).digest("hex");
114580
114728
  DEPOSIT_ORDER = spec_exports.DEPOSIT_CT_PUBLIC;
114581
114729
  EXIT_ORDER = spec_exports.EXIT_CT_PUBLIC;
114582
114730
  }
@@ -116239,7 +116387,7 @@ var init_lib2 = __esm({
116239
116387
  });
116240
116388
 
116241
116389
  // wallet/src/laneb/keys.mjs
116242
- import { createHash as createHash34, createHmac as createHmac9 } from "node:crypto";
116390
+ import { createHash as createHash35, createHmac as createHmac9 } from "node:crypto";
116243
116391
  function seedBytes7(state) {
116244
116392
  const seed = Buffer.from(String(state?.seedHex ?? ""), "hex");
116245
116393
  if (seed.length !== 32) fail50("seed_invalid");
@@ -116340,7 +116488,7 @@ var init_keys3 = __esm({
116340
116488
  }
116341
116489
  return out;
116342
116490
  };
116343
- sha5123 = (...parts) => createHash34("sha512").update(Buffer.concat(parts.map((part) => Buffer.from(part)))).digest();
116491
+ sha5123 = (...parts) => createHash35("sha512").update(Buffer.concat(parts.map((part) => Buffer.from(part)))).digest();
116344
116492
  hashToScalar = (...parts) => mod9(leToBig(sha5123(...parts)));
116345
116493
  nonZero = (scalar) => {
116346
116494
  if (scalar === 0n) fail50("degenerate_scalar");
@@ -116360,7 +116508,7 @@ var init_keys3 = __esm({
116360
116508
  });
116361
116509
 
116362
116510
  // wallet/src/laneb/flows.mjs
116363
- import { createHash as createHash35 } from "node:crypto";
116511
+ import { createHash as createHash36 } from "node:crypto";
116364
116512
  import { resolve as resolve34 } from "node:path";
116365
116513
  function serviceRefusal(error, what, fallbackNext) {
116366
116514
  if (error?.message === "laneb_service_not_enabled") {
@@ -117023,7 +117171,7 @@ var init_flows3 = __esm({
117023
117171
  };
117024
117172
  sleep3 = (ms) => new Promise((done) => setTimeout(done, ms));
117025
117173
  isAddress4 = (value) => typeof value === "string" && /^[1-9A-HJ-NP-Za-km-z]{32,44}$/.test(value);
117026
- sha256Hex3 = (text3) => createHash35("sha256").update(text3).digest("hex");
117174
+ sha256Hex3 = (text3) => createHash36("sha256").update(text3).digest("hex");
117027
117175
  AMOUNT_SENTENCE = "We know the quoted price; for scheme confidential we also check the payer's proof that the transfer equals it. We cannot decrypt a slot. The chain shows no amount.";
117028
117176
  saveBook = (store, book) => store.writeWal(BOOK, book);
117029
117177
  planRpc = (rpc2) => ({
@@ -117033,7 +117181,7 @@ var init_flows3 = __esm({
117033
117181
  });
117034
117182
 
117035
117183
  // wallet/src/laneb/amountProof.mjs
117036
- import { createHash as createHash36, randomBytes as randomBytes27 } from "node:crypto";
117184
+ import { createHash as createHash37, randomBytes as randomBytes27 } from "node:crypto";
117037
117185
  function readValidityContext(transactions) {
117038
117186
  if (!Array.isArray(transactions) || transactions.length === 0) refuse13("the plan carries no transactions");
117039
117187
  let validity;
@@ -117066,7 +117214,7 @@ function readValidityContext(transactions) {
117066
117214
  return { sourcePubkey: data.slice(1, 33), destinationPubkey: data.slice(33, 65), auditorPubkey: data.slice(65, 97), lo: half(97), hi: half(225) };
117067
117215
  }
117068
117216
  function challenge2({ nonce, half, sourcePubkey, sourceHandle, R: R2, A1, A2, commitment }) {
117069
- const digest2 = createHash36("sha512").update(Buffer.from(AMOUNT_PROOF_DOMAIN, "utf8")).update(nonce).update(Buffer.from(half, "utf8")).update(sourcePubkey).update(H2.toBytes()).update(sourceHandle).update(R2).update(A1).update(A2).update(commitment).digest();
117217
+ const digest2 = createHash37("sha512").update(Buffer.from(AMOUNT_PROOF_DOMAIN, "utf8")).update(nonce).update(Buffer.from(half, "utf8")).update(sourcePubkey).update(H2.toBytes()).update(sourceHandle).update(R2).update(A1).update(A2).update(commitment).digest();
117070
117218
  return leToBig2(digest2) % L3;
117071
117219
  }
117072
117220
  function nonceBytes(nonce) {
@@ -117181,7 +117329,7 @@ var init_amountProof = __esm({
117181
117329
  });
117182
117330
 
117183
117331
  // wallet/src/laneb/x402pay.mjs
117184
- import { createHash as createHash37, randomBytes as randomBytes28 } from "node:crypto";
117332
+ import { createHash as createHash38, randomBytes as randomBytes28 } from "node:crypto";
117185
117333
  import { resolve as resolve35 } from "node:path";
117186
117334
  async function call2(promise, what, fallbackNext) {
117187
117335
  try {
@@ -117653,7 +117801,7 @@ var init_x402pay = __esm({
117653
117801
  }
117654
117802
  };
117655
117803
  sleep4 = (ms) => new Promise((done) => setTimeout(done, ms));
117656
- sha256Hex4 = (bytes2) => createHash37("sha256").update(bytes2).digest("hex");
117804
+ sha256Hex4 = (bytes2) => createHash38("sha256").update(bytes2).digest("hex");
117657
117805
  isAddress5 = (value) => typeof value === "string" && /^[1-9A-HJ-NP-Za-km-z]{32,44}$/.test(value);
117658
117806
  isSignature2 = (value) => typeof value === "string" && /^[1-9A-HJ-NP-Za-km-z]{64,100}$/.test(value);
117659
117807
  usdc5 = (atomic3) => {
@@ -118364,14 +118512,15 @@ function startHistoryPrewarm(session, store, mark) {
118364
118512
  // for them after the walk, M). The same set the recovery asks (every listed transition
118365
118513
  // its cache lacks); it takes an answer only for a transition of the verified report
118366
118514
  // (chain.mjs createMemoReader prefetch; recover.mjs checks each bundle's digest).
118367
- onCompactList: (contexts) => {
118368
- markPhase("memo-prefetch");
118369
- prefetchRecoveryMemos({ store, finalizedHistory: { contexts }, serviceUrl: session.memoServiceUrl, programId: session.programId });
118370
- }
118515
+ onCompactList: memoPrefetchOnList(session, store)
118371
118516
  }));
118372
118517
  } catch {
118373
118518
  }
118374
118519
  }
118520
+ var memoPrefetchOnList = (session, store) => (contexts) => {
118521
+ markPhase("memo-prefetch");
118522
+ prefetchRecoveryMemos({ store, finalizedHistory: { contexts }, serviceUrl: session.memoServiceUrl, programId: session.programId });
118523
+ };
118375
118524
  var lazyProofTools = (session) => new Proxy({}, { get: (_target, key) => session.proofTools[key] });
118376
118525
  async function paidCall({ session, target, method, headers, body, cap, requestId, price, challenge: challenge3, timing, mark }) {
118377
118526
  if (session.closed) fail20("fetch_session_closed", "this payer session is closed; open a new one");
@@ -118424,7 +118573,8 @@ async function paidCall({ session, target, method, headers, body, cap, requestId
118424
118573
  connection: connectSplit(session.connection, session.historyUrl),
118425
118574
  programId: session.programId,
118426
118575
  pool: store.state.pool,
118427
- deploymentIdentity: session.proofTools.deploymentIdentity
118576
+ deploymentIdentity: session.proofTools.deploymentIdentity,
118577
+ onCompactList: memoPrefetchOnList(session, store)
118428
118578
  })
118429
118579
  }
118430
118580
  });
@@ -118451,7 +118601,7 @@ async function paidCall({ session, target, method, headers, body, cap, requestId
118451
118601
  // wallet/src/mcp/stdioServer.mjs
118452
118602
  init_fs();
118453
118603
  var import_web3131 = __toESM(require_index_cjs(), 1);
118454
- import { createHash as createHash29 } from "node:crypto";
118604
+ import { createHash as createHash30 } from "node:crypto";
118455
118605
  import { dirname as dirname24, join as join27, resolve as resolve25, sep as sep4 } from "node:path";
118456
118606
  import { fileURLToPath as fileURLToPath17 } from "node:url";
118457
118607
  init_proxy();
@@ -118730,7 +118880,7 @@ function addToJsonHost(file, entry, { now = /* @__PURE__ */ new Date(), force =
118730
118880
  // wallet/src/setup/proofTools.mjs
118731
118881
  init_fs();
118732
118882
  init_rpcDefault();
118733
- import { createHash as createHash22 } from "node:crypto";
118883
+ import { createHash as createHash23 } from "node:crypto";
118734
118884
  import { dirname as dirname17, join as join17, sep as sep3 } from "node:path";
118735
118885
 
118736
118886
  // wallet/src/setup/channel.mjs
@@ -118965,7 +119115,7 @@ var LIMITS = Object.freeze({ release: 64 * 1024, sums: 64 * 1024, file: 200 * 10
118965
119115
  var RELEASE_TIMEOUT_MS = 3e4;
118966
119116
  var FILE_TIMEOUT_MS = 15 * 6e4;
118967
119117
  var REQUIRED_FILES = Object.freeze(["proof-tools.json", "exit-proof-tools.json", "public-profile.json"]);
118968
- var sha2569 = (bytes2) => createHash22("sha256").update(bytes2).digest("hex");
119118
+ var sha2569 = (bytes2) => createHash23("sha256").update(bytes2).digest("hex");
118969
119119
  var fail22 = (code, detail) => new Error(`${code}: ${detail}`);
118970
119120
  async function getBytes(fetchImpl, url, timeoutMs, label, maxBytes, budget) {
118971
119121
  const limit = budget ? Math.min(maxBytes, budget.left) : maxBytes;
@@ -120006,7 +120156,7 @@ init_shielded_wallet();
120006
120156
 
120007
120157
  // wallet/src/mcp/autoPockets.mjs
120008
120158
  init_http();
120009
- import { createHash as createHash26 } from "node:crypto";
120159
+ import { createHash as createHash27 } from "node:crypto";
120010
120160
 
120011
120161
  // wallet/src/pocket/auto.mjs
120012
120162
  var import_web3126 = __toESM(require_index_cjs(), 1);
@@ -121337,7 +121487,7 @@ var REST_OF_FILL_SECONDS = Object.freeze({
121337
121487
  });
121338
121488
  var REFILLING_CODE = "wallet_refilling_retry_same_request";
121339
121489
  var firstCode3 = (error) => String(error?.message ?? error ?? "").split(/[\s:;(]/, 1)[0];
121340
- var sha25610 = (text3) => createHash26("sha256").update(text3, "utf8").digest("hex");
121490
+ var sha25610 = (text3) => createHash27("sha256").update(text3, "utf8").digest("hex");
121341
121491
  function requestFingerprint({ url, method = "GET", headers = {}, body }) {
121342
121492
  const sorted = Object.entries(headers ?? {}).map(([name, value]) => [name.toLowerCase(), String(value)]).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0);
121343
121493
  return sha25610(JSON.stringify([String(url), String(method).toUpperCase(), sorted, body ?? null]));
@@ -124533,7 +124683,7 @@ function createOneTimeAdopter({ session, log = () => {
124533
124683
 
124534
124684
  // wallet/src/mcp/answer.mjs
124535
124685
  init_fs();
124536
- import { createHash as createHash27 } from "node:crypto";
124686
+ import { createHash as createHash28 } from "node:crypto";
124537
124687
  import { join as join24 } from "node:path";
124538
124688
  var DEFAULT_MAX_INLINE_BYTES = 4e6;
124539
124689
  var DEFAULT_MAX_TEXT_CHARS = 64 * 1024;
@@ -124697,7 +124847,7 @@ function extractEmbeddedImages(json2, { saveDir, now, maxInlineBytes = DEFAULT_M
124697
124847
  return NOT_AN_IMAGE;
124698
124848
  }
124699
124849
  const sniffed = sniffImage(decoded);
124700
- const sha3 = createHash27("sha256").update(decoded).digest("hex");
124850
+ const sha3 = createHash28("sha256").update(decoded).digest("hex");
124701
124851
  if (!sniffed) {
124702
124852
  const svg = claimedMime === "image/svg+xml" || looksLikeSvg(decoded);
124703
124853
  const saved2 = save(decoded, svg ? "svg" : "bin", saveDir, now, sha3);
@@ -124763,7 +124913,7 @@ function paidAnswerContent({
124763
124913
  bytes: data.length,
124764
124914
  ...truncated ? { answerTruncated: true } : {}
124765
124915
  };
124766
- const sha25612 = createHash27("sha256").update(data).digest("hex");
124916
+ const sha25612 = createHash28("sha256").update(data).digest("hex");
124767
124917
  const sniffed = sniffImage(data);
124768
124918
  if (sniffed && (declared === "" || declared.startsWith("image/") || declared === "application/octet-stream")) {
124769
124919
  const saved2 = save(data, RASTER[sniffed], saveDir, now, sha25612);
@@ -124844,7 +124994,7 @@ function paidAnswerContent({
124844
124994
 
124845
124995
  // wallet/src/mcp/discover.mjs
124846
124996
  init_fs();
124847
- import { createHash as createHash28 } from "node:crypto";
124997
+ import { createHash as createHash29 } from "node:crypto";
124848
124998
  import { join as join25 } from "node:path";
124849
124999
  var SOLANA_MAINNET = "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp";
124850
125000
  var SOLANA_USDC = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";
@@ -125315,7 +125465,7 @@ function clip(text3, max) {
125315
125465
  return text3.length > max ? `${text3.slice(0, max - 1)}\u2026` : text3;
125316
125466
  }
125317
125467
  function cachePath(key, cacheDir) {
125318
- return join25(cacheDir, `x402-discover-${createHash28("sha256").update(key).digest("hex").slice(0, 24)}.json`);
125468
+ return join25(cacheDir, `x402-discover-${createHash29("sha256").update(key).digest("hex").slice(0, 24)}.json`);
125319
125469
  }
125320
125470
  function readCache(key, ctx, maxAge) {
125321
125471
  const age = (record) => ctx.clock() - Number(record?.fetchedAt);
@@ -125606,6 +125756,7 @@ var withTimeout = (promise, ms) => Promise.race([
125606
125756
  })
125607
125757
  ]);
125608
125758
  var ownKey = (store) => import_web3130.Keypair.fromSecretKey(Uint8Array.from(store.state.solanaSecretKey)).publicKey;
125759
+ var readFailure = (error) => [error?.name ?? "Error", error?.cause?.code, String(error?.message ?? "").replace(/[a-z][a-z0-9+.-]*:\/\/\S+/gi, "<url>").replace(/api[-_]?key=\S+/gi, "<key>").slice(0, 160)].filter(Boolean).join(" ");
125609
125760
  async function readOwnPublicBalance({ session, store }) {
125610
125761
  const owner = ownKey(store);
125611
125762
  const tokenAccount = getAssociatedTokenAddressSync(new import_web3130.PublicKey(store.state.asset), owner, false, TOKEN_PROGRAM_ID);
@@ -126654,7 +126805,7 @@ function createWalletTools({
126654
126805
  ]);
126655
126806
  if (answered.reading) {
126656
126807
  publicRead.then(({ error: late2 }) => {
126657
- if (late2) log(`MCP_PUBLIC_READ_FAILED_LATE ${late2?.name ?? "Error"}`);
126808
+ if (late2) log(`MCP_PUBLIC_READ_FAILED_LATE ${readFailure(late2)}`);
126658
126809
  });
126659
126810
  }
126660
126811
  const { read, error } = answered;
@@ -126673,7 +126824,7 @@ function createWalletTools({
126673
126824
  unshieldedSolLamports: read.solLamports
126674
126825
  };
126675
126826
  } else {
126676
- log(`MCP_PUBLIC_READ_FAILED ${error?.name ?? "Error"}`);
126827
+ log(`MCP_PUBLIC_READ_FAILED ${readFailure(error)}`);
126677
126828
  unshielded = {
126678
126829
  unshieldedAtomic: null,
126679
126830
  unshielded: null,
@@ -128102,7 +128253,7 @@ function runningBundleFile({ moduleUrl = new URL("__bundled_source__/wallet/src/
128102
128253
  function runningReleaseSha256({ bundleFile = runningBundleFile() } = {}) {
128103
128254
  if (!bundleFile) return Promise.resolve(void 0);
128104
128255
  return new Promise((done) => {
128105
- readFile(bundleFile, (error, bytes2) => done(error ? void 0 : createHash29("sha256").update(bytes2).digest("hex")));
128256
+ readFile(bundleFile, (error, bytes2) => done(error ? void 0 : createHash30("sha256").update(bytes2).digest("hex")));
128106
128257
  });
128107
128258
  }
128108
128259
  async function checkWalletUpdate({ facilitator, ownSha256 = runningReleaseSha256, fetchReleaseImpl = fetchRelease } = {}) {
@@ -130177,7 +130328,7 @@ init_chain2();
130177
130328
  init_proxy();
130178
130329
  init_sealedCache();
130179
130330
  init_reference2();
130180
- import { createHash as createHash30, createPublicKey as createPublicKey6, verify as verify3 } from "node:crypto";
130331
+ import { createHash as createHash31, createPublicKey as createPublicKey6, verify as verify3 } from "node:crypto";
130181
130332
  var PROGRAM_ID = new import_web3133.PublicKey("9fhQBbumKEFuXtMBDw8AaQyAjCorLGJQiS3skWZdQyQD");
130182
130333
  var USDC_MINT = new import_web3133.PublicKey("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");
130183
130334
  var TREE_ACCOUNT = import_web3133.PublicKey.findProgramAddressSync([Buffer.from("merkle_tree"), USDC_MINT.toBuffer()], PROGRAM_ID)[0];
@@ -130186,7 +130337,7 @@ var TREE_ACCOUNT_BYTES = 4136;
130186
130337
  var NEXT_INDEX_OFFSET = 40;
130187
130338
  var ROOT_HISTORY_OFFSET = 912;
130188
130339
  var ROOT_HISTORY_SIZE_OFFSET = 4129;
130189
- var EVENT_DISCRIMINATOR = createHash30("sha256").update("event:SplCommitmentData").digest().subarray(0, 8);
130340
+ var EVENT_DISCRIMINATOR = createHash31("sha256").update("event:SplCommitmentData").digest().subarray(0, 8);
130190
130341
  var EVENT_HEADER_BYTES = 84;
130191
130342
  var LOG_DATA = "Program data: ";
130192
130343
  var SIGNATURE_PAGE = 1e3;
@@ -133020,7 +133171,7 @@ var rpcFlags = [
133020
133171
  var HISTORY_RPC_FLAG = flag2(
133021
133172
  "--history-rpc",
133022
133173
  "<own|url>",
133023
- `where the pool's public history comes from (the history walk: its signature lists, transactions, and block signature lists). Default with --tor: the history proxy onion this wallet pins for the pool (the pool ${GUIDE.pool} has one; a pool without one uses your own RPC), so your RPC provider does not see that you read this pool; Default without --tor: the same history proxy over https on the facilitator's pay host (that host already serves your memos and payments), so a first walk takes seconds, not minutes of rate-limited RPC calls; a pool without one uses your own RPC. A line on stderr says which source the run uses. own: your own RPC serves it, with or without --tor, so your RPC provider sees that you read this pool. An https URL, or an http://<v3 onion>/ origin with --tor, serves it instead. That source sees that a client read this pool's public history (and your IP address unless you add --tor), not who; every wallet of the pool makes the same reads. A refresh asks it for every record of a fixed 256-record bucket of the pool's list and the newer ones, not only what is newer than your last refresh, so it sees that refresh only to the bucket (more reads than your own RPC needs). Your own RPC still serves the pool account that the history must match, and every read that names your wallet (your own payment, deposit, and pocket reads). If the source is a little behind the chain, the walk continues at once with the history up to the slot the source has reached, which matches when the pool did not change after that slot; only when it did, the walk asks the source again after 0.5 s, 1 s, 2 s, then every 5 s, for at most 60 s. The wallet checks the signatures of every transaction the source serves, and each refresh reads 3 of them, drawn at random, again on your own RPC (so your RPC provider sees 3 pool reads per refresh). If the source fails, stays behind, or serves history that does not match (a bad signature or a cross-check mismatch), the command stops and says so. It never falls back to your own RPC. A URL that holds an API key shows in the process list and shell history`,
133174
+ `where the pool's public history comes from (the history walk: its signature lists, transactions, and block signature lists). Default with --tor: the history proxy onion this wallet pins for the pool (the pool ${GUIDE.pool} has one; a pool without one uses your own RPC), so your RPC provider does not see that you read this pool; Default without --tor: the same history proxy over https on the facilitator's pay host (that host already serves your memos and payments), so a first walk takes seconds, not minutes of rate-limited RPC calls; a pool without one uses your own RPC. A line on stderr says which source the run uses. own: your own RPC serves it, with or without --tor, so your RPC provider sees that you read this pool. An https URL, or an http://<v3 onion>/ origin with --tor, serves it instead. That source sees that a client read this pool's public history (and your IP address unless you add --tor), not who; every wallet of the pool makes the same reads. A refresh asks it for every record of a fixed 256-record bucket of the pool's list and the newer ones, not only what is newer than your last refresh, so it sees that refresh only to the bucket (more reads than your own RPC needs). Your own RPC still serves the pool account that the history must match, and every read that names your wallet (your own payment, deposit, and pocket reads). If the source is a little behind the chain, the walk continues at once with the history up to the slot the source has reached, which matches when the pool did not change after that slot; only when it did, the walk asks the source again every 0.15 s for about 2 s, then after 0.5 s, 1 s, 2 s, then every 5 s, for at most 60 s. The wallet checks the signatures of every transaction the source serves, and each refresh reads 3 of them, drawn at random, again on your own RPC (so your RPC provider sees 3 pool reads per refresh). If the source fails, stays behind, or serves history that does not match (a bad signature or a cross-check mismatch), the command stops and says so. It never falls back to your own RPC. A URL that holds an API key shows in the process list and shell history`,
133024
133175
  { check: "history-rpc" }
133025
133176
  );
133026
133177
  var recoverFlags = (options = {}) => [