shinjuku-shielded 0.3.39 → 0.3.40

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": "5f5ca189829786779ba9e05c237bb6edf057a06d4745f0a601212136aa0bf68f",
5
- "bytes": 11216201,
6
- "sourceCommit": "c72d3c75917cf35191aa263f3e30878779ed814b",
4
+ "sha256": "5b21a788efa0e47f3e83f413f73a4c11a70f068edda47f4f68be3bd6c0855955",
5
+ "bytes": 11226333,
6
+ "sourceCommit": "40a82beaab73a8c1e1dbd6d44682b4d2cd93e402",
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.39",
3
+ "version": "0.3.40",
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": "5f5ca189",
7
- "shinjukuSha256": "5f5ca189829786779ba9e05c237bb6edf057a06d4745f0a601212136aa0bf68f",
6
+ "shinjukuRelease": "5b21a788",
7
+ "shinjukuSha256": "5b21a788efa0e47f3e83f413f73a4c11a70f068edda47f4f68be3bd6c0855955",
8
8
  "license": "SEE LICENSE IN LICENSE.txt",
9
9
  "author": "Shinjuku Shielded",
10
10
  "homepage": "https://github.com/ShinjukuStaition/shinjuku-mcp#readme",
@@ -42330,6 +42330,54 @@ var init_pool_denomination = __esm({
42330
42330
  }
42331
42331
  });
42332
42332
 
42333
+ // spikes/shielded-x402-wallet/lib/rpc-url.mjs
42334
+ function flagValue(args, name) {
42335
+ const index = args.indexOf(name);
42336
+ if (index === -1) return void 0;
42337
+ const value = args[index + 1];
42338
+ if (!value || value.startsWith("--")) throw new Error(`rpc_flag_value_missing: ${name} requires a value`);
42339
+ return value;
42340
+ }
42341
+ function resolveRpcUrl(args, { env = process.env, warn = (line) => console.error(line), fallback } = {}) {
42342
+ const file = flagValue(args, "--rpc-file");
42343
+ const inline = flagValue(args, "--rpc");
42344
+ if (file !== void 0 && inline !== void 0) throw new Error("rpc_flags_conflict: use --rpc-file or --rpc, not both");
42345
+ if (file !== void 0) {
42346
+ let text3;
42347
+ try {
42348
+ text3 = readFileSync(file, "utf8");
42349
+ } catch (error) {
42350
+ throw new Error(`rpc_file_unreadable: --rpc-file could not be read (${typeof error?.code === "string" ? error.code : "read error"})`);
42351
+ }
42352
+ const value = text3.split(/\r?\n/)[0].trim();
42353
+ if (!value) throw new Error("rpc_file_empty: --rpc-file holds no RPC URL on its first line");
42354
+ return value;
42355
+ }
42356
+ if (inline !== void 0) {
42357
+ if (rpcUrlLooksKeyed(inline)) {
42358
+ warn("warning: --rpc shows this RPC URL, key included, to anyone who can list processes or read shell history; put the URL in a private file and pass --rpc-file <file>");
42359
+ }
42360
+ return inline;
42361
+ }
42362
+ return env.UNDERMARKET_SOLANA_RPC_URL || fallback;
42363
+ }
42364
+ function rpcUrlLooksKeyed(value) {
42365
+ let url;
42366
+ try {
42367
+ url = new URL(value);
42368
+ } catch {
42369
+ return true;
42370
+ }
42371
+ if (url.search || url.username || url.password) return true;
42372
+ return url.pathname.split("/").some((segment) => segment.length >= 16 && /^[A-Za-z0-9_-]+$/.test(segment) && /[0-9]/.test(segment) && /[A-Za-z]/.test(segment));
42373
+ }
42374
+ var init_rpc_url = __esm({
42375
+ "spikes/shielded-x402-wallet/lib/rpc-url.mjs"() {
42376
+ "use strict";
42377
+ init_fs();
42378
+ }
42379
+ });
42380
+
42333
42381
  // spikes/shielded-x402-wallet/lib/prove.mjs
42334
42382
  import { createHash as createHash4 } from "node:crypto";
42335
42383
  import { join as join2, resolve as resolve2 } from "node:path";
@@ -42507,7 +42555,7 @@ function readRpcFileLine(path) {
42507
42555
  return void 0;
42508
42556
  }
42509
42557
  }
