shinjuku-shielded 0.3.42 → 0.3.43

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": "f55f1fb8f1b63bf4caf94b552f06f6c3126ed8fd598d6d8fe8fc9abd7377b509",
5
- "bytes": 11232354,
6
- "sourceCommit": "602ba18e9b8035f26155973016e9d4df9beaa718",
4
+ "sha256": "0ff1dea585d7a2ca69e0a37f43684dcb411f5a28eafa84a3f7fee65f5cd13904",
5
+ "bytes": 11235804,
6
+ "sourceCommit": "20e5a0c5b4faa27b1309e57816901b0ba77c78ce",
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.42",
3
+ "version": "0.3.43",
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": "f55f1fb8",
7
- "shinjukuSha256": "f55f1fb8f1b63bf4caf94b552f06f6c3126ed8fd598d6d8fe8fc9abd7377b509",
6
+ "shinjukuRelease": "0ff1dea5",
7
+ "shinjukuSha256": "0ff1dea585d7a2ca69e0a37f43684dcb411f5a28eafa84a3f7fee65f5cd13904",
8
8
  "license": "SEE LICENSE IN LICENSE.txt",
9
9
  "author": "Shinjuku Shielded",
10
10
  "homepage": "https://github.com/ShinjukuStaition/shinjuku-mcp#readme",
