shinjuku-shielded 0.3.46 → 0.3.47

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": "fe90fa0a418682c08b49b05bcda64ffd7b6cf8803166f95968205c80a2fcab4b",
5
- "bytes": 11282021,
6
- "sourceCommit": "4664c1b8a728712acc576493a6cabb03ccbe4167",
4
+ "sha256": "efd1a80db30f354b1fd326c9619666b7d63ce4051428a5e7a4f267a04ca568ea",
5
+ "bytes": 11284496,
6
+ "sourceCommit": "d84d9e95e8794f78eb2eeac89bf1671735c23e66",
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.46",
3
+ "version": "0.3.47",
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": "fe90fa0a",
7
- "shinjukuSha256": "fe90fa0a418682c08b49b05bcda64ffd7b6cf8803166f95968205c80a2fcab4b",
6
+ "shinjukuRelease": "efd1a80d",
7
+ "shinjukuSha256": "efd1a80db30f354b1fd326c9619666b7d63ce4051428a5e7a4f267a04ca568ea",
8
8
  "license": "SEE LICENSE IN LICENSE.txt",
9
9
  "author": "Shinjuku Shielded",
10
10
  "homepage": "https://github.com/ShinjukuStaition/shinjuku-mcp#readme",
@@ -62324,7 +62324,9 @@ var init_errorCodes = __esm({
62324
62324
  "p03_quote_anchor_evidence_invalid",
62325
62325
  "p03_quote_anchor_invalid",
62326
62326
  "p03_quote_anchor_not_current",
62327
+ "p03_quote_anchor_read_invalid",
62327
62328
  "p03_quote_anchor_reader_missing",
62329
+ "p03_quote_anchor_stale",
62328
62330
  "p03_quote_commitment_invalid",
62329
62331
  "p03_quote_crypto_address_base58_empty",
62330
62332
  "p03_quote_crypto_address_base58_invalid",
@@ -63987,6 +63989,13 @@ var init_errorCodes = __esm({
63987
63989
  "requirement_invalid",
63988
63990
  "paid_mismatch",
63989
63991
  "duplicate_payment",
63992
+ // Float fronting (float.mjs signFronted / attach, 2026-10-16): refusals and the loss reasons.
63993
+ "front_paused",
63994
+ "front_above_limit",
63995
+ "front_duplicate",
63996
+ "attach_mismatch",
63997
+ "fronted_nullifier_spent",
63998
+ "fronted_quote_expired",
63990
63999
  "p03_payer_float_history_unreadable",
63991
64000
  "p03_payer_float_dead_proof_failed",
63992
64001
  "p03_payer_float_watch_failed",
@@ -92811,6 +92820,8 @@ async function payViaFloat({
92811
92820
  const finishingUntil = Date.now() + FINISHING_LIMIT_MS;
92812
92821
  for (; ; ) {
92813
92822
  const seen = {};
92823
+ const innerRecord = store.readWal(`resource-payment-${hash8(record.innerRequestId)}`);
92824
+ const front = innerRecord === void 0 || Array.isArray(innerRecord?.request?.headers) && innerRecord.request.headers.some(([name]) => name === FLOAT_FRONT_HEADER);
92814
92825
  let result;
92815
92826
  try {
92816
92827
  result = await pay({
@@ -92824,9 +92835,15 @@ async function payViaFloat({
92824
92835
  maximumAtomic: record.paidAtomic,
92825
92836
  method: "POST",
92826
92837
  body: Buffer.from(record.bodyBase64, "base64"),
92827
- headers: { "content-type": "application/json" },
92838
+ headers: { "content-type": "application/json", ...front ? { [FLOAT_FRONT_HEADER]: "1" } : {} },
92828
92839
  // settlePriorBeforeQuote: a prior answer that holds every input is settled before the leg-1 402 (one quote, one row).
92829
- deps: { ...withoutCallerBody(deps), fetchImpl: floatFetch(fetchImpl, seen), settlePriorBeforeQuote: true }
92840
+ // acceptFrontedReceipt: only this request (our float route) may answer with a fronted receipt.
92841
+ deps: {
92842
+ ...withoutCallerBody(deps),
92843
+ fetchImpl: floatFetch(fetchImpl, seen),
92844
+ settlePriorBeforeQuote: true,
92845
+ acceptFrontedReceipt: front
92846
+ }
92830
92847
  });
92831
92848
  } catch (error) {
92832
92849
  if (seen.refusal) {
@@ -92941,7 +92958,7 @@ function paidResult(record, replayed) {
92941
92958
  float: { floatId: record.floatId }
92942
92959
  };
92943
92960
  }
92944
- var import_web3109, FLOAT_PAYMENT_SCHEMA, REGENERATE_CODES, FLOAT_PAYMENT_WAL_PREFIX, FLOAT_CONFIG_SCHEMA, FLOAT_PAY_PATH, MAX_BODY_BYTES, FLOAT_REFUND_ETA_SECONDS, REFUND_SETTLED_AFTER_MS, FINISHING_POLL_MS, FINISHING_LIMIT_MS, SELLER_TIMEOUT_MS, CONFIG_TIMEOUT_MS, CONFIG_CACHE_MS, DECIMAL3, POSITIVE, PENDING_CODES, hash8, fail18, floatPaymentWalName, configCache, poolDomains, poolDomainReads, poolDomainWarmFailedAt, WARM_RETRY_MS, payerGenerator, etaEntry, loadPayerGenerator, plainText;
92961
+ var import_web3109, FLOAT_PAYMENT_SCHEMA, REGENERATE_CODES, FLOAT_PAYMENT_WAL_PREFIX, FLOAT_CONFIG_SCHEMA, FLOAT_PAY_PATH, MAX_BODY_BYTES, FLOAT_REFUND_ETA_SECONDS, REFUND_SETTLED_AFTER_MS, FINISHING_POLL_MS, FINISHING_LIMIT_MS, SELLER_TIMEOUT_MS, CONFIG_TIMEOUT_MS, CONFIG_CACHE_MS, DECIMAL3, POSITIVE, PENDING_CODES, FLOAT_FRONT_HEADER, hash8, fail18, floatPaymentWalName, configCache, poolDomains, poolDomainReads, poolDomainWarmFailedAt, WARM_RETRY_MS, payerGenerator, etaEntry, loadPayerGenerator, plainText;
92945
92962
  var init_floatPay = __esm({
92946
92963
  "wallet/src/pay/floatPay.mjs"() {
92947
92964
  "use strict";
@@ -92974,6 +92991,7 @@ var init_floatPay = __esm({
92974
92991
  DECIMAL3 = /^(0|[1-9][0-9]*)$/;
92975
92992
  POSITIVE = /^[1-9][0-9]*$/;
92976
92993
  PENDING_CODES = /* @__PURE__ */ new Set(["float_paid_finishing", "payment_pending_retry_same_payment"]);
92994
+ FLOAT_FRONT_HEADER = "x-shinjuku-float-front";
92977
92995
  hash8 = (value) => sha256Hex2(Buffer.from(value, "utf8"));
92978
92996
  fail18 = (code, extra = {}) => {
92979
92997
  throw Object.assign(new Error(code), extra);
@@ -93440,7 +93458,7 @@ async function finalizePendingReceipt({ store, connection, programId, name, time
93440
93458
  }
93441
93459
  function writeFinalized(store, name, record, settlement) {
93442
93460
  const settledTransaction = settlement.provenance?.signature;
93443
- const finalized = settledTransaction === record.receipt.transaction ? { ...record, receiptFinality: "finalized" } : { ...record, receiptFinality: "finalized", receiptMismatch: "transaction", settledTransaction };
93461
+ const finalized = record.fronted === true && record.receipt.transaction === "" ? { ...record, receiptFinality: "finalized", settledTransaction } : settledTransaction === record.receipt.transaction ? { ...record, receiptFinality: "finalized" } : { ...record, receiptFinality: "finalized", receiptMismatch: "transaction", settledTransaction };
93444
93462
  store.writeWal(name, finalized);
93445
93463
  return finalized;
93446
93464
  }
@@ -93589,15 +93607,18 @@ function reserveBudget(store, requestKey, fingerprint, amount) {
93589
93607
  };
93590
93608
  store.save();
93591
93609
  }
93592
- function validateReceipt(receipt, record, state, programId) {
93610
+ function validateReceipt(receipt, record, state, programId, { acceptFronted = false } = {}) {
93593
93611
  const required = record.paymentRequired.accepts.find((entry) => entry.scheme === "shielded-exact");
93612
+ const fronted = acceptFronted === true && receipt?.transaction === "" && receipt?.extra?.finality === "fronted";
93594
93613
  let signature;
93595
- try {
93596
- signature = base58btcDecode2(receipt?.transaction);
93597
- } catch {
93598
- fail19("receipt_signature_invalid");
93614
+ if (!fronted) {
93615
+ try {
93616
+ signature = base58btcDecode2(receipt?.transaction);
93617
+ } catch {
93618
+ fail19("receipt_signature_invalid");
93619
+ }
93599
93620
  }
93600
- if (receipt?.success !== true || signature?.length !== 64 || receipt.network !== state.network || receipt.amount !== required.amount || receipt.extra?.binding !== "carbon-shielded-exact/svm-v3" || !["confirmed", "finalized"].includes(receipt.extra.finality) || receipt.extra.pool !== state.pool || receipt.extra.programId !== String(programId) || !sameQuoteCommitment(receipt.extra.quoteCommitment, required.extra.quoteCommitment) || receipt.extra.memoAvailabilityDigest !== record.memoDigest) fail19("receipt_binding_mismatch");
93621
+ if (receipt?.success !== true || !fronted && signature?.length !== 64 || receipt.network !== state.network || receipt.amount !== required.amount || receipt.extra?.binding !== "carbon-shielded-exact/svm-v3" || !(fronted || ["confirmed", "finalized"].includes(receipt.extra.finality)) || receipt.extra.pool !== state.pool || receipt.extra.programId !== String(programId) || !sameQuoteCommitment(receipt.extra.quoteCommitment, required.extra.quoteCommitment) || receipt.extra.memoAvailabilityDigest !== record.memoDigest) fail19("receipt_binding_mismatch");
93601
93622
  }
93602
93623
  async function payResource(options) {
93603
93624
  const timing = options?.deps?.timing;
@@ -94121,7 +94142,7 @@ async function payResourceOnce({
94121
94142
  let receipt;
94122
94143
  try {
94123
94144
  receipt = decodePaymentResponseHeader(encoded);
94124
- validateReceipt(receipt, record, store.state, programId);
94145
+ validateReceipt(receipt, record, store.state, programId, { acceptFronted: deps.acceptFrontedReceipt === true });
94125
94146
  } catch (error) {
94126
94147
  if (landed) {
94127
94148
  await response.body?.cancel();
@@ -94136,7 +94157,8 @@ async function payResourceOnce({
94136
94157
  if (landed) recordLandedWithoutAnswer(store, walName2, record);
94137
94158
  throw error;
94138
94159
  }
94139
- const answeredSettleSlot = receiptSettleSlot(receipt.extra?.settleSlot);
94160
+ const fronted = receipt.extra.finality === "fronted";
94161
+ const answeredSettleSlot = fronted ? void 0 : receiptSettleSlot(receipt.extra?.settleSlot);
94140
94162
  store.writeWal(walName2, {
94141
94163
  ...record,
94142
94164
  state: "receipt",
@@ -94144,6 +94166,7 @@ async function payResourceOnce({
94144
94166
  resultBase64,
94145
94167
  receiptFinality: "pending",
94146
94168
  answeredAtMs: Date.now(),
94169
+ ...fronted ? { fronted: true } : {},
94147
94170
  ...answeredSettleSlot !== void 0 ? { answeredSettleSlot } : {}
94148
94171
  });
94149
94172
  mark("receipt-pending");
@@ -95955,7 +95978,7 @@ function deriveShieldedSolanaP03PoolDomain(input) {
95955
95978
  ]);
95956
95979
  }
95957
95980
  function parseAnchorEvidence(raw) {
95958
- if (!isPlainObject3(raw)) throw new Error("p03_quote_anchor_evidence_invalid");
95981
+ if (!isPlainObject3(raw)) throw new Error("p03_quote_anchor_read_invalid");
95959
95982
  assertExactKeys(
95960
95983
  raw,
95961
95984
  ["anchorIndex", "anchorRoot", "chainTimestamp", "epoch", "finalizedSlot", "retainedAnchors"].filter((key) => raw[key] !== void 0),
@@ -96225,6 +96248,9 @@ var init_ShieldedSolanaP03Quote = __esm({
96225
96248
  const parsed = this.parseAuthentication(input);
96226
96249
  const evidence = parseAnchorEvidence(await this.readCurrentQuoteAnchor());
96227
96250
  if (evidence.chainTimestamp >= parsed.validBefore) throw new Error("p03_quote_expired");
96251
+ if (parsed.anchor.epoch > evidence.current.epoch || parsed.anchor.epoch === evidence.current.epoch && parsed.anchor.anchorIndex > evidence.current.anchorIndex) {
96252
+ throw new Error("p03_quote_anchor_stale");
96253
+ }
96228
96254
  const anchor = [evidence.current, ...evidence.retained].find((candidate) => candidate.epoch === parsed.anchor.epoch && candidate.anchorIndex === parsed.anchor.anchorIndex && candidate.anchorRoot === parsed.anchor.anchorRoot);
96229
96255
  if (!anchor) throw new Error("p03_quote_anchor_evidence_invalid");
96230
96256
  return this.authenticateParsed(input, parsed);
@@ -98520,7 +98546,9 @@ var init_service = __esm({
98520
98546
  "p03_http_payload_shape_invalid",
98521
98547
  "p03_append_payload_forbidden",
98522
98548
  "p03_payload_binding_invalid",
98523
- "p03_payment_proof_rejected"
98549
+ "p03_payment_proof_rejected",
98550
+ // The quote's anchor left the facilitator's anchor ring (2026-10-16): it can never pass again.
98551
+ "p03_quote_anchor_evidence_invalid"
98524
98552
  ]);
98525
98553
  definiteVerifyRefusal = (verified) => verified?.isValid === false && typeof verified.invalidMessage === "string" && DEFINITE_VERIFY_REFUSALS.has(verified.invalidMessage);
98526
98554
  refusedBeforeSettlement = (answer) => answer?.success === false && answer.extra?.refusedBeforeRecord === true;
@@ -127697,11 +127725,13 @@ function selfPayMayHaveSigned(store, unshieldId) {
127697
127725
  function leg1SettleSlot(store, float, requestId) {
127698
127726
  try {
127699
127727
  const inner = typeof float?.innerRequestId === "string" && float.innerRequestId ? float.innerRequestId : floatInnerRequestId(requestId);
127700
- return store?.readWal(`${RESOURCE_PAYMENT_WAL_PREFIX2}${sha256Hex2(Buffer.from(inner, "utf8"))}`)?.answeredSettleSlot;
127728
+ const record = store?.readWal(`${RESOURCE_PAYMENT_WAL_PREFIX2}${sha256Hex2(Buffer.from(inner, "utf8"))}`);
127729
+ return { slot: record?.answeredSettleSlot, fronted: record?.fronted === true };
127701
127730
  } catch {
127702
- return void 0;
127731
+ return { slot: void 0, fronted: false };
127703
127732
  }
127704
127733
  }
127734
+ var FRONTED_SETTLE_MARGIN_SLOTS = 20;
127705
127735
  function bindUnshieldRecipient(store, unshieldId, amountAtomic, to) {
127706
127736
  const name = `self-pay-${unshieldId}`;
127707
127737
  const record = store.readWal(name);
@@ -128138,12 +128168,14 @@ function createWalletTools({
128138
128168
  Promise.resolve().then(() => (ops.slot ?? ((c) => session.connection.getSlot(c)))(commitment)),
128139
128169
  ops.slotReadMs ?? PUBLIC_READ_TIMEOUT_MS
128140
128170
  );
128141
- function refreshAtFinality(settleSlot) {
128171
+ function refreshAtFinality(settleSlot, { tipMarginSlots = 0 } = {}) {
128142
128172
  if (finalityClosed) return;
128143
128173
  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;
128174
+ const margin = Number.isSafeInteger(tipMarginSlots) && tipMarginSlots > 0 ? tipMarginSlots : 0;
128144
128175
  const next = readSlot("confirmed").catch(() => void 0).then((tip) => {
128145
128176
  if (!Number.isSafeInteger(tip)) return given;
128146
- if (given === void 0 || given > tip || given < tip - FINALITY_SETTLE_WINDOW_SLOTS) return tip;
128177
+ if (given === void 0) return tip + margin;
128178
+ if (given > tip || given < tip - FINALITY_SETTLE_WINDOW_SLOTS) return tip;
128147
128179
  return given;
128148
128180
  });
128149
128181
  const prior = finalityTarget;
@@ -128491,7 +128523,12 @@ function createWalletTools({
128491
128523
  const amounts = floatPaid ? { priceAtomic: float.priceAtomic, feeAtomic: float.feeAtomic, amountAtomic: float.paidAtomic } : { priceAtomic: receipt.amountAtomic ?? null, feeAtomic: "0", amountAtomic: receipt.amountAtomic ?? null };
128492
128524
  const one = paidStore ? localBalanceOf(paidStore, (phase, outcome) => mark(`result:${phase}`, void 0, outcome)) : null;
128493
128525
  mark("mcp-result-balance");
128494
- if (receipt.replayed !== true) refreshAtFinality(floatPaid ? leg1SettleSlot(paidStore, float, requestId) : receipt.extra?.settleSlot);
128526
+ if (receipt.replayed !== true) {
128527
+ if (floatPaid) {
128528
+ const leg1 = leg1SettleSlot(paidStore, float, requestId);
128529
+ refreshAtFinality(leg1.slot, { tipMarginSlots: leg1.fronted ? FRONTED_SETTLE_MARGIN_SLOTS : 0 });
128530
+ } else refreshAtFinality(receipt.extra?.settleSlot);
128531
+ }
128495
128532
  mark("mcp-result");
128496
128533
  return answerResult(paidAnswerContent({
128497
128534
  status: response.status,
@@ -128807,7 +128844,8 @@ function createWalletTools({
128807
128844
  host,
128808
128845
  scheme: shielded ? "shielded-exact" : "exact",
128809
128846
  amountAtomic: typeof amount === "string" ? amount : null,
128810
- transaction: typeof record.receipt?.transaction === "string" ? record.receipt.transaction : null,
128847
+ // A fronted receipt (2026-10-16) names no transaction (""): the settle's own, once finalized, or null.
128848
+ transaction: typeof record.receipt?.transaction === "string" && record.receipt.transaction !== "" ? record.receipt.transaction : typeof record.settledTransaction === "string" ? record.settledTransaction : null,
128811
128849
  answeredAt: Number.isSafeInteger(record.answeredAtMs) ? new Date(record.answeredAtMs).toISOString() : null,
128812
128850
  ...typeof record.receiptFinality === "string" ? { receiptFinality: record.receiptFinality } : {},
128813
128851
  at: Number.isSafeInteger(record.answeredAtMs) ? record.answeredAtMs : -1