42510
- function resolveRpcUrl({ rpcFile, rpc: rpc2, env = process.env, origin, readFile: readFile5, notice } = {}) {
42558
+ function resolveRpcUrl2({ rpcFile, rpc: rpc2, env = process.env, origin, readFile: readFile5, notice } = {}) {
42511
42559
  if (rpcFile !== void 0) {
42512
42560
  const url2 = (readFile5 ?? readRpcFileLine)(rpcFile);
42513
42561
  if (!url2) throw new Error("rpc_file_unreadable: --rpc-file could not be read, or its first line is empty");
@@ -54782,12 +54830,23 @@ async function prepareFinalizedP03RecoveryFold(history, { sliceMs = 20 } = {}) {
54782
54830
  if (REBUILT_BY_REPORT.has(authenticated)) return;
54783
54831
  const running = FOLDS_IN_FLIGHT.get(authenticated);
54784
54832
  if (running !== void 0) return running;
54833
+ if (foldInFlight !== void 0) markPhase("fold-wait");
54834
+ while (foldInFlight !== void 0) {
54835
+ await foldInFlight.catch(() => {
54836
+ });
54837
+ if (REBUILT_BY_REPORT.has(authenticated)) return;
54838
+ const joined = FOLDS_IN_FLIGHT.get(authenticated);
54839
+ if (joined !== void 0) return joined;
54840
+ }
54785
54841
  const folding = foldInSlices(authenticated, sliceMs);
54786
54842
  FOLDS_IN_FLIGHT.set(authenticated, folding);
54843
+ foldInFlight = folding;
54787
54844
  try {
54788
- return await folding;
54845
+ await folding;
54846
+ markPhase("fold-done");
54789
54847
  } finally {
54790
54848
  FOLDS_IN_FLIGHT.delete(authenticated);
54849
+ if (foldInFlight === folding) foldInFlight = void 0;
54791
54850
  }
54792
54851
  }
54793
54852
  async function foldInSlices(authenticated, sliceMs) {
@@ -54816,6 +54875,7 @@ function* rebuildOrderedPrefixSteps(history) {
54816
54875
  while (resumed < prior.leaves.length && contexts[resumed].outCommitment === prior.leaves[resumed] && contexts[resumed].appendRoot === prior.roots[resumed + 1]) resumed += 1;
54817
54876
  if (resumed !== prior.leaves.length) resumed = 0;
54818
54877
  }
54878
+ markPhase(resumed > 0 ? "fold-reused" : "fold-cold");
54819
54879
  let nodes = resumed > 0 ? prior.nodes : zeroRoots2.slice(0, OUTER_DEPTH);
54820
54880
  let root = resumed > 0 ? prior.roots[resumed] : zeroRoots2[OUTER_DEPTH];
54821
54881
  const roots = resumed > 0 ? prior.roots.slice(0, resumed + 1) : [root];
@@ -54990,7 +55050,7 @@ function canonicalField(value, label) {
54990
55050
  }
54991
55051
  return value;
54992
55052
  }
54993
- var FIELD_MODULUS4, SUBTREE_LEAVES2, LOCAL_DEPTH, OUTER_DEPTH, TREE_DEPTH, P03_RECOVERY_PATH_SOURCE_MODEL, P03_PINNED_POSEIDON_PARAMETERS_SHA256, P03_PINNED_ZERO_LEAF, hashCalls, hash3, REBUILT_BY_REPORT, lastFold, FOLDS_IN_FLIGHT, ZERO_UPPER_ROOTS, LOCAL_ZERO_ROOTS, lastOuter;
55053
+ var FIELD_MODULUS4, SUBTREE_LEAVES2, LOCAL_DEPTH, OUTER_DEPTH, TREE_DEPTH, P03_RECOVERY_PATH_SOURCE_MODEL, P03_PINNED_POSEIDON_PARAMETERS_SHA256, P03_PINNED_ZERO_LEAF, hashCalls, hash3, REBUILT_BY_REPORT, lastFold, FOLDS_IN_FLIGHT, foldInFlight, ZERO_UPPER_ROOTS, LOCAL_ZERO_ROOTS, lastOuter;
54994
55054
  var init_recoveryPath = __esm({
54995
55055
  "wallet/src/recovery/recoveryPath.mjs"() {
54996
55056
  "use strict";
@@ -54998,6 +55058,7 @@ var init_recoveryPath = __esm({
54998
55058
  init_reference2();
54999
55059
  init_notes2();
55000
55060
  init_walk();
55061
+ init_phaseTiming();
55001
55062
  FIELD_MODULUS4 = 21888242871839275222246405745257275088548364400416034343698204186575808495617n;
55002
55063
  SUBTREE_LEAVES2 = 128n;
55003
55064
  LOCAL_DEPTH = 7;
@@ -56109,6 +56170,7 @@ async function loadOrExtendFinalizedP03History({
56109
56170
  cached = null;
56110
56171
  fallbacks += 1;
56111
56172
  }
56173
+ let laggingRetries = 0;
56112
56174
  for (let laggingTry = 0; cached; laggingTry += 1) {
56113
56175
  try {
56114
56176
  const extended = await extendFromCache({
@@ -56132,11 +56194,14 @@ async function loadOrExtendFinalizedP03History({
56132
56194
  mode: extended.mode,
56133
56195
  fallbacks,
56134
56196
  coverage: extended.coverageMode,
56197
+ laggingRetries,
56135
56198
  ...extended.window ? { window: extended.window } : {}
56136
56199
  };
56137
56200
  } catch (error) {
56138
56201
  onEvent("extension_failed", error);
56202
+ if (isProgramDataIdentityError(error)) throw error;
56139
56203
  if (isLaggingNodeRpcError(error) && laggingTry < EXTENSION_LAGGING_RETRY_MS.length) {
56204
+ laggingRetries += 1;
56140
56205
  await new Promise((resolve38) => setTimeout(resolve38, EXTENSION_LAGGING_RETRY_MS[laggingTry]));
56141
56206
  continue;
56142
56207
  }
@@ -56158,7 +56223,7 @@ async function loadOrExtendFinalizedP03History({
56158
56223
  await beforePersist?.(full);
56159
56224
  await persistCache(cache, full, programIdBase58, poolBase58);
56160
56225
  remember(full);
56161
- return { report: full.report, mode: "full", fallbacks, coverage: full.coverageMode };
56226
+ return { report: full.report, mode: "full", fallbacks, coverage: full.coverageMode, laggingRetries };
56162
56227
  }
56163
56228
  async function extendFromCache({ connection, programId, pool: pool2, deploymentIdentity, cached: stored, concurrency, lighterWalk, historySource, forceRead = false, liveRead }) {
56164
56229
  const program = new import_web398.PublicKey(programId);
@@ -59768,9 +59833,9 @@ async function runDepositReclaimCommand(args, cli) {
59768
59833
  const to = cli.flag(args, "--to");
59769
59834
  const serviceUrl2 = cli.flag(args, "--service");
59770
59835
  const keyFile = cli.flag(args, "--fee-payer-key-file");
59771
- const rpcUrl = cli.flag(args, "--rpc") ?? process.env.UNDERMARKET_SOLANA_RPC_URL;
59836
+ const rpcUrl = cli.rpcUrl(args);
59772
59837
  if (!pool2 || !programId || !depositId || !to || !rpcUrl || Boolean(serviceUrl2) === Boolean(keyFile)) {
59773
- throw new Error("deposit-reclaim requires --pool, --program, --deposit-id, --to, exactly one of --service or --fee-payer-key-file, and --rpc or UNDERMARKET_SOLANA_RPC_URL");
59838
+ throw new Error("deposit-reclaim requires --pool, --program, --deposit-id, --to, exactly one of --service or --fee-payer-key-file, and --rpc-file <file> (or --rpc, or UNDERMARKET_SOLANA_RPC_URL)");
59774
59839
  }
59775
59840
  const store = cli.openStore(pool2);
59776
59841
  if (store.state.pool !== pool2) throw new Error("deposit pool does not match wallet");
@@ -59786,11 +59851,11 @@ async function runDepositReclaimCommand(args, cli) {
59786
59851
  }
59787
59852
  async function runDepositScanCommand(args, cli) {
59788
59853
  const pool2 = cli.flag(args, "--pool");
59789
- const rpcUrl = cli.flag(args, "--rpc") ?? process.env.UNDERMARKET_SOLANA_RPC_URL;
59854
+ const rpcUrl = cli.rpcUrl(args);
59790
59855
  const fromFlag = cli.flag(args, "--from") ?? "0";
59791
59856
  const countFlag = cli.flag(args, "--count") ?? String(RELAY_KEY_PROBES);
59792
59857
  if (!pool2 || !rpcUrl || !/^(0|[1-9][0-9]{0,9})$/.test(fromFlag) || !/^[1-9][0-9]{0,3}$/.test(countFlag)) {
59793
- throw new Error(`deposit-scan requires --pool, --rpc or UNDERMARKET_SOLANA_RPC_URL, and optional whole numbers --from (default 0) and --count (1 to ${MAX_SCAN_COUNT}, default ${RELAY_KEY_PROBES})`);
59858
+ throw new Error(`deposit-scan requires --pool, --rpc-file <file> (or --rpc, or UNDERMARKET_SOLANA_RPC_URL), and optional whole numbers --from (default 0) and --count (1 to ${MAX_SCAN_COUNT}, default ${RELAY_KEY_PROBES})`);
59794
59859
  }
59795
59860
  const from = Number(fromFlag);
59796
59861
  const count2 = Number(countFlag);
@@ -59829,9 +59894,9 @@ async function reclaimLandedDepositRent({ store, connection, programId, deps = {
59829
59894
  async function runDepositCompactCommand(args, cli) {
59830
59895
  const pool2 = cli.flag(args, "--pool");
59831
59896
  const programId = cli.flag(args, "--program");
59832
- const rpcUrl = cli.flag(args, "--rpc") ?? process.env.UNDERMARKET_SOLANA_RPC_URL;
59897
+ const rpcUrl = cli.rpcUrl(args);
59833
59898
  if (!pool2 || !programId || !rpcUrl) {
59834
- throw new Error("deposit-compact requires --pool, --program, and --rpc or UNDERMARKET_SOLANA_RPC_URL");
59899
+ throw new Error("deposit-compact requires --pool, --program, and --rpc-file <file> (or --rpc, or UNDERMARKET_SOLANA_RPC_URL)");
59835
59900
  }
59836
59901
  const path = cli.walletPath(pool2);
59837
59902
  let release;
@@ -60180,11 +60245,26 @@ var init_recoveryCache = __esm({
60180
60245
 
60181
60246
  // wallet/src/recovery/memoDecryptPool.mjs
60182
60247
  import { availableParallelism } from "node:os";
60248
+ import { performance as performance2 } from "node:perf_hooks";
60183
60249
  import { Worker as Worker2 } from "node:worker_threads";
60184
- function sharedXOnMainThread(xs, eta) {
60250
+ function sliceClock() {
60251
+ let started = performance2.now();
60252
+ return async () => {
60253
+ if (performance2.now() - started < SLICE_MS) return;
60254
+ await yieldTurn();
60255
+ started = performance2.now();
60256
+ };
60257
+ }
60258
+ async function sharedXOnMainThread(xs, eta) {
60185
60259
  mainThreadSharedX ??= new Function(`${CURVE_SOURCE}
60186
60260
  return memoSharedX;`)();
60187
- return xs.map((x) => mainThreadSharedX(x, eta));
60261
+ const turn = sliceClock();
60262
+ const out = [];
60263
+ for (const x of xs) {
60264
+ out.push(mainThreadSharedX(x, eta));
60265
+ await turn();
60266
+ }
60267
+ return out;
60188
60268
  }
60189
60269
  function workerCount() {
60190
60270
  let cores = 1;
@@ -60274,7 +60354,10 @@ async function trialDecryptBundles(jobs, eta) {
60274
60354
  const xs = records.flatMap((list) => list.map((record) => Buffer.from(record.subarray(0, 32)).toString("hex")));
60275
60355
  const shared2 = await memoSharedXs(xs, scalar);
60276
60356
  if (shared2.length !== xs.length) throw new Error("memo decrypt pool answered the wrong count");
60277
- return jobs.map((job, index) => {
60357
+ const turn = sliceClock();
60358
+ const results = [];
60359
+ for (let index = 0; index < jobs.length; index += 1) {
60360
+ const job = jobs[index];
60278
60361
  const context = {
60279
60362
  poolDomain: BigInt(job.poolDomain),
60280
60363
  outCommitment: BigInt(job.outCommitment),
@@ -60286,15 +60369,17 @@ async function trialDecryptBundles(jobs, eta) {
60286
60369
  if (record.length !== RECORD_BYTES2) return void 0;
60287
60370
  return openRecord(record, slot3, shared2[index * RECORD_COUNT2 + slot3], context);
60288
60371
  });
60289
- return acceptMemoPlaintexts({
60372
+ results.push(acceptMemoPlaintexts({
60290
60373
  plaintexts,
60291
60374
  outCommitment: job.outCommitment,
60292
60375
  zeroLeaf: job.zeroLeaf,
60293
60376
  subtreeStartIndex: job.subtreeStartIndex
60294
- });
60295
- });
60377
+ }));
60378
+ await turn();
60379
+ }
60380
+ return results;
60296
60381
  }
60297
- var CURVE_SOURCE, WORKER_SOURCE, mainThreadSharedX, MAX_WORKERS, pool, nextJob;
60382
+ var CURVE_SOURCE, WORKER_SOURCE, SLICE_MS, yieldTurn, mainThreadSharedX, MAX_WORKERS, pool, nextJob;
60298
60383
  var init_memoDecryptPool = __esm({
60299
60384
  "wallet/src/recovery/memoDecryptPool.mjs"() {
60300
60385
  "use strict";
@@ -60424,6 +60509,10 @@ parentPort.on("message", ({ id, eta, xs }) => {
60424
60509
  parentPort.postMessage({ id, out: xs.map((x) => memoSharedX(x, scalar)) });
60425
60510
  });
60426
60511
  `;
60512
+ SLICE_MS = 25;
60513
+ yieldTurn = () => new Promise((resolve38) => {
60514
+ setImmediate(resolve38);
60515
+ });
60427
60516
  MAX_WORKERS = 8;
60428
60517
  nextJob = 0;
60429
60518
  }
@@ -60492,6 +60581,7 @@ var init_successorHistories = __esm({
60492
60581
  // wallet/src/recovery/recover.mjs
60493
60582
  import { createHash as createHash15 } from "node:crypto";
60494
60583
  import { join as join10, resolve as resolve10 } from "node:path";
60584
+ import { performance as performance3 } from "node:perf_hooks";
60495
60585
  import { fileURLToPath as fileURLToPath5 } from "node:url";
60496
60586
  function pinnedGenerator2(profileVector) {
60497
60587
  if (profileVector?.payerKeys?.generator) return profileVector.payerKeys.generator;
@@ -60513,6 +60603,16 @@ function replayValueOf(kind, poolDomain, commitment, eta, leafIndex) {
60513
60603
  REPLAY_VALUES.set(key, value);
60514
60604
  return value;
60515
60605
  }
60606
+ function decryptedKey(eta, programId, pool2, digest2, context) {
60607
+ return createHash15("sha256").update(`${String(eta)}|${programId}|${pool2}|${digest2}|${[
60608
+ context.transitionKind,
60609
+ context.poolDomain,
60610
+ context.outCommitment,
60611
+ context.contextCommitment,
60612
+ context.epoch,
60613
+ context.subtreeStartIndex
60614
+ ].map((value) => String(value)).join(":")}`).digest("base64");
60615
+ }
60516
60616
  function assertFinalizedRecoveryContext(context, digest2, programId, pool2) {
60517
60617
  const kinds = Object.freeze({ deposit: 1, payment: 2, withdraw: 3, "note-exit": 4, move: 5 });
60518
60618
  const field4 = (value) => typeof value === "bigint" && value >= 0n && value < FIELD_MODULUS6;
@@ -60550,6 +60650,24 @@ function walMemoBundles(store) {
60550
60650
  }
60551
60651
  return bundles;
60552
60652
  }
60653
+ async function walMemoBundlesSliced(store) {
60654
+ const bundles = /* @__PURE__ */ new Map();
60655
+ let started = performance3.now();
60656
+ for (const name of store.listWal()) {
60657
+ const record = store.readWal(name);
60658
+ if (record?.memoBundleHex) {
60659
+ const bytes2 = Uint8Array.from(Buffer.from(hexOf2(record.memoBundleHex), "hex"));
60660
+ bundles.set(hexOf2(record.memoDigest ?? bundleDigest2(bytes2)), bytes2);
60661
+ }
60662
+ if (performance3.now() - started >= 25) {
60663
+ await new Promise((resolve38) => {
60664
+ setImmediate(resolve38);
60665
+ });
60666
+ started = performance3.now();
60667
+ }
60668
+ }
60669
+ return bundles;
60670
+ }
60553
60671
  function decryptJob(bytes2, context, eta) {
60554
60672
  return {
60555
60673
  bundleBytes: bytes2,
@@ -60568,6 +60686,30 @@ async function decryptAll(decrypt, items, eta) {
60568
60686
  const results = await trialDecryptBundles(items.map(({ bytes: bytes2, context }) => decryptJob(bytes2, context, eta)), eta);
60569
60687
  return results.map((result) => result.accepted);
60570
60688
  }
60689
+ async function decryptKept(decrypt, items, eta, chainProgramId, pool2) {
60690
+ if (decrypt !== void 0) return decryptAll(decrypt, items, eta);
60691
+ const program = chainProgramId.toBase58();
60692
+ const poolKey = pool2.toBase58();
60693
+ const keys3 = items.map(({ digest: digest2, context }) => decryptedKey(eta, program, poolKey, digest2, context));
60694
+ const outputs = keys3.map((key) => {
60695
+ const kept = DECRYPTED.get(key);
60696
+ return kept === void 0 ? void 0 : copyOutputs(kept);
60697
+ });
60698
+ const missing = items.filter((_, index) => outputs[index] === void 0);
60699
+ if (missing.length > 0) {
60700
+ const fresh = await decryptAll(void 0, missing, eta);
60701
+ let next = 0;
60702
+ outputs.forEach((value, index) => {
60703
+ if (value !== void 0) return;
60704
+ const result = fresh[next];
60705
+ next += 1;
60706
+ if (DECRYPTED.size >= DECRYPTED_MAX) DECRYPTED.clear();
60707
+ DECRYPTED.set(keys3[index], copyOutputs(result));
60708
+ outputs[index] = result;
60709
+ });
60710
+ }
60711
+ return outputs;
60712
+ }
60571
60713
  async function legacyOutputs({ store, digests, serviceUrl: serviceUrl2, fresh, deps, chainProgramId, pool: pool2, eta, decrypt }) {
60572
60714
  const bundles = [];
60573
60715
  const seen = /* @__PURE__ */ new Set();
@@ -60620,7 +60762,7 @@ async function syncedOutputs({ store, finalizedHistory: finalizedHistory2, diges
60620
60762
  }
60621
60763
  if (!fresh) store.listWal();
60622
60764
  let wal;
60623
- const walFor = () => wal ??= fresh ? /* @__PURE__ */ new Map() : walMemoBundles(store);
60765
+ const walFor = async () => wal ??= fresh ? /* @__PURE__ */ new Map() : await walMemoBundlesSliced(store);
60624
60766
  const reader = deps.memoReader ?? createMemoReader(serviceUrl2, { fetchImpl: deps.fetchImpl ?? fetch, ...deps.pause ? { pause: deps.pause } : {} });
60625
60767
  (deps.notice ?? ((text3) => process.stderr.write(text3)))(
60626
60768
  `reading ${pending.length} memos from the memo service, ${Math.ceil(pending.length / MEMO_BATCH_MAX)} request(s)
@@ -60637,10 +60779,17 @@ async function syncedOutputs({ store, finalizedHistory: finalizedHistory2, diges
60637
60779
  }
60638
60780
  }
60639
60781
  const items = [];
60782
+ let sliceStart = performance3.now();
60640
60783
  for (const context of chunk) {
60784
+ if (performance3.now() - sliceStart >= 25) {
60785
+ await new Promise((resolve38) => {
60786
+ setImmediate(resolve38);
60787
+ });
60788
+ sliceStart = performance3.now();
60789
+ }
60641
60790
  const digest2 = hexOf2(context.memoDigest);
60642
60791
  const fromService = served.get(digest2);
60643
- const bytes2 = fromService ?? walFor().get(digest2);
60792
+ const bytes2 = fromService ?? (await walFor()).get(digest2);
60644
60793
  if (!bytes2) {
60645
60794
  absent2 += 1;
60646
60795
  continue;
@@ -60648,7 +60797,7 @@ async function syncedOutputs({ store, finalizedHistory: finalizedHistory2, diges
60648
60797
  assertBundle(digest2, bytes2);
60649
60798
  items.push({ context, digest: digest2, bytes: bytes2, fromService });
60650
60799
  }
60651
- const outputs = await decryptAll(decrypt, items, eta);
60800
+ const outputs = await decryptKept(decrypt, items, eta, chainProgramId, pool2);
60652
60801
  items.forEach(({ context, digest: digest2, fromService }, index) => {
60653
60802
  decrypted += 1;
60654
60803
  found.set(context, outputs[index]);
@@ -60834,7 +60983,7 @@ async function runRecover({ store, connection, programId, digests, serviceUrl: s
60834
60983
  ...Array.isArray(digests) && digests.length > 0 ? { narrowedByDigests: true } : {}
60835
60984
  };
60836
60985
  }
60837
- var import_web3102, FIELD_MODULUS6, MODEL_DIR, seedBytes3, committedGenerator, REPLAY_VALUES, REPLAY_VALUES_MAX, hexOf2;
60986
+ var import_web3102, FIELD_MODULUS6, MODEL_DIR, seedBytes3, committedGenerator, REPLAY_VALUES, REPLAY_VALUES_MAX, DECRYPTED, DECRYPTED_MAX, copyOutputs, hexOf2;
60838
60987
  var init_recover = __esm({
60839
60988
  "wallet/src/recovery/recover.mjs"() {
60840
60989
  "use strict";
@@ -60856,6 +61005,13 @@ var init_recover = __esm({
60856
61005
  seedBytes3 = (state) => Uint8Array.from(Buffer.from(state.seedHex, "hex"));
60857
61006
  REPLAY_VALUES = /* @__PURE__ */ new Map();
60858
61007
  REPLAY_VALUES_MAX = 5e4;
61008
+ DECRYPTED = /* @__PURE__ */ new Map();
61009
+ DECRYPTED_MAX = 5e4;
61010
+ copyOutputs = (outputs) => outputs.map((output2) => ({
61011
+ ...output2,
61012
+ ...output2.account ? { account: { ...output2.account } } : {},
61013
+ ...output2.note ? { note: { ...output2.note } } : {}
61014
+ }));
60859
61015
  hexOf2 = (value) => String(value).replace(/^0x/, "").toLowerCase();
60860
61016
  }
60861
61017
  });
@@ -62284,8 +62440,11 @@ var init_errorCodes = __esm({
62284
62440
  "programdata_address_mismatch",
62285
62441
  "programdata_derivation_drift",
62286
62442
  "recovery_program_unexpectedly_deployed",
62443
+ "rpc_file_empty",
62287
62444
  "rpc_file_invalid",
62288
62445
  "rpc_file_unreadable",
62446
+ "rpc_flag_value_missing",
62447
+ "rpc_flags_conflict",
62289
62448
  "settler_is_retired_production_settler",
62290
62449
  "settler_is_staging_settler",
62291
62450
  "settler_is_upgrade_authority",
@@ -70161,13 +70320,13 @@ function readPoolDenominationFlag(args) {
70161
70320
  if (typeof value !== "string" || value === "" || value.startsWith("--")) return "";
70162
70321
  return value;
70163
70322
  }
70164
- function resolveExitDenominationPolicy({ pool: pool2, flagValue, envValue, allowOffDenomination = false }) {
70323
+ function resolveExitDenominationPolicy({ pool: pool2, flagValue: flagValue2, envValue, allowOffDenomination = false }) {
70165
70324
  let poolDenominationAtomic;
70166
70325
  let configError;
70167
70326
  const warnings = [];
70168
- if (flagValue !== void 0) {
70169
- if (isCanonicalDenominationAtomic(flagValue)) poolDenominationAtomic = flagValue;
70170
- else if (flagValue === "") configError = "--pool-denomination requires a value";
70327
+ if (flagValue2 !== void 0) {
70328
+ if (isCanonicalDenominationAtomic(flagValue2)) poolDenominationAtomic = flagValue2;
70329
+ else if (flagValue2 === "") configError = "--pool-denomination requires a value";
70171
70330
  else configError = "--pool-denomination must be a canonical positive u64 atomic string";
70172
70331
  } else if (envValue !== void 0 && envValue !== "") {
70173
70332
  let map;
@@ -70805,8 +70964,8 @@ async function runRecoverCommand(args) {
70805
70964
  }
70806
70965
  const pool2 = flag(args, "--pool") ?? requiredPoolFromHome();
70807
70966
  const store = openWalletStore(walletPath(pool2), passphrase());
70808
- const rpcUrl = flag(args, "--rpc") ?? process.env.UNDERMARKET_SOLANA_RPC_URL;
70809
- if (!rpcUrl) throw new Error("recover requires --rpc or UNDERMARKET_SOLANA_RPC_URL");
70967
+ const rpcUrl = resolveRpcUrl(args);
70968
+ if (!rpcUrl) throw new Error("rpc_required: recover requires --rpc-file <file> (or --rpc, or UNDERMARKET_SOLANA_RPC_URL)");
70810
70969
  const programId = flag(args, "--program");
70811
70970
  if (!programId) throw new Error("recover requires --program <program id>");
70812
70971
  const digestsFile = flag(args, "--digests");
@@ -70914,7 +71073,7 @@ async function main(argv = process.argv.slice(2)) {
70914
71073
  case "status": {
70915
71074
  const pool2 = flag(args, "--pool") ?? requiredPoolFromHome();
70916
71075
  const store = openWalletStore(walletPath(pool2), passphrase());
70917
- const rpcUrl = flag(args, "--rpc") ?? process.env.UNDERMARKET_SOLANA_RPC_URL;
71076
+ const rpcUrl = resolveRpcUrl(args);
70918
71077
  const solana = import_web3105.Keypair.fromSecretKey(Uint8Array.from(store.state.solanaSecretKey));
70919
71078
  const report = {
70920
71079
  pool: canonicalPoolKey(store.state.pool),
@@ -70960,11 +71119,11 @@ async function main(argv = process.argv.slice(2)) {
70960
71119
  await runValueMove(command, args);
70961
71120
  return;
70962
71121
  case "deposit-compact":
70963
- return runDepositCompactCommand(args, { flag, walletPath, acquireLease: acquireWalletProcessLease, openStore: (pool2) => openWalletStore(walletPath(pool2), passphrase()), connect });
71122
+ return runDepositCompactCommand(args, { flag, rpcUrl: (cliArgs) => resolveRpcUrl(cliArgs), walletPath, acquireLease: acquireWalletProcessLease, openStore: (pool2) => openWalletStore(walletPath(pool2), passphrase()), connect });
70964
71123
  case "deposit-reclaim":
70965
- return runDepositReclaimCommand(args, { flag, openStore: (pool2) => openWalletStore(walletPath(pool2), passphrase()), connect });
71124
+ return runDepositReclaimCommand(args, { flag, rpcUrl: (cliArgs) => resolveRpcUrl(cliArgs), openStore: (pool2) => openWalletStore(walletPath(pool2), passphrase()), connect });
70966
71125
  case "deposit-scan":
70967
- return runDepositScanCommand(args, { flag, openStore: (pool2) => openWalletStore(walletPath(pool2), passphrase()), connect });
71126
+ return runDepositScanCommand(args, { flag, rpcUrl: (cliArgs) => resolveRpcUrl(cliArgs), openStore: (pool2) => openWalletStore(walletPath(pool2), passphrase()), connect });
70968
71127
  case "withdraw": {
70969
71128
  await runValueMove(command, args);
70970
71129
  return;
@@ -70972,8 +71131,8 @@ async function main(argv = process.argv.slice(2)) {
70972
71131
  case "note-exit": {
70973
71132
  const pool2 = flag(args, "--pool") ?? requiredPoolFromHome();
70974
71133
  const store = openWalletStore(walletPath(pool2), passphrase());
70975
- const rpcUrl = flag(args, "--rpc") ?? process.env.UNDERMARKET_SOLANA_RPC_URL;
70976
- if (!rpcUrl) throw new Error("note-exit requires --rpc or UNDERMARKET_SOLANA_RPC_URL");
71134
+ const rpcUrl = resolveRpcUrl(args);
71135
+ if (!rpcUrl) throw new Error("rpc_required: note-exit requires --rpc-file <file> (or --rpc, or UNDERMARKET_SOLANA_RPC_URL)");
70977
71136
  const programId = flag(args, "--program");
70978
71137
  const recipientTokenAccount = flag(args, "--to");
70979
71138
  const serviceUrl2 = flag(args, "--service");
@@ -71094,18 +71253,18 @@ async function main(argv = process.argv.slice(2)) {
71094
71253
  "usage: shielded-wallet <init|restore|address|status|deposit|pay|withdraw|recover|note-exit|backup-export|backup-verify> [options]",
71095
71254
  " restore --pool <pubkey> --network <caip-2> --asset <mint> --recovery <init's recovery file>",
71096
71255
  " (a lost wallet from init's recovery text; then recover, deposit-scan, pocket scan)",
71097
- " deposit --pool <pubkey> --program <id> --proof-tools <file> --deposit-id <id> --amount <atomic> [--rpc <url>]",
71256
+ " deposit --pool <pubkey> --program <id> --proof-tools <file> --deposit-id <id> --amount <atomic> [--rpc-file <file>]",
71098
71257
  " (first run proves and records; back up; then add --submit --service <url>)",
71099
71258
  " [--relay --service <url> [--one-time-index <n>]] USDC from a one-time address; the facilitator pays every fee",
71100
- " deposit-reclaim --pool <pubkey> --program <id> --deposit-id <id> --to <token account> (--service <url> | --fee-payer-key-file <file>) [--rpc <url>]",
71259
+ " deposit-reclaim --pool <pubkey> --program <id> --deposit-id <id> --to <token account> (--service <url> | --fee-payer-key-file <file>) [--rpc-file <file>]",
71101
71260
  " (a relayed deposit that did not land: its USDC back out of the one-time address)",
71102
- " deposit-scan --pool <pubkey> [--from <index>] [--count <n>] [--rpc <url>]",
71261
+ " deposit-scan --pool <pubkey> [--from <index>] [--count <n>] [--rpc-file <file>]",
71103
71262
  " (after a restore from the recovery text: funded one-time addresses in one index range, default 0-63)",
71104
71263
  " backup-export --pool <pubkey> --to <new directory>",
71105
71264
  " backup-verify --pool <pubkey> --backup-dir <directory>",
71106
- " recover --pool <pubkey> --program <id> --proof-tools <file> [--rpc <url>] [--fresh] [--history-rpc <own|url>]",
71265
+ " recover --pool <pubkey> --program <id> --proof-tools <file> [--rpc-file <file>] [--fresh] [--history-rpc <own|url>]",
71107
71266
  " note-exit --pool <pubkey> --program <id> --to <token account> --service <url> --proof-tools <file> [--exit-amount <atomic>]",
71108
- " [--rpc <url>] [--digests <file>] [--note <commitment>]",
71267
+ " [--rpc-file <file>] [--digests <file>] [--note <commitment>]",
71109
71268
  " [--min-delay-ms <ms>] [--jitter-ms <ms>] [--exit-now]",
71110
71269
  " [--pool-denomination <atomic>] [--allow-off-denomination]",
71111
71270
  " [--recipient-owner <pubkey> --allow-foreign-recipient] pay a token account another key owns",
@@ -71122,9 +71281,9 @@ async function runSelfCustodyDeposit(args) {
71122
71281
  const programId = flag(args, "--program");
71123
71282
  const depositId = flag(args, "--deposit-id");
71124
71283
  const amount = flag(args, "--amount");
71125
- const rpcUrl = flag(args, "--rpc") ?? process.env.UNDERMARKET_SOLANA_RPC_URL;
71284
+ const rpcUrl = resolveRpcUrl(args);
71126
71285
  if (!programId || !depositId || !/^[1-9][0-9]*$/.test(amount ?? "") || !rpcUrl) {
71127
- throw new Error("deposit requires --program, --deposit-id, --amount <atomic>, --proof-tools, and --rpc or UNDERMARKET_SOLANA_RPC_URL");
71286
+ throw new Error("deposit requires --program, --deposit-id, --amount <atomic>, --proof-tools, and --rpc-file <file> (or --rpc, or UNDERMARKET_SOLANA_RPC_URL)");
71128
71287
  }
71129
71288
  const proofTools = loadP03PublicPaymentProofTools(flag(args, "--proof-tools"));
71130
71289
  const path = walletPath(pool2);
@@ -71209,7 +71368,7 @@ async function runValueMove(command, args) {
71209
71368
  const { profile, vector, artifactDir, production } = loadProfileDirectory(profileDir);
71210
71369
  const pool2 = new import_web3105.PublicKey(flag(args, "--pool") ?? profile.pool ?? poolFromProfile(profile));
71211
71370
  const store = openWalletStore(walletPath(pool2.toBase58()), passphrase());
71212
- const rpcUrl = flag(args, "--rpc") ?? process.env.UNDERMARKET_SOLANA_RPC_URL ?? profile.rpcUrl;
71371
+ const rpcUrl = resolveRpcUrl(args, { fallback: profile.rpcUrl });
71213
71372
  if (!rpcUrl) throw new Error("an RPC URL is required");
71214
71373
  const connection = connect(rpcUrl);
71215
71374
  await assertBroadcastAllowed(connection);
@@ -71502,6 +71661,7 @@ var init_shielded_wallet = __esm({
71502
71661
  init_notes();
71503
71662
  init_memo();
71504
71663
  init_pool_denomination();
71664
+ init_rpc_url();
71505
71665
  init_prove();
71506
71666
  init_chain();
71507
71667
  init_store2();
@@ -72614,6 +72774,7 @@ async function prepareRecoveredPayment({
72614
72774
  circuitSource,
72615
72775
  anchor
72616
72776
  });
72777
+ markPhase("account-path");
72617
72778
  }
72618
72779
  if (wantedNotes.length > MAX_RESPEND_NOTES) fail15("too_many_notes");
72619
72780
  if (wantedNotes.length > 0) await prepareFold(deps.buildRecoveryPath);
@@ -72623,11 +72784,13 @@ async function prepareRecoveredPayment({
72623
72784
  circuitSource,
72624
72785
  anchor
72625
72786
  }));
72787
+ markPhase("note-paths");
72626
72788
  if (reserved !== void 0 && [accountPath, ...notePaths].some((path) => path?.replayValue === void 0 || reserved.has(BigInt(path.replayValue).toString()))) {
72627
72789
  heldInputsWait();
72628
72790
  }
72629
72791
  await prepareFold(deps.buildFrontier);
72630
72792
  const frontier = (deps.buildFrontier ?? buildFinalizedP03Frontier)({ history, circuitSource });
72793
+ markPhase("frontier");
72631
72794
  const outputAccountI = anchor.index;
72632
72795
  const atomicOf = (entries, key) => entries.reduce((sum2, entry) => sum2 + BigInt(entry[key].b), 0n);
72633
72796
  if (accountFile === void 0 && accounts.length > 1 && BigInt(account2.account.b) + atomicOf(wantedNotes, "note") < BigInt(witnessQuote.amountAtomic) && atomicOf(accounts, "account") + atomicOf(notes, "note") >= BigInt(witnessQuote.amountAtomic)) {
@@ -92561,7 +92724,11 @@ async function finalizePendingReceipt({ store, connection, programId, name, time
92561
92724
  strict = true;
92562
92725
  const [tipClock, finalClock] = await Promise.all([finalizedClock(connection, "confirmed"), finalizedClock(connection)]);
92563
92726
  const tip = tipClock.slot;
92564
- const target = tip > finalClock.slot ? tip + FINALITY_GATE_MARGIN_SLOTS : tip;
92727
+ let target = tip > finalClock.slot ? tip + FINALITY_GATE_MARGIN_SLOTS : tip;
92728
+ const settleSlot = receiptSettleSlot(record.answeredSettleSlot);
92729
+ if (settleSlot !== void 0 && BigInt(settleSlot) >= tip - FINALITY_GATE_SETTLE_WINDOW_SLOTS && BigInt(settleSlot) + FINALITY_GATE_SETTLE_MARGIN_SLOTS < target) {
92730
+ target = BigInt(settleSlot) + FINALITY_GATE_SETTLE_MARGIN_SLOTS;
92731
+ }
92565
92732
  gateClock = finalClock;
92566
92733
  while (gateClock.slot < target && now() < deadline) {
92567
92734
  await sleep5(Math.min(pollMs, FINALITY_GATE_POLL_MS));
@@ -93231,12 +93398,21 @@ async function payResourceOnce({
93231
93398
  if (landed) recordLandedWithoutAnswer(store, walName2, record);
93232
93399
  throw error;
93233
93400
  }
93234
- store.writeWal(walName2, { ...record, state: "receipt", receipt, resultBase64, receiptFinality: "pending", answeredAtMs: Date.now() });
93401
+ const answeredSettleSlot = receiptSettleSlot(receipt.extra?.settleSlot);
93402
+ store.writeWal(walName2, {
93403
+ ...record,
93404
+ state: "receipt",
93405
+ receipt,
93406
+ resultBase64,
93407
+ receiptFinality: "pending",
93408
+ answeredAtMs: Date.now(),
93409
+ ...answeredSettleSlot !== void 0 ? { answeredSettleSlot } : {}
93410
+ });
93235
93411
  mark("receipt-pending");
93236
93412
  withPhaseScope(mark, "anchor-next", () => requestSubAnchorForNewLeaf());
93237
93413
  return { replayed: false, receipt, resultBase64, receiptFinality: "pending" };
93238
93414
  }
93239
- var import_web3111, fail19, failUnresolved, hash9, OWNER_UNSHIELD_REQUEST, OWNER_UNSHIELD_ORIGIN, POCKET_FILL_ID, POOL_MOVE_PATH, RECEIPT_FINALITY_TIMEOUT_MS, RECEIPT_FINALITY_POLL_MS, FINALITY_GATE_MARGIN_SLOTS, FINALITY_GATE_POLL_MS, FINALITY_GATE_SKIP_AFTER_MS, PENDING_FINALITY, isPending, REPLAY_INPUTS, PAYMENT_OUTPUT_INPUT2, QUOTE_MARGIN_SECONDS, SELLER_REFUSED_PAY_AGAIN, SELLER_REASON_FACILITATOR_UNDERFUNDED, ANCHOR_EPOCH_MS, ANCHOR_MARGIN_MS, ANCHOR_WAIT_CAP_MS, DEAD_PAYMENT_MARGIN_SECONDS, SYSVAR_OWNER, quoteLiveAt, replayValuesOf, finalPayments, FINAL_UNCHANGED;
93415
+ var import_web3111, fail19, failUnresolved, hash9, OWNER_UNSHIELD_REQUEST, OWNER_UNSHIELD_ORIGIN, POCKET_FILL_ID, POOL_MOVE_PATH, RECEIPT_FINALITY_TIMEOUT_MS, RECEIPT_FINALITY_POLL_MS, FINALITY_GATE_MARGIN_SLOTS, FINALITY_GATE_POLL_MS, FINALITY_GATE_SETTLE_MARGIN_SLOTS, FINALITY_GATE_SETTLE_WINDOW_SLOTS, receiptSettleSlot, FINALITY_GATE_SKIP_AFTER_MS, PENDING_FINALITY, isPending, REPLAY_INPUTS, PAYMENT_OUTPUT_INPUT2, QUOTE_MARGIN_SECONDS, SELLER_REFUSED_PAY_AGAIN, SELLER_REASON_FACILITATOR_UNDERFUNDED, ANCHOR_EPOCH_MS, ANCHOR_MARGIN_MS, ANCHOR_WAIT_CAP_MS, DEAD_PAYMENT_MARGIN_SECONDS, SYSVAR_OWNER, quoteLiveAt, replayValuesOf, finalPayments, FINAL_UNCHANGED;
93240
93416
  var init_payResource = __esm({
93241
93417
  "wallet/src/pay/payResource.mjs"() {
93242
93418
  "use strict";
@@ -93280,6 +93456,9 @@ var init_payResource = __esm({
93280
93456
  RECEIPT_FINALITY_POLL_MS = 2e3;
93281
93457
  FINALITY_GATE_MARGIN_SLOTS = 10n;
93282
93458
  FINALITY_GATE_POLL_MS = 1e3;
93459
+ FINALITY_GATE_SETTLE_MARGIN_SLOTS = 2n;
93460
+ FINALITY_GATE_SETTLE_WINDOW_SLOTS = 150n;
93461
+ receiptSettleSlot = (value) => typeof value === "string" && /^[1-9][0-9]{0,15}$/.test(value) && Number.isSafeInteger(Number(value)) ? value : void 0;
93283
93462
  FINALITY_GATE_SKIP_AFTER_MS = 6e4;
93284
93463
  PENDING_FINALITY = /* @__PURE__ */ new Set(["pending", "confirmed"]);
93285
93464
  isPending = (record) => record?.state === "receipt" && PENDING_FINALITY.has(record.receiptFinality);
@@ -93324,7 +93503,7 @@ async function main2(args = process.argv.slice(2)) {
93324
93503
  const needed = options["cancel-request"] ? ["wallet", "passphrase-file"] : REQUIRED;
93325
93504
  if (needed.some((key) => !options[key])) throw new Error("p03_resource_cli_arguments_missing");
93326
93505
  const historyUrl = historyRpcUrl(options["history-rpc"]);
93327
- const rpcUrl = () => resolveRpcUrl({
93506
+ const rpcUrl = () => resolveRpcUrl2({
93328
93507
  rpcFile: options["rpc-file"],
93329
93508
  origin: options["memo-service"],
93330
93509
  readFile: (path) => readFileSync(resolve16(path), "utf8").trim()
@@ -94673,9 +94852,16 @@ var init_EncryptedJsonFile = __esm({
94673
94852
  }
94674
94853
  /** write(), returning the exact text it put in the file. */
94675
94854
  async writeReturningPayload(value) {
94855
+ return this.writeText(this.encryptToText(value));
94856
+ }
94857
+ /**
94858
+ * write()'s file step for text made by encryptToText (this file's key, or
94859
+ * another file's with the same key): the same temp file, fsync, rename and
94860
+ * directory fsync. Returns the text. Lets a caller that keeps two copies of
94861
+ * one value under one key encrypt it once (the P03 settle journal).
94862
+ */
94863
+ async writeText(payload2) {
94676
94864
  await mkdir3(dirname18(this.filePath), { recursive: true });
94677
- const body = JSON.stringify(value);
94678
- const payload2 = this.keyMaterial ? JSON.stringify(this.encrypt(body)) : body;
94679
94865
  const temporaryPath = `${this.filePath}.${process.pid}.${randomBytes16(6).toString("hex")}.tmp`;
94680
94866
  await writeFile2(temporaryPath, payload2, { mode: 384 });
94681
94867
  if (this.options.durable) {
@@ -94723,7 +94909,11 @@ var init_EncryptedJsonFile = __esm({
94723
94909
  this.writeTextSync(payload2);
94724
94910
  return payload2;
94725
94911
  }
94726
- /** The exact text writeSync would put in the file for `value` (a caller can hash it before the write). */
94912
+ /**
94913
+ * The exact text writeSync would put in the file for `value` (a caller can hash it before the write).
94914
+ * Compact on purpose: the payload is encrypted (pretty-printing ciphertext buys nothing and inflates
94915
+ * every full-file rewrite), and the plaintext fallback only exists for local dev without an encryption key.
94916
+ */
94727
94917
  encryptToText(value) {
94728
94918
  return this.keyMaterial ? JSON.stringify(this.encrypt(JSON.stringify(value))) : JSON.stringify(value);
94729
94919
  }
@@ -96434,7 +96624,10 @@ function publicReceipt(receipt) {
96434
96624
  pool: extra.pool,
96435
96625
  programId: extra.programId,
96436
96626
  quoteCommitment: extra.quoteCommitment,
96437
- memoAvailabilityDigest: extra.memoAvailabilityDigest
96627
+ memoAvailabilityDigest: extra.memoAvailabilityDigest,
96628
+ // The settle's confirmed slot: the payer's next finality gate waits for it (payResource.mjs
96629
+ // FINALITY_GATE_SETTLE_MARGIN_SLOTS, 2026-10-16). A public chain fact of this payment.
96630
+ settleSlot: extra.settleSlot
96438
96631
  }
96439
96632
  };
96440
96633
  }
@@ -97481,7 +97674,7 @@ async function main3(args = process.argv.slice(2)) {
97481
97674
  const feeKey = import_web3121.Keypair.fromSecretKey(Uint8Array.from(store.state.solanaSecretKey)).publicKey;
97482
97675
  const recipientOwner = new import_web3121.PublicKey(options["recipient-owner"]);
97483
97676
  if (recipientOwner.equals(feeKey)) fail28("recipient_owner_is_deposit_key");
97484
- const connection = connect2(resolveRpcUrl({
97677
+ const connection = connect2(resolveRpcUrl2({
97485
97678
  rpcFile: options["rpc-file"],
97486
97679
  origin: origin.origin,
97487
97680
  readFile: (path) => readFileSync(resolve19(path), "utf8").trim()
@@ -116425,7 +116618,7 @@ async function v0bMain(name, values, deps) {
116425
116618
  const rpc3 = values.has("--rpc-file") ? createV0bRpc(readSecretFile(values.get("--rpc-file"), "--rpc-file")) : void 0;
116426
116619
  return print(await v0bBalance({ store, rpc: rpc3 }));
116427
116620
  }
116428
- const rpc2 = createV0bRpc(resolveRpcUrl({
116621
+ const rpc2 = createV0bRpc(resolveRpcUrl2({
116429
116622
  rpcFile: values.get("--rpc-file"),
116430
116623
  env: deps.env ?? process.env,
116431
116624
  origin: values.get("--service"),
@@ -118165,7 +118358,7 @@ function playTokenOf(values) {
118165
118358
  }
118166
118359
  function rpcOf(name, values, { origin, env, err }) {
118167
118360
  if (!(READS_CHAIN.has(name) || name === "laneb receipts" && values.has("--verify") || values.has("--rpc-file"))) return void 0;
118168
- const { url } = resolveRpcUrl({
118361
+ const { url } = resolveRpcUrl2({
118169
118362
  rpcFile: values.get("--rpc-file"),
118170
118363
  env,
118171
118364
  origin,
@@ -121263,7 +121456,7 @@ async function main4(args = process.argv.slice(2), io = { out: (text3) => consol
121263
121456
  io.out(JSON.stringify({ success: true, ...releasePendingFill(store) }));
121264
121457
  return;
121265
121458
  }
121266
- const connection = connect2(resolveRpcUrl({
121459
+ const connection = connect2(resolveRpcUrl2({
121267
121460
  rpcFile: options["rpc-file"],
121268
121461
  origin: options.facilitator,
121269
121462
  readFile: (path) => readFileSync(resolve20(path), "utf8").trim()
@@ -124150,7 +124343,7 @@ function acknowledgeSuccessionNotice(store, fromPool, state, { now = Date.now()
124150
124343
  }
124151
124344
  var MODEL_VECTORS = fileURLToPath16(new URL("../../vendor/shielded-x402-model/vectors/rust-vectors.json", new URL("__bundled_source__/wallet/src/succession/scheduler.mjs", import.meta.url).href));
124152
124345
  var pinnedGenerator6 = () => JSON.parse(readFileSync(MODEL_VECTORS, "utf8")).payerKeys.generator;
124153
- var yieldTurn = () => new Promise((resolveTurn) => {
124346
+ var yieldTurn2 = () => new Promise((resolveTurn) => {
124154
124347
  setImmediate(resolveTurn);
124155
124348
  });
124156
124349
  var CIRCUIT_SOURCE = Object.freeze({ poseidonParametersSha256: P03_PINNED_POSEIDON_PARAMETERS_SHA256, zeroLeaf: P03_PINNED_ZERO_LEAF });
@@ -124174,9 +124367,9 @@ async function prepareSuccessionMove({ entry, verified, store, targetStore, conn
124174
124367
  deploymentIdentity: toolsB.deploymentIdentity
124175
124368
  });
124176
124369
  const recoverSource = async () => {
124177
- await yieldTurn();
124370
+ await yieldTurn2();
124178
124371
  const history2 = await loadHistory({ store, connection: split5, programId: entry.programId, pool: entry.from, deploymentIdentity: toolsA.deploymentIdentity });
124179
- await yieldTurn();
124372
+ await yieldTurn2();
124180
124373
  const successors = await loadSuccessorHistories({
124181
124374
  history: history2,
124182
124375
  store,
@@ -124185,7 +124378,7 @@ async function prepareSuccessionMove({ entry, verified, store, targetStore, conn
124185
124378
  deploymentIdentity: toolsB.deploymentIdentity,
124186
124379
  loadHistory
124187
124380
  });
124188
- await yieldTurn();
124381
+ await yieldTurn2();
124189
124382
  const walStates = captureWalStates(store);
124190
124383
  const recovery2 = await recover({
124191
124384
  store,
@@ -124200,7 +124393,7 @@ async function prepareSuccessionMove({ entry, verified, store, targetStore, conn
124200
124393
  return { recovery: recovery2, history: history2 };
124201
124394
  };
124202
124395
  const { recovery, history } = await recoverSource();
124203
- await yieldTurn();
124396
+ await yieldTurn2();
124204
124397
  const movable = recovery.recovered.filter((output2) => output2.spendStatus === "succession-movable");
124205
124398
  const eta = deriveWalletViewingAuthority2({ seedBytes: Uint8Array.from(Buffer.from(store.state.seedHex, "hex")), generator: pinnedGenerator6() }).eta;
124206
124399
  const anchor = { index: BigInt(verified.record.finalIndex), root: BigInt(`0x${verified.record.finalRoot}`) };
@@ -125832,6 +126025,8 @@ init_serviceUrl();
125832
126025
  init_anchorClock();
125833
126026
  var shownCaps = (caps) => Object.fromEntries(Object.entries(caps).map(([name, value]) => [name, String(value) === NO_LIMIT_ATOMIC2 ? "none" : value]));
125834
126027
  var RESOURCE_PAYMENT_WAL_PREFIX2 = "resource-payment-";
126028
+ var POOL_LAYOUT_CODE = /pool_state_length_or_magic_invalid|pool_layout_table_invalid|pool_state_anchor_layout_invalid/;
126029
+ var POOL_LAYOUT_UPDATE = "This wallet release cannot read the pool account: the pool program most likely changed its layout in an upgrade. Tell the user to restart this MCP server in the host (or restart the host app): each start loads the latest shinjuku-shielded";
125835
126030
  var SELF_PAY_ORIGIN3 = "https://self-pay.invalid/";
125836
126031
  var REQUEST_ID2 = /^[A-Za-z0-9._:-]{1,128}$/;
125837
126032
  var POSITIVE_ATOMIC4 = /^[1-9][0-9]{0,30}$/;
@@ -126271,6 +126466,14 @@ function selfPayMayHaveSigned(store, unshieldId) {
126271
126466
  if (record && record.state !== "started") return true;
126272
126467
  return Boolean(store.readWal(`${RESOURCE_PAYMENT_WAL_PREFIX2}${sha256Hex2(Buffer.from(selfPayRequestId(unshieldId), "utf8"))}`));
126273
126468
  }
126469
+ function leg1SettleSlot(store, float, requestId) {
126470
+ try {
126471
+ const inner = typeof float?.innerRequestId === "string" && float.innerRequestId ? float.innerRequestId : floatInnerRequestId(requestId);
126472
+ return store?.readWal(`${RESOURCE_PAYMENT_WAL_PREFIX2}${sha256Hex2(Buffer.from(inner, "utf8"))}`)?.answeredSettleSlot;
126473
+ } catch {
126474
+ return void 0;
126475
+ }
126476
+ }
126274
126477
  function bindUnshieldRecipient(store, unshieldId, amountAtomic, to) {
126275
126478
  const name = `self-pay-${unshieldId}`;
126276
126479
  const record = store.readWal(name);
@@ -126421,6 +126624,8 @@ var CAP_BALANCE_RETRY_MS = 5e3;
126421
126624
  var REFRESH_RETRY_MS = 6e4;
126422
126625
  var FINALITY_POLL_MS = 2e3;
126423
126626
  var FINALITY_WAIT_MS = 6e4;
126627
+ var FINALITY_REFRESH_LIMIT_MS = 18e4;
126628
+ var FINALITY_SETTLE_WINDOW_SLOTS = 150;
126424
126629
  var PUBLIC_READ_ANSWER_MS = 3e3;
126425
126630
  var SWITCH_WAIT_MS = 4e4;
126426
126631
  var ELICIT_TIMEOUT_MS = 5 * 6e4;
@@ -126488,7 +126693,7 @@ function createWalletTools({
126488
126693
  deps: ops.autoPockets ?? {}
126489
126694
  });
126490
126695
  if (money.autoPockets === true) autoPockets.start();
126491
- const mover = createMoveScheduler({ session, underLease, log, onSettled: refreshAtFinality, deps: ops.move && typeof ops.move === "object" ? ops.move : {} });
126696
+ const mover = createMoveScheduler({ session, underLease, log, onSettled: () => refreshAtFinality(), deps: ops.move && typeof ops.move === "object" ? ops.move : {} });
126492
126697
  if (ops.move !== false) mover.start();
126493
126698
  const succession = ops.succession === false ? void 0 : {
126494
126699
  successionStatus,
@@ -126647,31 +126852,52 @@ function createWalletTools({
126647
126852
  let finalityClosed = false;
126648
126853
  const finalityPollMs = ops.finalityPollMs ?? FINALITY_POLL_MS;
126649
126854
  const finalityWaitMs = ops.finalityWaitMs ?? FINALITY_WAIT_MS;
126650
- function refreshAtFinality(signature) {
126651
- if (typeof signature !== "string" || !signature || finalityClosed) return;
126652
- finalityTarget = signature;
126855
+ const finalityRefreshMs = ops.finalityRefreshMs ?? FINALITY_REFRESH_LIMIT_MS;
126856
+ const readSlot = (commitment) => withTimeout(
126857
+ Promise.resolve().then(() => (ops.slot ?? ((c) => session.connection.getSlot(c)))(commitment)),
126858
+ ops.slotReadMs ?? PUBLIC_READ_TIMEOUT_MS
126859
+ );
126860
+ function refreshAtFinality(settleSlot) {
126861
+ if (finalityClosed) return;
126862
+ const given = typeof settleSlot === "number" && Number.isSafeInteger(settleSlot) && settleSlot >= 0 ? settleSlot : typeof settleSlot === "string" && /^(0|[1-9][0-9]{0,15})$/.test(settleSlot) && Number.isSafeInteger(Number(settleSlot)) ? Number(settleSlot) : void 0;
126863
+ const next = readSlot("confirmed").catch(() => void 0).then((tip) => {
126864
+ if (!Number.isSafeInteger(tip)) return given;
126865
+ if (given === void 0 || given > tip || given < tip - FINALITY_SETTLE_WINDOW_SLOTS) return tip;
126866
+ return given;
126867
+ });
126868
+ const prior = finalityTarget;
126869
+ finalityTarget = Promise.all([prior, next]).then(([a, b]) => {
126870
+ const known = [a, b].filter((slot3) => Number.isSafeInteger(slot3));
126871
+ return known.length ? Math.max(...known) : void 0;
126872
+ });
126653
126873
  finalityDeadline = Date.now() + finalityWaitMs;
126654
- if (finalityWait) return;
126655
- const statuses = ops.signatureStatuses ?? ((signatures) => session.connection.getSignatureStatuses(signatures));
126874
+ if (!finalityWait) startFinalityWait();
126875
+ }
126876
+ function startFinalityWait() {
126877
+ let watched;
126656
126878
  finalityWait = (async () => {
126657
126879
  for (; ; ) {
126658
- const watched = finalityTarget;
126659
- let status;
126880
+ watched = finalityTarget;
126881
+ const target = await watched;
126882
+ if (finalityClosed) return;
126883
+ if (target === void 0) {
126884
+ log("MCP_FINALITY_WAIT_FAILED no settle slot");
126885
+ return;
126886
+ }
126887
+ let finalized;
126660
126888
  try {
126661
- status = (await statuses([watched]))?.value?.[0] ?? void 0;
126889
+ finalized = await readSlot("finalized");
126662
126890
  } catch {
126663
- status = void 0;
126891
+ finalized = void 0;
126664
126892
  }
126665
126893
  if (finalityClosed) return;
126666
- if (watched === finalityTarget && status?.err) {
126667
- log("MCP_FINALITY_WAIT_FAILED_TRANSACTION");
126668
- return;
126669
- }
126670
- if (watched === finalityTarget && status?.confirmationStatus === "finalized") {
126894
+ if (watched === finalityTarget && Number.isSafeInteger(finalized) && finalized >= target) {
126671
126895
  log("MCP_FINALITY_REFRESH");
126672
- await refreshShared({ background: true }).catch(() => {
126896
+ await withTimeout(refreshShared({ background: true }), finalityRefreshMs).catch((error) => {
126897
+ if (error?.timedOut) log("MCP_FINALITY_REFRESH_SLOW");
126673
126898
  });
126674
- return;
126899
+ if (watched === finalityTarget || finalityClosed) return;
126900
+ continue;
126675
126901
  }
126676
126902
  if (Date.now() + finalityPollMs > finalityDeadline) {
126677
126903
  log("MCP_FINALITY_WAIT_EXPIRED");
@@ -126684,6 +126910,8 @@ function createWalletTools({
126684
126910
  }
126685
126911
  })().finally(() => {
126686
126912
  finalityWait = void 0;
126913
+ if (finalityClosed || finalityTarget === watched) finalityTarget = void 0;
126914
+ else startFinalityWait();
126687
126915
  });
126688
126916
  }
126689
126917
  async function refreshIfStale() {
@@ -126969,7 +127197,7 @@ function createWalletTools({
126969
127197
  const floatPaid = float?.state === "receipt";
126970
127198
  const amounts = floatPaid ? { priceAtomic: float.priceAtomic, feeAtomic: float.feeAtomic, amountAtomic: float.paidAtomic } : { priceAtomic: receipt.amountAtomic ?? null, feeAtomic: "0", amountAtomic: receipt.amountAtomic ?? null };
126971
127199
  const one = paidStore ? localBalanceOf(paidStore) : null;
126972
- if (receipt.replayed !== true) refreshAtFinality(floatPaid ? float.floatSettleTransaction : transaction);
127200
+ if (receipt.replayed !== true) refreshAtFinality(floatPaid ? leg1SettleSlot(paidStore, float, requestId) : receipt.extra?.settleSlot);
126973
127201
  mark("mcp-result");
126974
127202
  return answerResult(paidAnswerContent({
126975
127203
  status: response.status,
@@ -127034,6 +127262,8 @@ function createWalletTools({
127034
127262
  next = `PAID: the chain shows the payment landed${error?.transaction ? ` (transaction ${error.transaction})` : ""}, but the seller did not return its answer and refuses the same payment. Do not call x402_pay again with this request_id. Tell the user it was paid without an answer; pay again only with a NEW request_id if the user wants a second payment`;
127035
127263
  } else if (code === "wallet_locked") {
127036
127264
  next = `another shinjuku-wallet command is using this wallet; wait for it, then call x402_pay again with request_id "${requestId}"`;
127265
+ } else if (POOL_LAYOUT_CODE.test(code)) {
127266
+ next = `${POOL_LAYOUT_UPDATE}. Then call x402_pay again with request_id "${requestId}" and the same url, method, headers, and body: it pays once. If the latest release says the same, tell your owner: ${code}`;
127037
127267
  } else if (OWNER_CAP_CODES.has(code)) {
127038
127268
  next = ownerOnlyNext(`${code}: ${rest || "a wallet-file cap refused this payment"}`.replace(/[.;\s]+$/, ""), code);
127039
127269
  } else if (code === "fetch_offer_confidential" || /confidential_(retired|use_laneb_pay_url)$/.test(code)) {
@@ -127557,6 +127787,7 @@ function createWalletTools({
127557
127787
  else if (/insufficient_token_balance|above_balance/.test(code)) next = "Nothing was moved. The wallet's own key holds less public USDC than amount_atomic (wallet_balance unshieldedAtomic). Tell the user, or call wallet_shield with a NEW request_id and a smaller amount_atomic";
127558
127788
  else if (/insufficient_sol/.test(code)) next = `Nothing new was moved. This request_id is a deposit an older version started that pays its own network fee, and the wallet's own key${ownAddress ? ` ${ownAddress}` : " (init's solanaFeePayer)"} holds too little SOL for it. Tell your owner: ${code}. A NEW request_id needs no SOL: the facilitator pays its fees`;
127559
127789
  else if (/pool_at_deposit_cap|pool_value_cap|above_pool_deposit_cap|above_cap|pool_terminal|id_reused/.test(code)) next = `Nothing new was moved. Do not retry this request. Tell your owner: ${code}.${atAddress}`;
127790
+ else if (POOL_LAYOUT_CODE.test(code)) next = `${POOL_LAYOUT_UPDATE}. Then ${again(kind, job)}: it continues where it stopped and never moves the money twice. If the latest release says the same, tell your owner: ${code}`;
127560
127791
  else if (code === "mcp_unshield_to_not_allowed") next = unboundNext(job.requestId, job.amountAtomic);
127561
127792
  else if (code === "mcp_unshield_to_invalid") next = "Nothing was paid. Tell the user: this address has no USDC token account of the pool mint; it must have one first";
127562
127793
  else if (code === "wallet_locked") next = `another shinjuku-wallet command is using this wallet; ${again(kind, job)} in ${POLL_SECONDS2} s: it continues where it stopped and never moves the money twice`;
@@ -127853,7 +128084,7 @@ function createWalletTools({
127853
128084
  job.result = result;
127854
128085
  log(`MCP_${kind.toUpperCase()}_DONE requestId=${job.requestId}`);
127855
128086
  if (kind !== "unshield") afterShield(job);
127856
- else refreshAtFinality(result?.exitTransaction ?? result?.selfPayTransaction);
128087
+ else refreshAtFinality();
127857
128088
  }, (error) => {
127858
128089
  job.failedStage = job.stage;
127859
128090
  job.state = "failed";
@@ -128132,7 +128363,7 @@ function createWalletTools({
128132
128363
  session,
128133
128364
  underLease,
128134
128365
  log,
128135
- deps: { onSettled: refreshAtFinality }
128366
+ deps: { onSettled: () => refreshAtFinality() }
128136
128367
  });
128137
128368
  } catch (error) {
128138
128369
  log(`MCP_POOL_SWITCH_SCHEDULER_NOT_STARTED: ${error?.name ?? "Error"}`);
@@ -129467,7 +129698,7 @@ async function main5(args = process.argv.slice(2)) {
129467
129698
  let steps;
129468
129699
  const runOne = async ({ id, amountAtomic, accountCommitment: accountCommitment3 }) => {
129469
129700
  if (!steps) {
129470
- const connection = connect2(resolveRpcUrl({
129701
+ const connection = connect2(resolveRpcUrl2({
129471
129702
  rpcFile: options["rpc-file"],
129472
129703
  origin: origin.origin,
129473
129704
  readFile: (path) => readFileSync(resolve27(path), "utf8").trim()
@@ -130090,7 +130321,7 @@ async function main6(args = process.argv.slice(2)) {
130090
130321
  try {
130091
130322
  const store = openWalletStore(walletPath2, passphrase2);
130092
130323
  timing("store-open");
130093
- const connection = connect2(resolveRpcUrl({
130324
+ const connection = connect2(resolveRpcUrl2({
130094
130325
  rpcFile: options["rpc-file"],
130095
130326
  origin: options["memo-service"],
130096
130327
  readFile: (path) => readFileSync(resolve28(path), "utf8").trim()
@@ -130168,7 +130399,7 @@ async function keepWarmOnce(values, { io, env = process.env }) {
130168
130399
  const walletPath2 = resolve29(values.get("--wallet"));
130169
130400
  const passphrase2 = assertPassphrase(values.has("--passphrase-file") ? readFileSync(resolve29(values.get("--passphrase-file")), "utf8").trim() : String(env.SHIELDED_WALLET_PASSPHRASE ?? ""));
130170
130401
  const store = openWalletStore(walletPath2, passphrase2);
130171
- const connection = connect2(resolveRpcUrl({
130402
+ const connection = connect2(resolveRpcUrl2({
130172
130403
  rpcFile: values.get("--rpc-file"),
130173
130404
  origin: values.get("--memo-service"),
130174
130405
  readFile: (path) => readFileSync(resolve29(path), "utf8").trim()
@@ -133261,7 +133492,7 @@ async function addFunds(values, deps) {
133261
133492
  const { io } = deps;
133262
133493
  const run5 = runValues(values, deps);
133263
133494
  const passphrase2 = readPrivateLine(run5.passphraseFile, "--passphrase-file");
133264
- const rpcUrl = run5.rpcFile !== void 0 ? readPrivateLine(run5.rpcFile, "--rpc-file") : resolveRpcUrl({ env: deps.env, origin: run5.service, notice: (text3) => io.err(text3) }).url;
133495
+ const rpcUrl = run5.rpcFile !== void 0 ? readPrivateLine(run5.rpcFile, "--rpc-file") : resolveRpcUrl2({ env: deps.env, origin: run5.service, notice: (text3) => io.err(text3) }).url;
133265
133496
  if (values.get("--route") === "privacy-cash") {
133266
133497
  try {
133267
133498
  run5.source = readSourceKeyFile(run5.fromKeyFile).publicKey.toBase58();
@@ -133672,7 +133903,7 @@ var sessionLease = (session) => (task) => {
133672
133903
  };
133673
133904
  return typeof session.serial === "function" ? session.serial(run5) : run5();
133674
133905
  };
133675
- var spendRpcUrl = (values, deps) => deps.rpcUrlFromFile ?? values.get("--rpc") ?? deps.env[RPC_ENV3] ?? resolveRpcUrl({
133906
+ var spendRpcUrl = (values, deps) => deps.rpcUrlFromFile ?? values.get("--rpc") ?? deps.env[RPC_ENV3] ?? resolveRpcUrl2({
133676
133907
  env: {},
133677
133908
  origin: facilitatorOriginOf(values.get("--service"), values.get("--facilitator"), values.get("--memo-service")),
133678
133909
  notice: () => {
@@ -135386,7 +135617,7 @@ async function runMoveCommand(values, deps, io) {
135386
135617
  `);
135387
135618
  return;
135388
135619
  }
135389
- const rpcUrl = values.has("--rpc-file") ? deps.readRpcFile(values.get("--rpc-file")) : deps.env[RPC_ENV3] || resolveRpcUrl({ env: {}, origin: facilitator, notice: io.err }).url;
135620
+ const rpcUrl = values.has("--rpc-file") ? deps.readRpcFile(values.get("--rpc-file")) : deps.env[RPC_ENV3] || resolveRpcUrl2({ env: {}, origin: facilitator, notice: io.err }).url;
135390
135621
  const lease = (walletFile) => async (task) => {
135391
135622
  let release;
135392
135623
  try {
@@ -135740,7 +135971,7 @@ function rpcFileArgs(command, args, values, deps, io) {
135740
135971
  const index = args.indexOf("--rpc-file");
135741
135972
  return { args: [...args.slice(0, index), "--rpc", url2, ...args.slice(index + 2)], url: url2 };
135742
135973
  }
135743
- const { url } = resolveRpcUrl({ env: {}, origin: facilitatorOriginOf(values.get("--service"), values.get("--facilitator"), values.get("--memo-service")), notice: io.err });
135974
+ const { url } = resolveRpcUrl2({ env: {}, origin: facilitatorOriginOf(values.get("--service"), values.get("--facilitator"), values.get("--memo-service")), notice: io.err });
135744
135975
  return { args: [...args, "--rpc", url], url };
135745
135976
  }
135746
135977
  function runSellerIdentity(values, deps, io) {
@@ -136110,7 +136341,7 @@ async function adoptOneTimeForBalance({ store, values, deps, io }) {
136110
136341
  const pools = [...config ? knownPools(config) : [], ...Object.keys(RETIRED_POOLS)];
136111
136342
  const wallets = openEarlierWallets({ home, store, passphrase: deps.env[PASSPHRASE_ENV2], pools });
136112
136343
  if (!wallets.some((wallet) => wallet.state === "open")) return [];
136113
- const rpcUrl = values.get("--rpc") ?? deps.rpcUrlFromFile ?? deps.env[RPC_ENV3] ?? resolveRpcUrl({ env: {}, origin: new URL(values.get("--service")).origin, notice: io.err }).url;
136344
+ const rpcUrl = values.get("--rpc") ?? deps.rpcUrlFromFile ?? deps.env[RPC_ENV3] ?? resolveRpcUrl2({ env: {}, origin: new URL(values.get("--service")).origin, notice: io.err }).url;
136114
136345
  return await adoptOneTimeDeposits({ wallets, run: {
136115
136346
  store,
136116
136347
  connection: (deps.connectRpc ?? connect2)(rpcUrl, "finalized"),
@@ -136811,7 +137042,7 @@ async function runShinjukuWallet(argv, overrides = {}) {
136811
137042
  applyStoredChannel({ home: setupHome(runDeps.env) });
136812
137043
  } catch {
136813
137044
  }
136814
- const familyRpcUrl = () => rpc2.url ?? values.get("--rpc") ?? runDeps.env[RPC_ENV3] ?? resolveRpcUrl({
137045
+ const familyRpcUrl = () => rpc2.url ?? values.get("--rpc") ?? runDeps.env[RPC_ENV3] ?? resolveRpcUrl2({
136815
137046
  env: {},
136816
137047
  origin: facilitatorOriginOf(values.get("--service"), values.get("--facilitator"), values.get("--memo-service")),
136817
137048
  notice: io.err