@piprail/sdk 1.20.1 → 1.21.0

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/CHANGELOG.md CHANGED
@@ -4,6 +4,45 @@ All notable changes to `@piprail/sdk` are documented here. The format
4
4
  follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the
5
5
  versions follow [Semantic Versioning](https://semver.org/).
6
6
 
7
+ ## [1.21.0] — 2026-06-13 — standard `exact` rail on Solana (SVM) + fully-gasless facilitator mode
8
+
9
+ Opt-in, defaults unchanged. `onchain-proof` stays the default on every chain and is byte-identical.
10
+
11
+ ### Added
12
+ - **The standard x402 `exact` rail now covers Solana**, not just EVM — so any standard x402
13
+ client/agent that speaks `exact` (the majority) can pay a PipRail Solana gate directly, and a
14
+ PipRail agent can pay any standard Solana `exact` server. Per the ratified `scheme_exact_svm.md`:
15
+ the buyer partial-signs an SPL `TransferChecked` transaction whose **fee payer is the merchant**,
16
+ and the gate co-signs as fee payer + broadcasts against your own RPC — **no facilitator, no
17
+ backend** (the same self-settle model as the EVM `exact` rail). Enable it exactly as on EVM:
18
+ `requirePayment({ chain: 'solana', token: 'USDC', amount, payTo, exact: { settle: 'self', relayer } })`,
19
+ and on the client `new PipRailClient({ chain: 'solana', wallet, schemes: ['onchain-proof', 'exact'] })`.
20
+ - **Buyer-gasless on Solana, for any SPL token.** The buyer signs the canonical
21
+ `[setComputeUnitLimit, setComputeUnitPrice, TransferChecked]` transaction and spends **zero SOL** —
22
+ only the token funds the payment. Gasless-ness is transaction-level (the fee payer), not token-level,
23
+ so **USDC and USDT are equally gasless** (no EIP-3009/Permit2 equivalent needed, unlike EVM). The fee
24
+ payer must be **distinct from `payTo`** (a scheme MUST-rule the SDK enforces), and the recipient's
25
+ token account must already exist (the exact rail won't create it — `onchain-proof` does).
26
+ - **Solana facilitator mode → _fully_ gasless (neither buyer nor merchant pays).** `exact: { settle: {
27
+ facilitator } }` now works on Solana, not just EVM: the gate auto-discovers the facilitator's
28
+ fee-payer pubkey from its `GET /supported`, advertises it, and forwards settlement — the **facilitator
29
+ pays the gas**. Live-proven on mainnet against **PayAI** (`https://facilitator.payai.network`, no API
30
+ key). Self-settle (your own relayer pays the sub-cent fee) remains available; PipRail hosts nothing
31
+ and is never the fee payer.
32
+
33
+ ### Security (defense-in-depth, after an adversarial review)
34
+ - The gate counts **only authentically-signed** transfers toward the required amount (a
35
+ tiny-signed + large-unsigned multi-transfer can't reach the price), enforces fee-payer **isolation by
36
+ resolved pubkey** across every instruction (ALT-safe, not a literal index check), and **canonicalizes**
37
+ the SVM replay key so a base64-malleated re-submission can't bypass the replay claim.
38
+
39
+ ### Changed (internal — no API change)
40
+ - The `exact` rail moved behind a new driver SPI, `ResolvedNetwork.resolveExactRail`, so the gate is
41
+ fully chain-agnostic (it no longer special-cases EVM). EVM's EIP-3009/Permit2 method-selection is
42
+ unchanged in behaviour; Solana plugs in `{ method: 'svm', extra: { feePayer, tokenProgram } }`.
43
+ - The wire types gained the SVM `exact` payload (`{ transaction }`) and the `extra` keys
44
+ `feePayer`/`memo`/`tokenProgram`; `assetTransferMethod` now also accepts `'svm'`.
45
+
7
46
  ## [1.20.1] — 2026-06-11 — gate replay store: bounded + exception-safe
8
47
 
9
48
  Patch — internal robustness on the gate's built-in replay protection. No API change, no visible
package/dist/index.cjs CHANGED
@@ -533,6 +533,37 @@ var EXACT_NETWORK_SLUGS = {
533
533
  function chainIdForExactNetwork(slug) {
534
534
  return _nullishCoalesce(EXACT_NETWORK_SLUGS[slug], () => ( null));
535
535
  }
536
+ async function resolveExactRailEvm(input) {
537
+ const { asset, method, readDomain, permit2Supported } = input;
538
+ if (asset === "native") return null;
539
+ const want = method === "eip3009" || method === "permit2" ? method : "auto";
540
+ let chosen;
541
+ let extra = {};
542
+ if (want === "permit2") {
543
+ chosen = "permit2";
544
+ } else {
545
+ const d = await readDomain(asset);
546
+ if (d) {
547
+ chosen = "eip3009";
548
+ extra = { name: d.name, version: d.version };
549
+ } else if (want === "eip3009") {
550
+ throw new Error(
551
+ `requirePayment: exact \`method: 'eip3009'\` requested for ${asset}, but it isn't an EIP-3009 token (no name()/version()/authorizationState). Use \`method: 'permit2'\` (any ERC-20, e.g. Binance-Peg USDC on BNB) or \`'auto'\`. (Or check your rpcUrl is reachable.)`
552
+ );
553
+ } else {
554
+ chosen = "permit2";
555
+ }
556
+ }
557
+ if (chosen === "permit2" && !permit2Supported()) {
558
+ if (method === "permit2") {
559
+ throw new Error(
560
+ `requirePayment: exact \`method: 'permit2'\` needs the x402 Permit2 proxy deployed on this chain, but it isn't there. Offer an EIP-3009 token (gasless, no proxy), or drop \`exact\` on this chain. (See PERMIT2_PROXY_CHAIN_IDS.)`
561
+ );
562
+ }
563
+ return null;
564
+ }
565
+ return { method: chosen, extra };
566
+ }
536
567
  var EIP3009_TYPES = {
537
568
  TransferWithAuthorization: [
538
569
  { name: "from", type: "address" },
@@ -1417,11 +1448,14 @@ function parseExactPaymentHeader(value) {
1417
1448
  if (typeof network !== "string") return null;
1418
1449
  const payload = v.payload;
1419
1450
  if (!payload || typeof payload !== "object") return null;
1420
- const signature = payload.signature;
1421
- if (typeof signature !== "string") return null;
1422
1451
  const x402Version = typeof v.x402Version === "number" ? v.x402Version : 2;
1423
1452
  const asset = accepted && typeof accepted.asset === "string" ? accepted.asset : void 0;
1424
1453
  const base2 = { x402Version, network, ...asset ? { asset } : {}, raw: v };
1454
+ if (typeof payload.transaction === "string") {
1455
+ return { ...base2, method: "svm", payload: { transaction: payload.transaction } };
1456
+ }
1457
+ const signature = payload.signature;
1458
+ if (typeof signature !== "string") return null;
1425
1459
  const authorization = payload.authorization;
1426
1460
  if (authorization && typeof authorization === "object") {
1427
1461
  for (const k of ["from", "to", "value", "validAfter", "validBefore", "nonce"]) {
@@ -1708,6 +1742,16 @@ function makeEvmNetwork(resolved) {
1708
1742
  exactPermit2Supported() {
1709
1743
  return isPermit2ProxyChain(resolved.chainId);
1710
1744
  },
1745
+ // The gate's rail-advertisement SPI — EIP-3009 vs Permit2 selection (the pure helper),
1746
+ // injecting the on-chain domain read + the Permit2 proxy-presence check.
1747
+ async resolveExactRail({ asset, method }) {
1748
+ return resolveExactRailEvm({
1749
+ asset,
1750
+ method,
1751
+ readDomain: (a) => readExactDomain(publicClient, a),
1752
+ permit2Supported: () => isPermit2ProxyChain(resolved.chainId)
1753
+ });
1754
+ },
1711
1755
  async settleExactSelf({ relayer, payload, accept }) {
1712
1756
  const a = relayer._native;
1713
1757
  if ("permit2Authorization" in payload) {
@@ -1720,6 +1764,9 @@ function makeEvmNetwork(resolved) {
1720
1764
  accept
1721
1765
  });
1722
1766
  }
1767
+ if ("transaction" in payload) {
1768
+ return { ok: false, error: "signature_invalid", detail: "An SVM (Solana) payload was submitted to an EVM exact rail." };
1769
+ }
1723
1770
  return verifyAndSettleExactEvm({
1724
1771
  publicClient,
1725
1772
  walletClient: a.walletClient,
@@ -1744,7 +1791,7 @@ var loaders = {
1744
1791
  solana: async () => {
1745
1792
  let mod;
1746
1793
  try {
1747
- mod = await Promise.resolve().then(() => _interopRequireWildcard(require("./solana-MPPE6K24.cjs")));
1794
+ mod = await Promise.resolve().then(() => _interopRequireWildcard(require("./solana-CCVSMOKS.cjs")));
1748
1795
  } catch (cause) {
1749
1796
  throw new (0, _chunkPA6YD3HLcjs.MissingDriverError)(
1750
1797
  `Solana selected, but its packages aren't installed. Run: npm install @solana/web3.js @solana/spl-token bs58`,
@@ -2770,7 +2817,7 @@ var PipRailClient = (_class2 = class {
2770
2817
  * before publishing, so retry with a brief backoff if a fresh listing is missing.
2771
2818
  * - Results are cross-scheme (mostly the mainstream `exact` scheme); `fetch()` pays
2772
2819
  * `onchain-proof` rails by default, and standard `exact` rails too once you opt in
2773
- * with `schemes: ['onchain-proof', 'exact']` (EVM + EIP-3009 USDC/EURC).
2820
+ * with `schemes: ['onchain-proof', 'exact']` (EVM EIP-3009/Permit2 + Solana SVM).
2774
2821
  */
2775
2822
  async discover(opts = {}) {
2776
2823
  const found = await searchOpenIndexes({
@@ -2955,7 +3002,7 @@ var PipRailClient = (_class2 = class {
2955
3002
  );
2956
3003
  if (schemes.includes("exact") && exactOnNet && typeof net.payExact !== "function") {
2957
3004
  throw new (0, _chunkPA6YD3HLcjs.UnsupportedSchemeError)(
2958
- `This 402 offers a standard 'exact' rail on ${net.network}, but the ${net.family} family can't pay 'exact' (EVM + EIP-3009 only), and no 'onchain-proof' rail was offered.`
3005
+ `This 402 offers a standard 'exact' rail on ${net.network}, but the ${net.family} family can't pay 'exact' (supported on EVM + Solana today), and no 'onchain-proof' rail was offered.`
2959
3006
  );
2960
3007
  }
2961
3008
  if (!schemes.includes("exact") && exactOnNet && typeof net.payExact === "function") {
@@ -3335,7 +3382,7 @@ var PipRailClient = (_class2 = class {
3335
3382
  async payExactRail(net, wallet, accept, url, init, quote) {
3336
3383
  if (!net.payExact) {
3337
3384
  throw new (0, _chunkPA6YD3HLcjs.UnsupportedSchemeError)(
3338
- `the ${net.family} family can't pay a standard 'exact' rail (EVM + EIP-3009 only).`
3385
+ `the ${net.family} family can't pay a standard 'exact' rail (supported on EVM + Solana today).`
3339
3386
  );
3340
3387
  }
3341
3388
  throwIfAborted(_optionalChain([init, 'optionalAccess', _48 => _48.signal]));
@@ -4012,6 +4059,24 @@ function buildX402DnsTxt(input) {
4012
4059
  }
4013
4060
 
4014
4061
  // src/facilitator.ts
4062
+ async function fetchFacilitatorFeePayer(url, network, timeoutMs = 8e3) {
4063
+ const base2 = url.replace(/\/+$/, "");
4064
+ const ctrl = new AbortController();
4065
+ const timer = setTimeout(() => ctrl.abort(), timeoutMs);
4066
+ try {
4067
+ const res = await fetch(`${base2}/supported`, { signal: ctrl.signal });
4068
+ if (!res.ok) return void 0;
4069
+ const body = await res.json();
4070
+ const kinds = Array.isArray(_optionalChain([body, 'optionalAccess', _64 => _64.kinds])) ? body.kinds : [];
4071
+ const kind = kinds.find((k) => _optionalChain([k, 'optionalAccess', _65 => _65.scheme]) === "exact" && _optionalChain([k, 'optionalAccess', _66 => _66.network]) === network);
4072
+ const fp = _optionalChain([kind, 'optionalAccess', _67 => _67.extra, 'optionalAccess', _68 => _68.feePayer]);
4073
+ return typeof fp === "string" ? fp : void 0;
4074
+ } catch (e32) {
4075
+ return void 0;
4076
+ } finally {
4077
+ clearTimeout(timer);
4078
+ }
4079
+ }
4015
4080
  function safeStringify(value) {
4016
4081
  return JSON.stringify(value, (_k, v) => typeof v === "bigint" ? v.toString() : v);
4017
4082
  }
@@ -4035,7 +4100,7 @@ async function post(url, body, headers) {
4035
4100
  let json = null;
4036
4101
  try {
4037
4102
  json = await res.json();
4038
- } catch (e32) {
4103
+ } catch (e33) {
4039
4104
  }
4040
4105
  return { status: res.status, json };
4041
4106
  }
@@ -4153,7 +4218,7 @@ function createPaymentGate(options) {
4153
4218
  );
4154
4219
  if (options.exact && !specs.some((s) => s.exact)) {
4155
4220
  throw new Error(
4156
- "requirePayment: `exact` was requested but none of the offered rails support it. The standard `exact` rail is EVM ERC-20 only \u2014 EIP-3009 (USDC / EURC) or Permit2 (any ERC-20, e.g. Binance-Peg USDC on BNB) \u2014 NOT native coins, NOT non-EVM chains. Offer an EVM ERC-20 token, or drop `exact`."
4221
+ "requirePayment: `exact` was requested but none of the offered rails support it. The standard `exact` rail is EVM ERC-20 (EIP-3009 \u2014 USDC / EURC \u2014 or Permit2, e.g. Binance-Peg USDC on BNB) or a Solana SPL token (SVM) \u2014 NOT native coins, NOT families without a standard `exact` scheme. Offer an EVM ERC-20 / Solana SPL token, or drop `exact`."
4157
4222
  );
4158
4223
  }
4159
4224
  return specs;
@@ -4166,53 +4231,32 @@ function createPaymentGate(options) {
4166
4231
  }
4167
4232
  async function resolveExactRail(net, asset) {
4168
4233
  const cfg = options.exact;
4169
- if (net.family !== "evm" || asset === "native" || !net.settleExactSelf) {
4170
- return void 0;
4171
- }
4172
- const want = _nullishCoalesce(cfg.method, () => ( "auto"));
4173
- let method;
4174
- let domain;
4175
- if (want === "permit2") {
4176
- method = "permit2";
4177
- } else {
4178
- const d = net.exactDomain ? await net.exactDomain(asset) : null;
4179
- if (d) {
4180
- method = "eip3009";
4181
- domain = d;
4182
- } else if (want === "eip3009") {
4183
- throw new Error(
4184
- `requirePayment: exact \`method: 'eip3009'\` requested for ${asset} on ${net.network}, but it isn't an EIP-3009 token (no name()/version()/authorizationState). Use \`method: 'permit2'\` (any ERC-20, e.g. Binance-Peg USDC on BNB) or \`'auto'\`. (Or check your rpcUrl is reachable.)`
4185
- );
4186
- } else {
4187
- method = "permit2";
4188
- }
4189
- }
4190
- if (method === "permit2" && !(_nullishCoalesce(_optionalChain([net, 'access', _64 => _64.exactPermit2Supported, 'optionalCall', _65 => _65()]), () => ( false)))) {
4191
- if (cfg.method === "permit2") {
4192
- throw new Error(
4193
- `requirePayment: exact \`method: 'permit2'\` needs the x402 Permit2 proxy deployed on ${net.network}, but it isn't there. Offer an EIP-3009 token (gasless, no proxy), or drop \`exact\` on this chain. (See PERMIT2_PROXY_CHAIN_IDS.)`
4194
- );
4195
- }
4196
- return void 0;
4197
- }
4234
+ if (!net.resolveExactRail) return void 0;
4235
+ let relayer;
4236
+ let feePayer;
4198
4237
  if (cfg.settle === "self") {
4199
4238
  if (cfg.relayer === void 0) {
4200
4239
  throw new Error(
4201
4240
  "requirePayment: exact `settle: 'self'` needs a `relayer` wallet (the gas-paying key that broadcasts the settle), e.g. exact: { settle: 'self', relayer: { privateKey } }."
4202
4241
  );
4203
4242
  }
4204
- const relayer = net.bindWallet(cfg.relayer);
4205
- return { method, ...domain ? { domain } : {}, mode: { kind: "self", relayer } };
4206
- }
4207
- return {
4208
- method,
4209
- ...domain ? { domain } : {},
4210
- mode: {
4211
- kind: "facilitator",
4212
- url: cfg.settle.facilitator,
4213
- ...cfg.settle.authHeaders ? { authHeaders: cfg.settle.authHeaders } : {}
4214
- }
4243
+ relayer = net.bindWallet(cfg.relayer);
4244
+ } else {
4245
+ feePayer = cfg.settle.feePayer;
4246
+ }
4247
+ const method = _nullishCoalesce(cfg.method, () => ( "auto"));
4248
+ let info = await net.resolveExactRail({ asset, method, relayer, feePayer });
4249
+ if (!info && cfg.settle !== "self" && !feePayer) {
4250
+ const discovered = await fetchFacilitatorFeePayer(cfg.settle.facilitator, net.network);
4251
+ if (discovered) info = await net.resolveExactRail({ asset, method, relayer, feePayer: discovered });
4252
+ }
4253
+ if (!info) return void 0;
4254
+ const mode = cfg.settle === "self" ? { kind: "self", relayer } : {
4255
+ kind: "facilitator",
4256
+ url: cfg.settle.facilitator,
4257
+ ...cfg.settle.authHeaders ? { authHeaders: cfg.settle.authHeaders } : {}
4215
4258
  };
4259
+ return { method: info.method, ...info.extra ? { extra: info.extra } : {}, mode };
4216
4260
  }
4217
4261
  const hasCustomStore = Boolean(options.isUsed || options.markUsed);
4218
4262
  const localUsed = /* @__PURE__ */ new Map();
@@ -4269,11 +4313,11 @@ function createPaymentGate(options) {
4269
4313
  maxTimeoutSeconds,
4270
4314
  extra: {
4271
4315
  assetTransferMethod: rail.method,
4272
- ...rail.domain ? { name: rail.domain.name, version: rail.domain.version } : {},
4273
4316
  minConfirmations,
4274
4317
  decimals: s.decimals,
4275
4318
  amountFormatted: s.amountFormatted,
4276
- ...s.symbol ? { symbol: s.symbol } : {}
4319
+ ...s.symbol ? { symbol: s.symbol } : {},
4320
+ ...rail.extra
4277
4321
  }
4278
4322
  };
4279
4323
  }
@@ -4289,7 +4333,7 @@ function createPaymentGate(options) {
4289
4333
  const specs = await ready();
4290
4334
  const nonce = genNonce();
4291
4335
  const bazaar = options.discovery ? { bazaar: buildBazaarExtension(options.discovery === true ? {} : options.discovery) } : void 0;
4292
- const extensions = { ...bazaar, ..._optionalChain([opts, 'optionalAccess', _66 => _66.extensions]) };
4336
+ const extensions = { ...bazaar, ..._optionalChain([opts, 'optionalAccess', _69 => _69.extensions]) };
4293
4337
  const challenge2 = {
4294
4338
  x402Version: 2,
4295
4339
  resource: {
@@ -4297,7 +4341,7 @@ function createPaymentGate(options) {
4297
4341
  ...options.description ? { description: options.description } : {}
4298
4342
  },
4299
4343
  accepts: buildAccepts(specs, nonce),
4300
- ..._optionalChain([opts, 'optionalAccess', _67 => _67.error]) ? { error: opts.error } : {},
4344
+ ..._optionalChain([opts, 'optionalAccess', _70 => _70.error]) ? { error: opts.error } : {},
4301
4345
  ...Object.keys(extensions).length > 0 ? { extensions } : {}
4302
4346
  };
4303
4347
  return { challenge: challenge2, requiredHeader: buildChallengeHeader(challenge2) };
@@ -4320,7 +4364,7 @@ function createPaymentGate(options) {
4320
4364
  let amountFormatted = receipt.amount;
4321
4365
  try {
4322
4366
  amountFormatted = _chunkPA6YD3HLcjs.formatUnits.call(void 0, BigInt(receipt.amount), spec.decimals);
4323
- } catch (e33) {
4367
+ } catch (e34) {
4324
4368
  }
4325
4369
  return {
4326
4370
  ...receipt,
@@ -4334,7 +4378,7 @@ function createPaymentGate(options) {
4334
4378
  if (!options.onPaidError) return;
4335
4379
  try {
4336
4380
  options.onPaidError(error, receipt);
4337
- } catch (e34) {
4381
+ } catch (e35) {
4338
4382
  }
4339
4383
  }
4340
4384
  function fireOnPaid(receipt) {
@@ -4426,10 +4470,23 @@ function createPaymentGate(options) {
4426
4470
  `No \`exact\` rail offered for ${exact.network}${exact.asset ? `/${exact.asset}` : ""} (offered: ${exactSpecs.map((s) => `${s.asset}@${s.net.network}`).join(", ")}).`
4427
4471
  );
4428
4472
  }
4429
- const auth = "permit2Authorization" in exact.payload ? exact.payload.permit2Authorization : exact.payload.authorization;
4430
- const nonce = auth.nonce;
4473
+ let nonce;
4474
+ let evmAuth = null;
4475
+ if ("transaction" in exact.payload) {
4476
+ try {
4477
+ nonce = Buffer.from(exact.payload.transaction, "base64").toString("base64");
4478
+ } catch (e36) {
4479
+ nonce = exact.payload.transaction;
4480
+ }
4481
+ } else if ("permit2Authorization" in exact.payload) {
4482
+ evmAuth = exact.payload.permit2Authorization;
4483
+ nonce = evmAuth.nonce;
4484
+ } else {
4485
+ evmAuth = exact.payload.authorization;
4486
+ nonce = evmAuth.nonce;
4487
+ }
4431
4488
  if (await claimTx(nonce)) {
4432
- return rejection("tx_already_used", `Authorization nonce ${nonce} was already redeemed.`);
4489
+ return rejection("tx_already_used", `Authorization ${evmAuth ? `nonce ${nonce}` : "transaction"} was already redeemed.`);
4433
4490
  }
4434
4491
  const accept = buildExactAccept(spec);
4435
4492
  const mode = spec.exact.mode;
@@ -4454,12 +4511,14 @@ function createPaymentGate(options) {
4454
4511
  amount: accept.amount,
4455
4512
  payTo: accept.payTo,
4456
4513
  maxTimeoutSeconds: accept.maxTimeoutSeconds,
4457
- // name/version are OPTIONAL on the wire type (a foreign rail may omit them), but the
4458
- // gate's OWN exact rail always read them on-chain at resolution — so they're present here.
4459
- extra: { name: _nullishCoalesce(accept.extra.name, () => ( "")), version: _nullishCoalesce(accept.extra.version, () => ( "")) }
4514
+ // The scheme's chain-specific `extra`, from the gate's OWN trusted rail: SVM forwards the
4515
+ // facilitator's `feePayer` (the gas sponsor); EVM forwards the token's EIP-712 domain.
4516
+ extra: accept.extra.assetTransferMethod === "svm" ? { feePayer: _nullishCoalesce(accept.extra.feePayer, () => ( "")) } : { name: _nullishCoalesce(accept.extra.name, () => ( "")), version: _nullishCoalesce(accept.extra.version, () => ( "")) }
4460
4517
  },
4461
4518
  receipt: { network: accept.network, asset: accept.asset, payTo: accept.payTo, amount: accept.amount },
4462
- payerHint: auth.from
4519
+ // The buyer address, for the receipt's `payer` fallback. EVM carries it in the
4520
+ // authorization; SVM doesn't (the facilitator returns the settled payer) → omit it.
4521
+ ...evmAuth ? { payerHint: evmAuth.from } : {}
4463
4522
  });
4464
4523
  }
4465
4524
  } catch (err) {
@@ -4537,7 +4596,7 @@ function isRetryableStatus(status) {
4537
4596
  }
4538
4597
  var sleep = (ms) => ms > 0 ? new Promise((resolve) => setTimeout(resolve, ms)) : Promise.resolve();
4539
4598
  async function signBody(secret, body) {
4540
- const subtle = _optionalChain([globalThis, 'access', _68 => _68.crypto, 'optionalAccess', _69 => _69.subtle]);
4599
+ const subtle = _optionalChain([globalThis, 'access', _71 => _71.crypto, 'optionalAccess', _72 => _72.subtle]);
4541
4600
  if (!subtle) return null;
4542
4601
  try {
4543
4602
  const enc = new TextEncoder();
@@ -4547,7 +4606,7 @@ async function signBody(secret, body) {
4547
4606
  const sig = await subtle.sign("HMAC", key, enc.encode(body));
4548
4607
  const hex = Array.from(new Uint8Array(sig)).map((b) => b.toString(16).padStart(2, "0")).join("");
4549
4608
  return `sha256=${hex}`;
4550
- } catch (e35) {
4609
+ } catch (e37) {
4551
4610
  return null;
4552
4611
  }
4553
4612
  }
@@ -4607,8 +4666,8 @@ async function deliverReceipt(receipt, options) {
4607
4666
  const retryable = status === void 0 ? true : isRetryableStatus(status);
4608
4667
  const willRetry = !ok && retryable && attempt < maxAttempts;
4609
4668
  try {
4610
- _optionalChain([onAttempt, 'optionalCall', _70 => _70({ attempt, ok, ...status !== void 0 ? { status } : {}, ...error ? { error } : {}, willRetry })]);
4611
- } catch (e36) {
4669
+ _optionalChain([onAttempt, 'optionalCall', _73 => _73({ attempt, ok, ...status !== void 0 ? { status } : {}, ...error ? { error } : {}, willRetry })]);
4670
+ } catch (e38) {
4612
4671
  }
4613
4672
  if (ok) return { delivered: true, attempts: attempt, status };
4614
4673
  if (!willRetry) {