shinjuku-shielded 0.3.40 → 0.3.41

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": "5b21a788efa0e47f3e83f413f73a4c11a70f068edda47f4f68be3bd6c0855955",
5
- "bytes": 11226333,
6
- "sourceCommit": "40a82beaab73a8c1e1dbd6d44682b4d2cd93e402",
4
+ "sha256": "387938b415cfece575952e875ecafc7149e29279e202a4e862433f66f664a803",
5
+ "bytes": 11230018,
6
+ "sourceCommit": "60acd91587cd5576b91001c7dcdabbb1c0f723aa",
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.40",
3
+ "version": "0.3.41",
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": "5b21a788",
7
- "shinjukuSha256": "5b21a788efa0e47f3e83f413f73a4c11a70f068edda47f4f68be3bd6c0855955",
6
+ "shinjukuRelease": "387938b4",
7
+ "shinjukuSha256": "387938b415cfece575952e875ecafc7149e29279e202a4e862433f66f664a803",
8
8
  "license": "SEE LICENSE IN LICENSE.txt",
9
9
  "author": "Shinjuku Shielded",
10
10
  "homepage": "https://github.com/ShinjukuStaition/shinjuku-mcp#readme",
@@ -48426,10 +48426,21 @@ function walNames(directory) {
48426
48426
  });
48427
48427
  }