@@ -96770,12 +96770,33 @@ async function createSellerAdapter({
96770
96770
  const signingBytes = Buffer.from(config.signingKey.slice(2), "hex");
96771
96771
  const signerPublicKey = `0x${Buffer.from(secp256k1.getPublicKey(signingBytes, true)).toString("hex")}`;
96772
96772
  deriveShieldedSolanaP03Recipient({ eta: config.eta, resourceNonce: randomBytes17(32), poolDomain: BigInt(profile.poolDomain) });
96773
+ const ecdhScalar = config.eta % SHIELDED_SOLANA_P03_JUBJUB_SCALAR_MODULUS;
96774
+ const sharedXOf = (point) => shieldedSolanaP03ScalarMultiply(point, ecdhScalar).x;
96775
+ const sharedXByPoint = /* @__PURE__ */ new Map();
96776
+ let precomputesRunning = 0;
96773
96777
  const scanner = new ShieldedSolanaP03MemoScanner({ ecdh: {
96774
- deriveSharedX: (point) => shieldedSolanaP03ScalarMultiply(
96775
- point,
96776
- config.eta % SHIELDED_SOLANA_P03_JUBJUB_SCALAR_MODULUS
96777
- ).x
96778
+ deriveSharedX: (point) => sharedXByPoint.get(`${point.x}:${point.y}`) ?? sharedXOf(point)
96778
96779
  } });
96780
+ async function precomputeMemoSharedX(memoBundle, owned) {
96781
+ let sliceStart = performance.now();
96782
+ for (let offset = 0; offset + MEMO_RECORD_BYTES2 <= memoBundle.length; offset += MEMO_RECORD_BYTES2) {
96783
+ if (performance.now() - sliceStart >= MEMO_PRECOMPUTE_SLICE_MS) {
96784
+ await new Promise((resolveTurn) => {
96785
+ setImmediate(resolveTurn);
96786
+ });
96787
+ sliceStart = performance.now();
96788
+ }
96789
+ if (owned.done) return;
96790
+ try {
96791
+ const point = shieldedSolanaP03CurvePointFromX(BigInt(`0x${Buffer.from(memoBundle.subarray(offset, offset + 32)).toString("hex")}`));
96792
+ const key = `${point.x}:${point.y}`;
96793
+ if (sharedXByPoint.has(key)) continue;
96794
+ sharedXByPoint.set(key, sharedXOf(point));
96795
+ owned.keys.push(key);
96796
+ } catch {
96797
+ }
96798
+ }
96799
+ }
96779
96800
  const readChainAnchor = createAnchorReader({ connection: memoizeFinalizedReads(connection), profile });
96780
96801
  let anchorRequest;
96781
96802
  const requestFacilitatorAnchor = () => anchorRequest ??= (async () => {
@@ -97178,15 +97199,32 @@ async function createSellerAdapter({
97178
97199
  try {
97179
97200
  if (!offer.outboundJson) {
97180
97201
  const parsed = parseSolanaP03HttpPaymentPayload(payment.payload);
97181
- const auth = await issuer(offer.resource, payment.accepted.amount).authenticate({
97182
- requirements: payment.accepted,
97183
- resource: payment.resource,
97184
- publicInput7: parsed.publicInputs[7]
97185
- });
97186
- mark("intake-authenticated");
97187
- const intakeRead = readAnchor();
97188
- intakeRead.catch(() => void 0);
97189
- const recoveredNote = await scanner.recoverMerchantNoteYielding({ parsed, authenticatedQuote: auth });
97202
+ const quoteIssuer = issuer(offer.resource, payment.accepted.amount);
97203
+ const authInput = { requirements: payment.accepted, resource: payment.resource, publicInput7: parsed.publicInputs[7] };
97204
+ await quoteIssuer.authenticateForClaim(authInput);
97205
+ const authenticated = quoteIssuer.authenticate(authInput);
97206
+ authenticated.catch(() => void 0);
97207
+ const owned = { keys: [], done: false };
97208
+ let precomputed;
97209
+ if (precomputesRunning < MEMO_PRECOMPUTES_MAX) {
97210
+ precomputesRunning += 1;
97211
+ precomputed = precomputeMemoSharedX(parsed.memoBundle, owned).catch(() => void 0).finally(() => {
97212
+ precomputesRunning -= 1;
97213
+ });
97214
+ }
97215
+ let recoveredNote;
97216
+ let intakeRead;
97217
+ try {
97218
+ const auth = await authenticated;
97219
+ mark("intake-authenticated");
97220
+ intakeRead = readAnchor();
97221
+ intakeRead.catch(() => void 0);
97222
+ await precomputed;
97223
+ recoveredNote = await scanner.recoverMerchantNoteYielding({ parsed, authenticatedQuote: auth });
97224
+ } finally {
97225
+ owned.done = true;
97226
+ for (const key of owned.keys) sharedXByPoint.delete(key);
97227
+ }
97190
97228
  mark("intake-note-recovered");
97191
97229
  const chain = await intakeRead;
97192
97230
  intakeChain = chain;
@@ -97415,7 +97453,7 @@ async function createSellerAdapter({
97415
97453
  }));
97416
97454
  return { server, handle, close, signerPublicKey, settledTransactions, offerSummaries };
97417
97455
  }
97418
- 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;
97456
+ 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, MEMO_RECORD_BYTES2, MEMO_PRECOMPUTE_SLICE_MS, MEMO_PRECOMPUTES_MAX, 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;
97419
97457
  var init_service = __esm({
97420
97458
  "wallet/src/seller/service.mjs"() {
97421
97459
  "use strict";
@@ -97466,6 +97504,9 @@ var init_service = __esm({
97466
97504
  ANCHOR_REQUEST_TIMEOUT_MS2 = 9e4;
97467
97505
  ANCHOR_POLL_ATTEMPTS = 15;
97468
97506
  ANCHOR_POLL_MS = 2e3;
97507
+ MEMO_RECORD_BYTES2 = 200;
97508
+ MEMO_PRECOMPUTE_SLICE_MS = 8;
97509
+ MEMO_PRECOMPUTES_MAX = 2;
97469
97510
  PRE_SETTLE_REUSE_MARGIN_S = 60;
97470
97511
  PRE_SETTLE_REUSE_MAX_AGE_MS = 2e4;
97471
97512
  FINALIZED_MEMO_MAX_AGE_MS = 1e3;
@@ -126800,7 +126841,18 @@ function createWalletTools({
126800
126841
  ...share ? { share } : {}
126801
126842
  });
126802
126843
  let lastWriterEndedAt = 0;
126803
- const refreshWalk = ops.refreshWalk ?? (ops.refresh ? void 0 : (store) => walkWalletHistory(session, store));
126844
+ let paysInFlight = 0;
126845
+ let refreshDeferred = false;
126846
+ let refreshForeground = false;
126847
+ let refreshRunDeferred = false;
126848
+ const REFRESH_DEFERRED = /* @__PURE__ */ Symbol("deferred refresh");
126849
+ const runDeferredRefresh = () => {
126850
+ if (!refreshDeferred || paysInFlight !== 0 || finalityWait || refreshRun || finalityClosed) return;
126851
+ refreshDeferred = false;
126852
+ refreshShared({ background: true }).catch(() => {
126853
+ });
126854
+ };
126855
+ const refreshWalk = ops.refreshWalk ?? (ops.refresh ? void 0 : (store, share) => walkWalletHistory(session, store, share));
126804
126856
  const errorCode2 = (error, fallback) => describeError(error, { fallback, safeText: SAFE_TEXT }).split(/[\s:;(]/, 1)[0];
126805
126857
  const underLease = (task) => session.serial(async () => {
126806
126858
  let release;
@@ -126899,10 +126951,16 @@ function createWalletTools({
126899
126951
  };
126900
126952
  const withPoolSwitch = (tool) => ({ ...tool, run: async (...args) => {
126901
126953
  let output2;
126954
+ const paying = tool.name === "x402_pay";
126955
+ if (paying) paysInFlight += 1;
126902
126956
  try {
126903
126957
  output2 = await tool.run(...args);
126904
126958
  } finally {
126905
126959
  if (tool.annotations?.readOnlyHint !== true) lastWriterEndedAt = Date.now();
126960
+ if (paying) {
126961
+ paysInFlight -= 1;
126962
+ runDeferredRefresh();
126963
+ }
126906
126964
  }
126907
126965
  if (!succession || !output2 || output2.isError || typeof output2.text !== "string") return output2;
126908
126966
  const read = readSwitch();
@@ -126951,9 +127009,20 @@ function createWalletTools({
126951
127009
  });
126952
127010
  if (ops.oneTimeAdopt !== false) adopter.start();
126953
127011
  function refreshShared({ background = false } = {}) {
127012
+ if (refreshRun && !background && refreshRunDeferred) return refreshRun.then(() => refreshShared(), () => refreshShared());
127013
+ if (refreshRun && !background) refreshForeground = true;
126954
127014
  if (!refreshRun) {
126955
127015
  refreshInBackground = background;
127016
+ refreshForeground = !background;
127017
+ refreshRunDeferred = false;
126956
127018
  const calledAt = Date.now();
127019
+ const deferNow = () => {
127020
+ if (!background || refreshForeground || paysInFlight === 0) return false;
127021
+ refreshRunDeferred = true;
127022
+ refreshDeferred = true;
127023
+ log("MCP_REFRESH_DEFERRED");
127024
+ return true;
127025
+ };
126957
127026
  refreshRun = (async () => {
126958
127027
  let early;
126959
127028
  if (background && refreshWalk) {
@@ -126961,18 +127030,21 @@ function createWalletTools({
126961
127030
  const store = session.openStore();
126962
127031
  const records = JSON.stringify(captureWalStates(store));
126963
127032
  const pool2 = store.state.pool;
126964
- early = { records, pool: pool2, history: await refreshWalk(store) };
127033
+ early = { records, pool: pool2, history: await refreshWalk(store, { notBeforeMs: Math.max(calledAt, lastWriterEndedAt) }) };
126965
127034
  } catch {
126966
127035
  early = void 0;
126967
127036
  }
126968
127037
  }
126969
127038
  return underLease((store) => {
127039
+ if (deferNow()) return REFRESH_DEFERRED;
127040
+ refreshDeferred = false;
126970
127041
  const same2 = early !== void 0 && early.pool === store.state.pool && early.records === JSON.stringify(captureWalStates(store));
126971
127042
  if (early !== void 0 && !same2) log("MCP_REFRESH_WALK_AGAIN");
126972
127043
  const share = early !== void 0 && !same2 ? { notBeforeMs: Math.max(calledAt, lastWriterEndedAt) } : void 0;
126973
127044
  return refreshStep(store, same2 ? early.history : void 0, share);
126974
127045
  });
126975
- })().then(() => {
127046
+ })().then((result) => {
127047
+ if (result === REFRESH_DEFERRED) return;
126976
127048
  refreshFailedAt = 0;
126977
127049
  log("MCP_REFRESH_DONE");
126978
127050
  }, (error) => {
@@ -126981,8 +127053,12 @@ function createWalletTools({
126981
127053
  log(`MCP_REFRESH_FAILED ${refreshFailedCode}`);
126982
127054
  throw error;
126983
127055
  }).finally(() => {
127056
+ const deferred = refreshRunDeferred;
126984
127057
  refreshRun = void 0;
126985
127058
  refreshInBackground = false;
127059
+ refreshForeground = false;
127060
+ refreshRunDeferred = false;
127061
+ if (deferred || refreshDeferred) runDeferredRefresh();
126986
127062
  });
126987
127063
  }
126988
127064
  return refreshRun;
@@ -127053,6 +127129,7 @@ function createWalletTools({
127053
127129
  finalityWait = void 0;
127054
127130
  if (finalityClosed || finalityTarget === watched) finalityTarget = void 0;
127055
127131
  else startFinalityWait();
127132
+ runDeferredRefresh();
127056
127133
  });
127057
127134
  }
127058
127135
  async function refreshIfStale() {
@@ -127473,7 +127550,7 @@ function createWalletTools({
127473
127550
  let refresh = {};
127474
127551
  const recentlyFailed = refreshFailedAt && Date.now() - refreshFailedAt < REFRESH_RETRY_MS && !refreshRun;
127475
127552
  if (report.split?.shieldedAtomic != null && report.status === "stale") {
127476
- if (!recentlyFailed && !finalityWait) refreshShared().catch(() => {
127553
+ if (!recentlyFailed && (!finalityWait || refreshDeferred)) refreshShared().catch(() => {
127477
127554
  });
127478
127555
  refresh = { refreshing: true };
127479
127556
  } else if (report.split?.shieldedAtomic == null && recentlyFailed) {