48428
48428
  function bindWalDirectory(directory, key, claim = true) {
48429
- mkdirSync(directory, { recursive: true, mode: 448 });
48430
48429
  const ownerPath = join3(directory, WAL_OWNER_FILE);
48430
+ const verified = verifiedWalOwners.get(key);
48431
+ try {
48432
+ if (verified?.get(resolve3(directory)) === ownerStatId(ownerPath)) return;
48433
+ } catch {
48434
+ }
48435
+ mkdirSync(directory, { recursive: true, mode: 448 });
48431
48436
  const identity = createHmac("sha256", key).update(WAL_OWNER_SCHEMA).digest("hex");
48432
48437
  const verifyOwner = () => {
48438
+ let statId;
48439
+ try {
48440
+ statId = ownerStatId(ownerPath);
48441
+ } catch {
48442
+ statId = void 0;
48443
+ }
48433
48444
  let owner;
48434
48445
  try {
48435
48446
  owner = JSON.parse(readFileSync(ownerPath, "utf8"));
@@ -48439,6 +48450,10 @@ function bindWalDirectory(directory, key, claim = true) {
48439
48450
  if (owner?.schema !== WAL_OWNER_SCHEMA || owner.identity !== identity || Object.keys(owner).sort().join() !== "identity,schema") {
48440
48451
  throw new WalletStoreError("wallet_wal_owner_mismatch");
48441
48452
  }
48453
+ if (statId === void 0) return;
48454
+ let byDirectory = verifiedWalOwners.get(key);
48455
+ if (!byDirectory) verifiedWalOwners.set(key, byDirectory = /* @__PURE__ */ new Map());
48456
+ byDirectory.set(resolve3(directory), statId);
48442
48457
  };
48443
48458
  if (existsSync(ownerPath)) {
48444
48459
  verifyOwner();
@@ -48571,7 +48586,7 @@ function openWalletStore(path, passphrase2) {
48571
48586
  };
48572
48587
  return store;
48573
48588
  }
48574
- var STORE_SCHEMA, WAL_SCHEMA, SCRYPT, WAL_OWNER_FILE, WAL_OWNER_SCHEMA, WalletStoreError, KEY_CACHE_LIMIT, keyCacheSecret, keyCache, keyStats, keyCacheId, rememberKey, assertPassphrase, assertWalName;
48589
+ var STORE_SCHEMA, WAL_SCHEMA, SCRYPT, WAL_OWNER_FILE, WAL_OWNER_SCHEMA, WalletStoreError, KEY_CACHE_LIMIT, keyCacheSecret, keyCache, keyStats, keyCacheId, rememberKey, verifiedWalOwners, ownerStatId, assertPassphrase, assertWalName;
48575
48590
  var init_store = __esm({
48576
48591
  "wallet/src/store/store.mjs"() {
48577
48592
  "use strict";
@@ -48597,6 +48612,11 @@ var init_store = __esm({
48597
48612
  keyCache.set(id, key);
48598
48613
  while (keyCache.size > KEY_CACHE_LIMIT) keyCache.delete(keyCache.keys().next().value);
48599
48614
  };
48615
+ verifiedWalOwners = /* @__PURE__ */ new WeakMap();
48616
+ ownerStatId = (path) => {
48617
+ const stat = statSync(path, { bigint: true });
48618
+ return `${stat.dev}:${stat.ino}:${stat.size}:${stat.mtimeNs}:${stat.ctimeNs}`;
48619
+ };
48600
48620
  assertPassphrase = (passphrase2) => {
48601
48621
  if (typeof passphrase2 !== "string" || passphrase2.length < 8) {
48602
48622
  throw new WalletStoreError("wallet_passphrase_too_short: the wallet passphrase must be at least 8 characters");
@@ -56623,6 +56643,23 @@ function walletCompactHistoryCache(store) {
56623
56643
  async function loadWalletP03History(args) {
56624
56644
  const runKey = lastRunReportKey(args.store, args.programId, args.pool, args.deploymentIdentity, args.cache);
56625
56645
  const prewarm = runKey === void 0 ? void 0 : prewarmedWalks.get(runKey);
56646
+ const share = args.share;
56647
+ if (share !== void 0) {
56648
+ if (prewarm !== void 0 && strictScope.getStore() !== true && args.forceRead !== true && Number.isFinite(share.notBeforeMs) && prewarm.startedAt >= share.notBeforeMs && Date.now() - prewarm.startedAt <= HISTORY_PREWARM_JOIN_MS) {
56649
+ try {
56650
+ const report3 = await prewarm.promise;
56651
+ PREWARMED_REPORTS.add(report3);
56652
+ markPhase("walk-prewarm-shared");
56653
+ return report3;
56654
+ } catch {
56655
+ }
56656
+ }
56657
+ const { share: _share, ...walkArgs } = args;
56658
+ const startedAt2 = Date.now();
56659
+ const report2 = await loadWalletP03HistoryNow(walkArgs);
56660
+ if (runKey !== void 0) recentLoads.set(runKey, { startedAt: startedAt2, report: report2 });
56661
+ return report2;
56662
+ }
56626
56663
  if (prewarm !== void 0) {
56627
56664
  prewarmedWalks.delete(runKey);
56628
56665
  if (strictScope.getStore() !== true && args.forceRead !== true && Date.now() - prewarm.startedAt <= HISTORY_PREWARM_JOIN_MS) {
@@ -96638,6 +96675,30 @@ function sellerHttpReply(result) {
96638
96675
  const body = result.result ? Buffer.from(result.result.bodyBase64, "base64") : Buffer.from(JSON.stringify(result.paymentRequired ?? { code: result.code, ...result.reason === FACILITATOR_UNDERFUNDED ? { reason: result.reason } : {} }));
96639
96676
  return { status: result.status, headers, body };
96640
96677
  }
96678
+ function earlyConfirmedTransaction(connection, signature) {
96679
+ if (typeof connection.getTransaction !== "function" || typeof connection.getVerifiedTransaction === "function" || typeof connection.getVerifiedTransactions === "function") {
96680
+ return void 0;
96681
+ }
96682
+ return connection.getTransaction(signature, CONFIRMED_TRANSACTION_READ).then((raw) => raw ?? null, () => null);
96683
+ }
96684
+ function withPrefetchedTransaction(connection, signature, prefetched) {
96685
+ let pending = prefetched;
96686
+ const getTransaction = (requested, options) => {
96687
+ if (pending && requested === signature && options?.commitment === CONFIRMED_TRANSACTION_READ.commitment && options?.maxSupportedTransactionVersion === CONFIRMED_TRANSACTION_READ.maxSupportedTransactionVersion) {
96688
+ const answer = pending;
96689
+ pending = void 0;
96690
+ return Promise.resolve(answer);
96691
+ }
96692
+ return connection.getTransaction(requested, options);
96693
+ };
96694
+ return new Proxy(connection, {
96695
+ get(target, property) {
96696
+ if (property === "getTransaction") return getTransaction;
96697
+ const value = Reflect.get(target, property, target);
96698
+ return typeof value === "function" ? value.bind(target) : value;
96699
+ }
96700
+ });
96701
+ }
96641
96702
  async function createSellerAdapter({
96642
96703
  config,
96643
96704
  connection,
@@ -96953,11 +97014,21 @@ async function createSellerAdapter({
96953
97014
  mark("receipt-unverified");
96954
97015
  return completed2;
96955
97016
  }
96956
- const status = await visibleReceiptStatus(connection, receipt.transaction, visibility);
97017
+ const early = earlyConfirmedTransaction(connection, receipt.transaction);
97018
+ let polled = false;
97019
+ const status = await visibleReceiptStatus(
97020
+ connection,
97021
+ receipt.transaction,
97022
+ { ...visibility, sleep: (ms) => {
97023
+ polled = true;
97024
+ return visibility.sleep(ms);
97025
+ } }
97026
+ );
96957
97027
  const level = receiptStatusLevel(status);
96958
97028
  if (!level || require2 === "finalized" && level !== "finalized") fail26("receipt_pending");
97029
+ const prefetched = early && !polled && level === "confirmed" ? await early : null;
96959
97030
  await validateReceiptTransaction(
96960
- connection,
97031
+ prefetched ? withPrefetchedTransaction(connection, receipt.transaction, prefetched) : connection,
96961
97032
  receipt,
96962
97033
  { paymentHeader: offer.paymentHeader },
96963
97034
  { pool: profile.pool },
@@ -97289,7 +97360,7 @@ async function createSellerAdapter({
97289
97360
  }));
97290
97361
  return { server, handle, close, signerPublicKey, settledTransactions, offerSummaries };
97291
97362
  }
97292
- var import_web3120, BINDING, SCHEMA2, OFFERS_LAYOUT, SNAPSHOT_EVERY_MS, LOADER2, canonical4, storeProfileIdentity, jsonSafe, bigint, encodeHeader, PAYMENT_REFUSED, FACILITATOR_UNDERFUNDED, DEFINITE_VERIFY_REFUSALS, definiteVerifyRefusal, refusedBeforeSettlement, ANCHOR_REQUEST_TIMEOUT_MS2, ANCHOR_POLL_ATTEMPTS, ANCHOR_POLL_MS, PRE_SETTLE_REUSE_MARGIN_S, PRE_SETTLE_REUSE_MAX_AGE_MS, FINALIZED_MEMO_MAX_AGE_MS, pause, FOLLOW_UP_DELAYS_MS, FOLLOW_UP_RESETTLE_FROM;
97363
+ var import_web3120, BINDING, SCHEMA2, OFFERS_LAYOUT, SNAPSHOT_EVERY_MS, LOADER2, canonical4, storeProfileIdentity, jsonSafe, bigint, encodeHeader, PAYMENT_REFUSED, FACILITATOR_UNDERFUNDED, DEFINITE_VERIFY_REFUSALS, definiteVerifyRefusal, refusedBeforeSettlement, ANCHOR_REQUEST_TIMEOUT_MS2, ANCHOR_POLL_ATTEMPTS, ANCHOR_POLL_MS, PRE_SETTLE_REUSE_MARGIN_S, PRE_SETTLE_REUSE_MAX_AGE_MS, FINALIZED_MEMO_MAX_AGE_MS, pause, FOLLOW_UP_DELAYS_MS, FOLLOW_UP_RESETTLE_FROM, CONFIRMED_TRANSACTION_READ;
97293
97364
  var init_service = __esm({
97294
97365
  "wallet/src/seller/service.mjs"() {
97295
97366
  "use strict";
@@ -97358,6 +97429,7 @@ var init_service = __esm({
97358
97429
  6e5
97359
97430
  ]);
97360
97431
  FOLLOW_UP_RESETTLE_FROM = 4;
97432
+ CONFIRMED_TRANSACTION_READ = Object.freeze({ commitment: "confirmed", maxSupportedTransactionVersion: 1 });
97361
97433
  }
97362
97434
  });
97363
97435
 
@@ -97533,20 +97605,19 @@ async function selfPay({
97533
97605
  ...record,
97534
97606
  state: "paid",
97535
97607
  transaction,
97536
- noteCommitment: (deps.findNote ?? selfPaidNoteCommitment)(store, unshieldId, eta).toString()
97608
+ noteCommitment: (await (deps.findNote ?? selfPaidNoteCommitment)(store, unshieldId, eta)).toString()
97537
97609
  };
97538
97610
  store.writeWal(name, record);
97539
97611
  return record;
97540
97612
  }
97541
- function selfPaidNoteCommitment(store, unshieldId, eta) {
97613
+ async function selfPaidNoteCommitment(store, unshieldId, eta) {
97542
97614
  const key = sha256Hex2(Buffer.from(selfPayRequestId(unshieldId), "utf8"));
97543
97615
  const payment = store.readWal(`resource-payment-${key}`);
97544
97616
  const proof = store.readWal(`resource-proof-${key}`)?.proved?.output;
97545
97617
  const accepted = payment?.paymentRequired?.accepts?.find((entry) => entry.scheme === "shielded-exact");
97546
97618
  if (!proof?.memoBundleHex || !accepted) fail27("payment_wal_missing");
97547
- const { accepted: outputs } = trialDecryptBundle({
97619
+ const [{ accepted: outputs }] = await trialDecryptBundles([{
97548
97620
  bundleBytes: Uint8Array.from(Buffer.from(proof.memoBundleHex.replace(/^0x/, ""), "hex")),
97549
- eta,
97550
97621
  poolDomain: BigInt(proof.poolDomain),
97551
97622
  outCommitment: BigInt(proof.outCommitment),
97552
97623
  contextCommitment: BigInt(proof.quoteCommitment),
@@ -97554,7 +97625,7 @@ function selfPaidNoteCommitment(store, unshieldId, eta) {
97554
97625
  transitionKind: 2,
97555
97626
  zeroLeaf: P03_PINNED_ZERO_LEAF,
97556
97627
  subtreeStartIndex: 0n
97557
- });
97628
+ }], eta);
97558
97629
  const notes = outputs.filter((entry) => entry.kind === "note");
97559
97630
  if (notes.length !== 1 || notes[0].note.b !== BigInt(proof.amountAtomic)) fail27("self_paid_note_not_found");
97560
97631
  return notes[0].commitment;
@@ -97566,7 +97637,7 @@ var init_selfPay = __esm({
97566
97637
  init_fs();
97567
97638
  init_service();
97568
97639
  init_notes2();
97569
- init_memo2();
97640
+ init_memoDecryptPool();
97570
97641
  init_store();
97571
97642
  init_recoveryPath();
97572
97643
  init_payResource();
@@ -126400,16 +126471,17 @@ async function runShieldFromElsewhere({ session, depositId, amountAtomic, onStag
126400
126471
  const result = await (steps.submit ?? submitRelayedDeposit)(common);
126401
126472
  return { state: result.state, transaction: typeof result.receipt?.signature === "string" ? result.receipt.signature : null };
126402
126473
  }
126403
- var walkWalletHistory = (session, store) => loadWalletP03History({
126474
+ var walkWalletHistory = (session, store, share) => loadWalletP03History({
126404
126475
  store,
126405
126476
  connection: connectSplit(session.connection, session.historyUrl),
126406
126477
  programId: session.programId,
126407
126478
  pool: store.state.pool,
126408
- deploymentIdentity: session.proofTools.deploymentIdentity
126479
+ deploymentIdentity: session.proofTools.deploymentIdentity,
126480
+ ...share ? { share } : {}
126409
126481
  });
126410
- async function refreshWallet({ session, store, history: walked }) {
126482
+ async function refreshWallet({ session, store, history: walked, share }) {
126411
126483
  const walStates = captureWalStates(store);
126412
- const history = walked ?? await walkWalletHistory(session, store);
126484
+ const history = walked ?? await walkWalletHistory(session, store, share);
126413
126485
  const result = await runRecover({
126414
126486
  store,
126415
126487
  connection: session.connection,
@@ -126666,7 +126738,13 @@ function createWalletTools({
126666
126738
  let refreshFailedAt = 0;
126667
126739
  let refreshFailedCode;
126668
126740
  let refreshInBackground = false;
126669
- const refreshStep = (store, history) => (ops.refresh ?? refreshWallet)({ session, store, ...history ? { history } : {} });
126741
+ const refreshStep = (store, history, share) => (ops.refresh ?? refreshWallet)({
126742
+ session,
126743
+ store,
126744
+ ...history ? { history } : {},
126745
+ ...share ? { share } : {}
126746
+ });
126747
+ let lastWriterEndedAt = 0;
126670
126748
  const refreshWalk = ops.refreshWalk ?? (ops.refresh ? void 0 : (store) => walkWalletHistory(session, store));
126671
126749
  const errorCode2 = (error, fallback) => describeError(error, { fallback, safeText: SAFE_TEXT }).split(/[\s:;(]/, 1)[0];
126672
126750
  const underLease = (task) => session.serial(async () => {
@@ -126680,6 +126758,7 @@ function createWalletTools({
126680
126758
  return await task(session.openStore());
126681
126759
  } finally {
126682
126760
  await release();
126761
+ lastWriterEndedAt = Date.now();
126683
126762
  }
126684
126763
  });
126685
126764
  const autoPockets = createAutoPockets({
@@ -126764,7 +126843,12 @@ function createWalletTools({
126764
126843
  }
126765
126844
  };
126766
126845
  const withPoolSwitch = (tool) => ({ ...tool, run: async (...args) => {
126767
- const output2 = await tool.run(...args);
126846
+ let output2;
126847
+ try {
126848
+ output2 = await tool.run(...args);
126849
+ } finally {
126850
+ if (tool.annotations?.readOnlyHint !== true) lastWriterEndedAt = Date.now();
126851
+ }
126768
126852
  if (!succession || !output2 || output2.isError || typeof output2.text !== "string") return output2;
126769
126853
  const read = readSwitch();
126770
126854
  const field4 = switchField(read);
@@ -126814,6 +126898,7 @@ function createWalletTools({
126814
126898
  function refreshShared({ background = false } = {}) {
126815
126899
  if (!refreshRun) {
126816
126900
  refreshInBackground = background;
126901
+ const calledAt = Date.now();
126817
126902
  refreshRun = (async () => {
126818
126903
  let early;
126819
126904
  if (background && refreshWalk) {
@@ -126829,7 +126914,8 @@ function createWalletTools({
126829
126914
  return underLease((store) => {
126830
126915
  const same2 = early !== void 0 && early.pool === store.state.pool && early.records === JSON.stringify(captureWalStates(store));
126831
126916
  if (early !== void 0 && !same2) log("MCP_REFRESH_WALK_AGAIN");
126832
- return refreshStep(store, same2 ? early.history : void 0);
126917
+ const share = early !== void 0 && !same2 ? { notBeforeMs: Math.max(calledAt, lastWriterEndedAt) } : void 0;
126918
+ return refreshStep(store, same2 ? early.history : void 0, share);
126833
126919
  });
126834
126920
  })().then(() => {
126835
126921
  refreshFailedAt = 0;