@piprail/sdk 2.14.2 → 2.15.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,30 @@ 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
+ ## [2.15.0] — 2026-06-24 — merchant on-ramp: presets, adapters, `gate.selfTest()`
8
+
9
+ ### Added — merchant on-ramp (presets, adapters, self-test)
10
+
11
+ Make the *accept* side as terse as the *pay* side. All additive — the zero-config
12
+ `createPaymentGate` / `requirePayment` / `PipRailClient` paths stay byte-identical.
13
+
14
+ - **Merchant presets** — `createPaywall` (a fixed price for a resource) and `createTipJar`
15
+ (pay-what-you-want ≥ a minimum): named sugar over `createPaymentGate` with `token` defaulting to
16
+ USDC. Each resolves to a standard gate, so its 402 is byte-identical to the hand-written equivalent.
17
+ - **Framework adapters** — `toFetchHandler` (the universal `(request, …) => Response` for Next.js,
18
+ Netlify, Bun, Deno, Vercel, Hono, Lambda — anything request-in/response-out) and `toWorker` (the
19
+ `{ fetch }` export for Cloudflare / Service Workers). One call runs the whole read-header →
20
+ switch-on-`kind` → write-headers contract (502 on a `SettlementError`, never 402) and forwards any
21
+ extra runtime args (`env`/`ctx`/`params`) to your handler. Express keeps `requirePayment`.
22
+ - **`proxyTo(origin)`** — a ready-made `serve` that forwards a PAID request to an existing backend (any
23
+ language), untouched, stripping the proof headers; the origin never sees an unpaid request.
24
+ `toWorker(gate, proxyTo('https://my-api.com'))` puts a paywall in front of a whole API.
25
+ - **`gate.selfTest()`** — a read-only, never-throw config check that resolves the gate's rails and
26
+ reports `{ ok, rails, warnings }` (or `{ ok:false, error }`) without signing or sending. Powers a
27
+ merchant's `npm run verify` and a scaffolder's post-deploy smoke step.
28
+ - New exports: `createPaywall`, `createTipJar`, `toFetchHandler`, `toWorker`, `proxyTo`; types
29
+ `PaywallOptions`, `TipJarOptions`, `Serve`, `GateSelfTest`.
30
+
7
31
  ## [2.14.2] — 2026-06-24 — deeper element-level hardening (the 2.14.1 break-it pass, round two)
8
32
 
9
33
  A follow-up patch to 2.14.1. A second adversarial smash pass found that 2.14.1 guarded the
@@ -1828,6 +1852,7 @@ straight into your wallet. The API is small and self-contained.
1828
1852
  to your wallet; PipRail never holds funds.
1829
1853
  - `viem ^2.21` is a peer dependency. Node 20+ or a modern browser.
1830
1854
 
1855
+ [2.15.0]: https://www.npmjs.com/package/@piprail/sdk
1831
1856
  [2.14.0]: https://www.npmjs.com/package/@piprail/sdk
1832
1857
  [2.13.1]: https://www.npmjs.com/package/@piprail/sdk
1833
1858
  [2.12.0]: https://www.npmjs.com/package/@piprail/sdk
package/README.md CHANGED
@@ -26,6 +26,8 @@ app.get('/report',
26
26
 
27
27
  That route now costs **0.05 USDC on Base**, paid straight to your wallet. One parameter picks the chain. Add `onPaid` / `onFailed` to be notified the moment a payment settles or is rejected — both carry the same reason, and the buyer's client is notified too. → [Accepting payments](https://docs.piprail.com/accepting-payments/require-payment-and-gate/)
28
28
 
29
+ > **Don't want to wire it by hand?** `npm create piprail@latest` scaffolds a complete, mainnet-ready, deployable merchant (node / Cloudflare / Vercel) — paste a public address, no key, no account. → [Scaffold a merchant](https://docs.piprail.com/getting-started/scaffolder/)
30
+
29
31
  ## Let an agent pay for it
30
32
 
31
33
  ```ts
@@ -74,7 +76,7 @@ The same app can **take** payments and **make** them. → [Making payments](http
74
76
  | | |
75
77
  |---|---|
76
78
  | **[Getting started](https://docs.piprail.com/getting-started/introduction/)** | Install · quickstart · how it works |
77
- | **[Accepting payments](https://docs.piprail.com/accepting-payments/require-payment-and-gate/)** | `requirePayment` · `createPaymentGate` · the `exact` rail · the `upto` metered rail |
79
+ | **[Accepting payments](https://docs.piprail.com/accepting-payments/require-payment-and-gate/)** | `requirePayment` · `createPaymentGate` · [presets](https://docs.piprail.com/accepting-payments/merchant-presets/) (`createPaywall` / `createTipJar`) · [framework adapters](https://docs.piprail.com/accepting-payments/framework-adapters/) · the `exact` rail · the `upto` metered rail |
78
80
  | **[Making payments](https://docs.piprail.com/making-payments/piprail-client/)** | `PipRailClient` · `quote` · `estimateCost` · `planPayment` · auto-route · `MultiChainPayer` |
79
81
  | **[Verifiable receipts](https://docs.piprail.com/accepting-payments/verifiable-receipts/)** | Chain-grounded, anyone-verifiable receipts (no key) · optional EIP-712 attestation |
80
82
  | **[Spend controls](https://docs.piprail.com/spend-controls/payment-policy/)** | Per-token + cross-token grand total · payment-count caps · time envelope · durable budget · the spend ledger |
package/dist/index.cjs CHANGED
@@ -7499,7 +7499,36 @@ function createPaymentGate(options) {
7499
7499
  await settleTx(idKey, result.kind === "paid");
7500
7500
  return result.kind === "paid" ? echoPaymentIdentifier(result, id) : result;
7501
7501
  }
7502
- return { challenge, verify, verifyObject, describe, landingPage };
7502
+ async function selfTest() {
7503
+ try {
7504
+ const specs = await ready();
7505
+ const warnings = [];
7506
+ const rails = specs.map((s) => {
7507
+ if (!s.symbol) {
7508
+ warnings.push(
7509
+ `${s.asset} on ${s.net.network}: custom token (no built-in symbol) \u2014 double-check the address + decimals.`
7510
+ );
7511
+ }
7512
+ return {
7513
+ network: s.net.network,
7514
+ asset: s.asset,
7515
+ ...s.symbol ? { symbol: s.symbol } : {},
7516
+ decimals: s.decimals,
7517
+ amount: s.amountFormatted,
7518
+ payTo: s.payTo,
7519
+ schemes: [
7520
+ ...s.exact ? ["exact"] : [],
7521
+ ...s.upto ? ["upto"] : [],
7522
+ "onchain-proof"
7523
+ ]
7524
+ };
7525
+ });
7526
+ return { ok: true, rails, warnings };
7527
+ } catch (err) {
7528
+ return { ok: false, rails: [], warnings: [], error: err instanceof Error ? err.message : String(err) };
7529
+ }
7530
+ }
7531
+ return { challenge, verify, verifyObject, describe, landingPage, selfTest };
7503
7532
  }
7504
7533
  function requirePayment(options) {
7505
7534
  if (options.upto) {
@@ -7551,6 +7580,87 @@ function normaliseHeader(value) {
7551
7580
  return value;
7552
7581
  }
7553
7582
 
7583
+ // src/merchant.ts
7584
+ function createPaywall({ token = "USDC", ...rest }) {
7585
+ return createPaymentGate({ token, ...rest });
7586
+ }
7587
+ function createTipJar({ token = "USDC", min, ...rest }) {
7588
+ return createPaymentGate({ token, amount: min, ...rest });
7589
+ }
7590
+
7591
+ // src/adapters.ts
7592
+ function jsonResponse(body, status, headers) {
7593
+ return new Response(JSON.stringify(body), {
7594
+ status,
7595
+ headers: { "content-type": "application/json; charset=utf-8", ..._nullishCoalesce(headers, () => ( {})) }
7596
+ });
7597
+ }
7598
+ function withSettlementHeaders(res, receiptHeader) {
7599
+ const headers = new Headers();
7600
+ res.headers.forEach((value, key) => {
7601
+ if (key.toLowerCase() !== "set-cookie") headers.append(key, value);
7602
+ });
7603
+ const src = res.headers;
7604
+ const cookies = typeof src.getSetCookie === "function" ? src.getSetCookie() : (() => {
7605
+ const combined = res.headers.get("set-cookie");
7606
+ return combined ? [combined] : [];
7607
+ })();
7608
+ for (const cookie of cookies) headers.append("set-cookie", cookie);
7609
+ headers.set(HEADER_RESPONSE, receiptHeader);
7610
+ headers.set(HEADER_RESPONSE_V1, receiptHeader);
7611
+ return new Response(res.body, { status: res.status, statusText: res.statusText, headers });
7612
+ }
7613
+ function toFetchHandler(gate, serve) {
7614
+ return async (request, ...rest) => {
7615
+ let result;
7616
+ try {
7617
+ const sig = _nullishCoalesce(_nullishCoalesce(request.headers.get(HEADER_SIGNATURE), () => ( request.headers.get(HEADER_SIGNATURE_V1))), () => ( void 0));
7618
+ result = await gate.verify(sig);
7619
+ } catch (err) {
7620
+ if (err instanceof _chunk3FR22M3Ocjs.SettlementError) {
7621
+ return jsonResponse(
7622
+ {
7623
+ x402Version: 2,
7624
+ error: "settlement_failed",
7625
+ detail: err.message,
7626
+ fallback: "The gasless `exact` settlement failed. This resource also accepts `onchain-proof` \u2014 retry by paying that rail yourself (you broadcast the transfer and pay the gas)."
7627
+ },
7628
+ 502
7629
+ );
7630
+ }
7631
+ throw err;
7632
+ }
7633
+ if (result.kind === "paid") {
7634
+ const res = await serve(request, ...rest);
7635
+ return withSettlementHeaders(res, result.receiptHeader);
7636
+ }
7637
+ return jsonResponse(result.challenge, 402, { [HEADER_REQUIRED]: result.requiredHeader });
7638
+ };
7639
+ }
7640
+ function toWorker(gate, serve) {
7641
+ return { fetch: toFetchHandler(gate, serve) };
7642
+ }
7643
+ function proxyTo(origin) {
7644
+ const base2 = origin.replace(/\/+$/, "");
7645
+ return (request) => {
7646
+ const inUrl = new URL(request.url);
7647
+ const target = base2 + inUrl.pathname + inUrl.search;
7648
+ const headers = new Headers(request.headers);
7649
+ headers.delete(HEADER_SIGNATURE);
7650
+ headers.delete(HEADER_SIGNATURE_V1);
7651
+ const init = {
7652
+ method: request.method,
7653
+ headers,
7654
+ redirect: "manual"
7655
+ };
7656
+ if (request.method !== "GET" && request.method !== "HEAD") {
7657
+ init.body = request.body;
7658
+ init.duplex = "half";
7659
+ }
7660
+ return fetch(target, init);
7661
+ };
7662
+ }
7663
+
7554
7664
  // src/receipts.ts
7555
7665
  var DEFAULT_RETRIES = 5;
7556
7666
  var DEFAULT_TIMEOUT_MS = 1e4;
@@ -8155,4 +8265,9 @@ function createMcpPaymentTool(options) {
8155
8265
 
8156
8266
 
8157
8267
 
8158
- exports.A2A_ERROR_KEY = A2A_ERROR_KEY; exports.A2A_EXTENSIONS_HEADER = A2A_EXTENSIONS_HEADER; exports.A2A_PAYLOAD_KEY = A2A_PAYLOAD_KEY; exports.A2A_RECEIPTS_KEY = A2A_RECEIPTS_KEY; exports.A2A_REQUIRED_KEY = A2A_REQUIRED_KEY; exports.A2A_STATUS_KEY = A2A_STATUS_KEY; exports.A2A_X402_EXTENSION_URI_V01 = A2A_X402_EXTENSION_URI_V01; exports.A2A_X402_EXTENSION_URI_V02 = A2A_X402_EXTENSION_URI_V02; exports.BRAND = BRAND; exports.BUILTIN_DENOMS = BUILTIN_DENOMS; exports.CHAINS = CHAINS; exports.ConfirmationTimeoutError = _chunk3FR22M3Ocjs.ConfirmationTimeoutError; exports.DENOM_PRECISION = DENOM_PRECISION; exports.DIRECTORY_INFO = DIRECTORY_INFO; exports.EIP3009_TYPES = EIP3009_TYPES; exports.EXACT_NETWORK_SLUGS = EXACT_NETWORK_SLUGS; exports.EXT_OFFER_RECEIPT = EXT_OFFER_RECEIPT; exports.EXT_PAYMENT_IDENTIFIER = EXT_PAYMENT_IDENTIFIER; exports.GENERATOR = GENERATOR; exports.HEADER_REQUIRED = HEADER_REQUIRED; exports.HEADER_RESPONSE = HEADER_RESPONSE; exports.HEADER_RESPONSE_V1 = HEADER_RESPONSE_V1; exports.HEADER_SIGNATURE = HEADER_SIGNATURE; exports.HEADER_SIGNATURE_V1 = HEADER_SIGNATURE_V1; exports.InsufficientFundsError = _chunk3FR22M3Ocjs.InsufficientFundsError; exports.InvalidConfigError = _chunk3FR22M3Ocjs.InvalidConfigError; exports.InvalidEnvelopeError = _chunk3FR22M3Ocjs.InvalidEnvelopeError; exports.KNOWN_FACILITATORS = KNOWN_FACILITATORS; exports.MCP_PAYMENT_META_KEY = MCP_PAYMENT_META_KEY; exports.MCP_PAYMENT_RESPONSE_META_KEY = MCP_PAYMENT_RESPONSE_META_KEY; exports.MaxRetriesExceededError = _chunk3FR22M3Ocjs.MaxRetriesExceededError; exports.MissingDriverError = _chunk3FR22M3Ocjs.MissingDriverError; exports.MultiChainPayer = MultiChainPayer; exports.NoCompatibleAcceptError = _chunk3FR22M3Ocjs.NoCompatibleAcceptError; exports.NonReplayableBodyError = _chunk3FR22M3Ocjs.NonReplayableBodyError; exports.PERMIT2_ADDRESS = PERMIT2_ADDRESS; exports.PERMIT2_PROXY_CHAIN_IDS = PERMIT2_PROXY_CHAIN_IDS; exports.PERMIT2_UPTO_WITNESS_TYPES = PERMIT2_UPTO_WITNESS_TYPES; exports.PERMIT2_WITNESS_TYPES = PERMIT2_WITNESS_TYPES; exports.PIPRAIL_AGENT_GUIDE = PIPRAIL_AGENT_GUIDE; exports.POWERED_BY = POWERED_BY; exports.PaymentDeclinedError = _chunk3FR22M3Ocjs.PaymentDeclinedError; exports.PaymentTimeoutError = _chunk3FR22M3Ocjs.PaymentTimeoutError; exports.PipRailClient = PipRailClient; exports.PipRailError = _chunk3FR22M3Ocjs.PipRailError; exports.REGISTER_ATTRIBUTION = REGISTER_ATTRIBUTION; exports.RecipientNotReadyError = _chunk3FR22M3Ocjs.RecipientNotReadyError; exports.SettlementError = _chunk3FR22M3Ocjs.SettlementError; exports.SpendLedger = SpendLedger; exports.UPTO_PROXY_CHAIN_IDS = UPTO_PROXY_CHAIN_IDS; exports.UnknownTokenError = _chunk3FR22M3Ocjs.UnknownTokenError; exports.UnsupportedNetworkError = _chunk3FR22M3Ocjs.UnsupportedNetworkError; exports.UnsupportedSchemeError = _chunk3FR22M3Ocjs.UnsupportedSchemeError; exports.VERIFY_CODE_TO_A2A_ERROR = VERIFY_CODE_TO_A2A_ERROR; exports.WalletRequiredError = _chunk3FR22M3Ocjs.WalletRequiredError; exports.WrongChainError = _chunk3FR22M3Ocjs.WrongChainError; exports.WrongFamilyError = _chunk3FR22M3Ocjs.WrongFamilyError; exports.X402_EXACT_PERMIT2_PROXY = X402_EXACT_PERMIT2_PROXY; exports.X402_UPTO_PERMIT2_PROXY = X402_UPTO_PERMIT2_PROXY; exports.agentGuide = agentGuide; exports.appendAttribution = appendAttribution; exports.appendKeywords = appendKeywords; exports.buildBazaarExtension = buildBazaarExtension; exports.buildChallengeHeader = buildChallengeHeader; exports.buildEndpointInfo = buildEndpointInfo; exports.buildExactAuthorization = buildExactAuthorization; exports.buildExactSignatureHeader = buildExactSignatureHeader; exports.buildMcpPaymentMeta = buildMcpPaymentMeta; exports.buildOpenApi = buildOpenApi; exports.buildPaymentIdentifierAdvertisement = buildPaymentIdentifierAdvertisement; exports.buildReceiptExtension = buildReceiptExtension; exports.buildReceiptHeader = buildReceiptHeader; exports.buildSelfDescription = buildSelfDescription; exports.buildSignatureHeader = buildSignatureHeader; exports.buildUptoSignatureHeader = buildUptoSignatureHeader; exports.buildWellKnownX402 = buildWellKnownX402; exports.buildWellKnownX402Manifest = buildWellKnownX402Manifest; exports.buildX402DnsTxt = buildX402DnsTxt; exports.chainIdForExactNetwork = chainIdForExactNetwork; exports.claim402IndexDomain = claim402IndexDomain; exports.classifyChallenge = classifyChallenge; exports.createA2APaymentHandler = createA2APaymentHandler; exports.createMcpPaymentTool = createMcpPaymentTool; exports.createPaymentGate = createPaymentGate; exports.decodeBase64Json = decodeBase64Json; exports.decorateOutcome = decorateOutcome; exports.deliverReceipt = deliverReceipt; exports.denomOf = denomOf; exports.describeChallenge = describeChallenge; exports.discoveryHeaders = discoveryHeaders; exports.eip3009Abi = eip3009Abi; exports.encodeXPaymentHeader = encodeXPaymentHeader; exports.evaluatePolicy = evaluatePolicy; exports.explainDecline = explainDecline; exports.facilitatorCoverage = facilitatorCoverage; exports.fetchAcross = fetchAcross; exports.firstKeylessFacilitator = firstKeylessFacilitator; exports.formatSpendReport = formatSpendReport; exports.fromA2APaymentPayload = fromA2APaymentPayload; exports.fromA2APaymentRequired = fromA2APaymentRequired; exports.fromMcpPayment = fromMcpPayment; exports.fromMcpPaymentRequired = fromMcpPaymentRequired; exports.fromMcpPaymentResponse = fromMcpPaymentResponse; exports.getDirectoryInfo = getDirectoryInfo; exports.isMcpPaymentRequired = isMcpPaymentRequired; exports.isPermit2ProxyChain = isPermit2ProxyChain; exports.isUptoProxyChain = isUptoProxyChain; exports.knownFacilitatorsFor = knownFacilitatorsFor; exports.memorySpendStore = _chunkO4UQOZ4Zcjs.memorySpendStore; exports.normalizeNetwork = normalizeNetwork; exports.parseChallenge = parseChallenge; exports.parseExactObject = parseExactObject; exports.parseExactPaymentHeader = parseExactPaymentHeader; exports.parseExactRequirements = parseExactRequirements; exports.parseFacilitatorSupported = parseFacilitatorSupported; exports.parseReceipt = parseReceipt; exports.parseReceiptExtension = parseReceiptExtension; exports.parseSettleResponse = parseSettleResponse; exports.parseSignatureHeader = parseSignatureHeader; exports.parseSignatureObject = parseSignatureObject; exports.parseUptoObject = parseUptoObject; exports.parseUptoPaymentHeader = parseUptoPaymentHeader; exports.paymentTools = paymentTools; exports.pickAccept = pickAccept; exports.planAcross = planAcross; exports.rankResources = rankResources; exports.readExactDomain = readExactDomain; exports.readPaymentIdentifier = readPaymentIdentifier; exports.register402Index = register402Index; exports.registerDriver = registerDriver; exports.registerX402Scan = registerX402Scan; exports.renderLandingPage = renderLandingPage; exports.requirePayment = requirePayment; exports.resolveChain = resolveChain; exports.scoreResource = scoreResource; exports.searchOpenIndexes = searchOpenIndexes; exports.settleViaFacilitator = settleViaFacilitator; exports.summarizePlan = summarizePlan; exports.toA2AErrorCode = toA2AErrorCode; exports.toA2APaymentFailed = toA2APaymentFailed; exports.toA2APaymentReceipts = toA2APaymentReceipts; exports.toA2APaymentRequired = toA2APaymentRequired; exports.toInsufficientFundsError = _chunk3FR22M3Ocjs.toInsufficientFundsError; exports.toInvalidBody = toInvalidBody; exports.toMcpPaymentRequired = toMcpPaymentRequired; exports.toMcpPaymentResponse = toMcpPaymentResponse; exports.verify402IndexDomain = verify402IndexDomain;
8268
+
8269
+
8270
+
8271
+
8272
+
8273
+ exports.A2A_ERROR_KEY = A2A_ERROR_KEY; exports.A2A_EXTENSIONS_HEADER = A2A_EXTENSIONS_HEADER; exports.A2A_PAYLOAD_KEY = A2A_PAYLOAD_KEY; exports.A2A_RECEIPTS_KEY = A2A_RECEIPTS_KEY; exports.A2A_REQUIRED_KEY = A2A_REQUIRED_KEY; exports.A2A_STATUS_KEY = A2A_STATUS_KEY; exports.A2A_X402_EXTENSION_URI_V01 = A2A_X402_EXTENSION_URI_V01; exports.A2A_X402_EXTENSION_URI_V02 = A2A_X402_EXTENSION_URI_V02; exports.BRAND = BRAND; exports.BUILTIN_DENOMS = BUILTIN_DENOMS; exports.CHAINS = CHAINS; exports.ConfirmationTimeoutError = _chunk3FR22M3Ocjs.ConfirmationTimeoutError; exports.DENOM_PRECISION = DENOM_PRECISION; exports.DIRECTORY_INFO = DIRECTORY_INFO; exports.EIP3009_TYPES = EIP3009_TYPES; exports.EXACT_NETWORK_SLUGS = EXACT_NETWORK_SLUGS; exports.EXT_OFFER_RECEIPT = EXT_OFFER_RECEIPT; exports.EXT_PAYMENT_IDENTIFIER = EXT_PAYMENT_IDENTIFIER; exports.GENERATOR = GENERATOR; exports.HEADER_REQUIRED = HEADER_REQUIRED; exports.HEADER_RESPONSE = HEADER_RESPONSE; exports.HEADER_RESPONSE_V1 = HEADER_RESPONSE_V1; exports.HEADER_SIGNATURE = HEADER_SIGNATURE; exports.HEADER_SIGNATURE_V1 = HEADER_SIGNATURE_V1; exports.InsufficientFundsError = _chunk3FR22M3Ocjs.InsufficientFundsError; exports.InvalidConfigError = _chunk3FR22M3Ocjs.InvalidConfigError; exports.InvalidEnvelopeError = _chunk3FR22M3Ocjs.InvalidEnvelopeError; exports.KNOWN_FACILITATORS = KNOWN_FACILITATORS; exports.MCP_PAYMENT_META_KEY = MCP_PAYMENT_META_KEY; exports.MCP_PAYMENT_RESPONSE_META_KEY = MCP_PAYMENT_RESPONSE_META_KEY; exports.MaxRetriesExceededError = _chunk3FR22M3Ocjs.MaxRetriesExceededError; exports.MissingDriverError = _chunk3FR22M3Ocjs.MissingDriverError; exports.MultiChainPayer = MultiChainPayer; exports.NoCompatibleAcceptError = _chunk3FR22M3Ocjs.NoCompatibleAcceptError; exports.NonReplayableBodyError = _chunk3FR22M3Ocjs.NonReplayableBodyError; exports.PERMIT2_ADDRESS = PERMIT2_ADDRESS; exports.PERMIT2_PROXY_CHAIN_IDS = PERMIT2_PROXY_CHAIN_IDS; exports.PERMIT2_UPTO_WITNESS_TYPES = PERMIT2_UPTO_WITNESS_TYPES; exports.PERMIT2_WITNESS_TYPES = PERMIT2_WITNESS_TYPES; exports.PIPRAIL_AGENT_GUIDE = PIPRAIL_AGENT_GUIDE; exports.POWERED_BY = POWERED_BY; exports.PaymentDeclinedError = _chunk3FR22M3Ocjs.PaymentDeclinedError; exports.PaymentTimeoutError = _chunk3FR22M3Ocjs.PaymentTimeoutError; exports.PipRailClient = PipRailClient; exports.PipRailError = _chunk3FR22M3Ocjs.PipRailError; exports.REGISTER_ATTRIBUTION = REGISTER_ATTRIBUTION; exports.RecipientNotReadyError = _chunk3FR22M3Ocjs.RecipientNotReadyError; exports.SettlementError = _chunk3FR22M3Ocjs.SettlementError; exports.SpendLedger = SpendLedger; exports.UPTO_PROXY_CHAIN_IDS = UPTO_PROXY_CHAIN_IDS; exports.UnknownTokenError = _chunk3FR22M3Ocjs.UnknownTokenError; exports.UnsupportedNetworkError = _chunk3FR22M3Ocjs.UnsupportedNetworkError; exports.UnsupportedSchemeError = _chunk3FR22M3Ocjs.UnsupportedSchemeError; exports.VERIFY_CODE_TO_A2A_ERROR = VERIFY_CODE_TO_A2A_ERROR; exports.WalletRequiredError = _chunk3FR22M3Ocjs.WalletRequiredError; exports.WrongChainError = _chunk3FR22M3Ocjs.WrongChainError; exports.WrongFamilyError = _chunk3FR22M3Ocjs.WrongFamilyError; exports.X402_EXACT_PERMIT2_PROXY = X402_EXACT_PERMIT2_PROXY; exports.X402_UPTO_PERMIT2_PROXY = X402_UPTO_PERMIT2_PROXY; exports.agentGuide = agentGuide; exports.appendAttribution = appendAttribution; exports.appendKeywords = appendKeywords; exports.buildBazaarExtension = buildBazaarExtension; exports.buildChallengeHeader = buildChallengeHeader; exports.buildEndpointInfo = buildEndpointInfo; exports.buildExactAuthorization = buildExactAuthorization; exports.buildExactSignatureHeader = buildExactSignatureHeader; exports.buildMcpPaymentMeta = buildMcpPaymentMeta; exports.buildOpenApi = buildOpenApi; exports.buildPaymentIdentifierAdvertisement = buildPaymentIdentifierAdvertisement; exports.buildReceiptExtension = buildReceiptExtension; exports.buildReceiptHeader = buildReceiptHeader; exports.buildSelfDescription = buildSelfDescription; exports.buildSignatureHeader = buildSignatureHeader; exports.buildUptoSignatureHeader = buildUptoSignatureHeader; exports.buildWellKnownX402 = buildWellKnownX402; exports.buildWellKnownX402Manifest = buildWellKnownX402Manifest; exports.buildX402DnsTxt = buildX402DnsTxt; exports.chainIdForExactNetwork = chainIdForExactNetwork; exports.claim402IndexDomain = claim402IndexDomain; exports.classifyChallenge = classifyChallenge; exports.createA2APaymentHandler = createA2APaymentHandler; exports.createMcpPaymentTool = createMcpPaymentTool; exports.createPaymentGate = createPaymentGate; exports.createPaywall = createPaywall; exports.createTipJar = createTipJar; exports.decodeBase64Json = decodeBase64Json; exports.decorateOutcome = decorateOutcome; exports.deliverReceipt = deliverReceipt; exports.denomOf = denomOf; exports.describeChallenge = describeChallenge; exports.discoveryHeaders = discoveryHeaders; exports.eip3009Abi = eip3009Abi; exports.encodeXPaymentHeader = encodeXPaymentHeader; exports.evaluatePolicy = evaluatePolicy; exports.explainDecline = explainDecline; exports.facilitatorCoverage = facilitatorCoverage; exports.fetchAcross = fetchAcross; exports.firstKeylessFacilitator = firstKeylessFacilitator; exports.formatSpendReport = formatSpendReport; exports.fromA2APaymentPayload = fromA2APaymentPayload; exports.fromA2APaymentRequired = fromA2APaymentRequired; exports.fromMcpPayment = fromMcpPayment; exports.fromMcpPaymentRequired = fromMcpPaymentRequired; exports.fromMcpPaymentResponse = fromMcpPaymentResponse; exports.getDirectoryInfo = getDirectoryInfo; exports.isMcpPaymentRequired = isMcpPaymentRequired; exports.isPermit2ProxyChain = isPermit2ProxyChain; exports.isUptoProxyChain = isUptoProxyChain; exports.knownFacilitatorsFor = knownFacilitatorsFor; exports.memorySpendStore = _chunkO4UQOZ4Zcjs.memorySpendStore; exports.normalizeNetwork = normalizeNetwork; exports.parseChallenge = parseChallenge; exports.parseExactObject = parseExactObject; exports.parseExactPaymentHeader = parseExactPaymentHeader; exports.parseExactRequirements = parseExactRequirements; exports.parseFacilitatorSupported = parseFacilitatorSupported; exports.parseReceipt = parseReceipt; exports.parseReceiptExtension = parseReceiptExtension; exports.parseSettleResponse = parseSettleResponse; exports.parseSignatureHeader = parseSignatureHeader; exports.parseSignatureObject = parseSignatureObject; exports.parseUptoObject = parseUptoObject; exports.parseUptoPaymentHeader = parseUptoPaymentHeader; exports.paymentTools = paymentTools; exports.pickAccept = pickAccept; exports.planAcross = planAcross; exports.proxyTo = proxyTo; exports.rankResources = rankResources; exports.readExactDomain = readExactDomain; exports.readPaymentIdentifier = readPaymentIdentifier; exports.register402Index = register402Index; exports.registerDriver = registerDriver; exports.registerX402Scan = registerX402Scan; exports.renderLandingPage = renderLandingPage; exports.requirePayment = requirePayment; exports.resolveChain = resolveChain; exports.scoreResource = scoreResource; exports.searchOpenIndexes = searchOpenIndexes; exports.settleViaFacilitator = settleViaFacilitator; exports.summarizePlan = summarizePlan; exports.toA2AErrorCode = toA2AErrorCode; exports.toA2APaymentFailed = toA2APaymentFailed; exports.toA2APaymentReceipts = toA2APaymentReceipts; exports.toA2APaymentRequired = toA2APaymentRequired; exports.toFetchHandler = toFetchHandler; exports.toInsufficientFundsError = _chunk3FR22M3Ocjs.toInsufficientFundsError; exports.toInvalidBody = toInvalidBody; exports.toMcpPaymentRequired = toMcpPaymentRequired; exports.toMcpPaymentResponse = toMcpPaymentResponse; exports.toWorker = toWorker; exports.verify402IndexDomain = verify402IndexDomain;
package/dist/index.d.cts CHANGED
@@ -7169,6 +7169,34 @@ declare function toInvalidBody(result: {
7169
7169
  error: string;
7170
7170
  detail: string;
7171
7171
  }): X402InvalidBody;
7172
+ /**
7173
+ * The result of {@link PaymentGate.selfTest} — a read-only config check. NEVER throws, and never
7174
+ * touches the network beyond the same lazy driver/token resolution the first `challenge()` does
7175
+ * (no signing, no sending). `ok:true` with the resolved `rails` when the config is sound; `ok:false`
7176
+ * with a human `error` when something's wrong (no payTo, a malformed address for the family, an
7177
+ * unknown token, an unresolvable chain). Powers a scaffolder's "✅ your endpoint is configured"
7178
+ * step and a merchant's `npm run verify`.
7179
+ */
7180
+ interface GateSelfTest {
7181
+ ok: boolean;
7182
+ /** One entry per resolved payment option (empty when `ok:false`). */
7183
+ rails: Array<{
7184
+ /** CAIP-2 network, e.g. `eip155:8453`. */
7185
+ network: string;
7186
+ asset: string;
7187
+ symbol?: string;
7188
+ decimals: number;
7189
+ /** Human amount the gate charges (for a tip jar, the minimum/floor). */
7190
+ amount: string;
7191
+ payTo: AddressId;
7192
+ /** The schemes this rail offers, e.g. `['onchain-proof']` or `['exact', 'onchain-proof']`. */
7193
+ schemes: string[];
7194
+ }>;
7195
+ /** Non-fatal nudges (e.g. a custom token with no built-in symbol to double-check). */
7196
+ warnings: string[];
7197
+ /** Present only when `ok:false` — the human reason the config can't serve a payment. */
7198
+ error?: string;
7199
+ }
7172
7200
  interface PaymentGate {
7173
7201
  /** Build a fresh 402 challenge (new nonce) for a resource URL. */
7174
7202
  challenge(resourceUrl?: string): Promise<{
@@ -7203,6 +7231,13 @@ interface PaymentGate {
7203
7231
  * The SDK never serves it itself (headless by charter). Agents/crawlers keep the JSON 402.
7204
7232
  */
7205
7233
  landingPage(challenge: X402Challenge): string;
7234
+ /**
7235
+ * Read-only config check — resolve the gate's rails WITHOUT signing or sending, and report what
7236
+ * it would charge (or why it can't). Never throws; runs the same lazy resolution as the first
7237
+ * `challenge()`. The merchant's "did I wire this right?" and a scaffolder's post-deploy smoke
7238
+ * step. See {@link GateSelfTest}.
7239
+ */
7240
+ selfTest(): Promise<GateSelfTest>;
7206
7241
  }
7207
7242
  declare function createPaymentGate(options: RequirePaymentOptions): PaymentGate;
7208
7243
  interface ExpressLikeRequest {
@@ -7224,6 +7259,110 @@ type ExpressLikeMiddleware = (req: ExpressLikeRequest, res: ExpressLikeResponse,
7224
7259
  */
7225
7260
  declare function requirePayment(options: RequirePaymentOptions): ExpressLikeMiddleware;
7226
7261
 
7262
+ /**
7263
+ * The advanced gate options a preset forwards verbatim — every {@link RequirePaymentOptions} field
7264
+ * EXCEPT the `chain`/`token`/`amount`/`payTo` quartet (each preset re-declares those with its own
7265
+ * shape) and the multi-chain `accept` array (use {@link createPaymentGate} directly for a multi-rail
7266
+ * gate). So `onPaid`, `exact`, `receipts`, `discovery`, `isUsed`/`markUsed`, … all pass through.
7267
+ */
7268
+ type GateExtras = Omit<RequirePaymentOptions, 'chain' | 'token' | 'amount' | 'payTo' | 'accept'>;
7269
+ /** Options for {@link createPaywall}. */
7270
+ interface PaywallOptions extends GateExtras {
7271
+ /** Which chain to be paid on. EVM (`'base'`|`'bnb'`|…) or a non-EVM family name. */
7272
+ chain: ChainSelector;
7273
+ /** Token to charge in. Defaults to **USDC**. */
7274
+ token?: TokenInput;
7275
+ /** The fixed price, human-readable, e.g. `'0.05'`. */
7276
+ amount: string;
7277
+ /** Your receiving wallet address — no private key (receiving needs only the address). */
7278
+ payTo: AddressId;
7279
+ }
7280
+ /**
7281
+ * Gate one resource behind a fixed price — the API / SaaS / premium-content case. Sugar over
7282
+ * {@link createPaymentGate} with `token` defaulting to USDC; every other gate option is forwarded
7283
+ * unchanged, so the resulting gate (and its 402) is identical to the hand-written equivalent.
7284
+ */
7285
+ declare function createPaywall({ token, ...rest }: PaywallOptions): PaymentGate;
7286
+ /** Options for {@link createTipJar}. */
7287
+ interface TipJarOptions extends GateExtras {
7288
+ /** Which chain to be paid on. */
7289
+ chain: ChainSelector;
7290
+ /** Token to accept. Defaults to **USDC**. */
7291
+ token?: TokenInput;
7292
+ /**
7293
+ * The MINIMUM tip, human-readable, e.g. `'1.00'`. The gate accepts any payment **≥ min** — the
7294
+ * on-chain verify rejects only an under-payment (`amount_too_low`), so a payer can always give
7295
+ * more. There is no upper bound; the minimum is a floor, not a fixed price.
7296
+ */
7297
+ min: string;
7298
+ /** Your receiving wallet address. */
7299
+ payTo: AddressId;
7300
+ }
7301
+ /**
7302
+ * An open "pay what you want (≥ a minimum)" gate — the creator / tip / donation case. Sugar over
7303
+ * {@link createPaymentGate} that sets the challenge `amount` to `min`; because the gate accepts an
7304
+ * over-payment, the minimum is a floor. Everything else (`onPaid`, etc.) forwards unchanged.
7305
+ */
7306
+ declare function createTipJar({ token, min, ...rest }: TipJarOptions): PaymentGate;
7307
+
7308
+ /**
7309
+ * Built-in framework adapters — turn a {@link PaymentGate} into a request handler for any
7310
+ * WHATWG-`fetch` runtime. There are only TWO real shapes among fetch runtimes, so there are two
7311
+ * adapters: a plain handler **function** (Next.js, Netlify, Bun, Deno, Vercel Edge, Hono, Lambda),
7312
+ * and the `{ fetch }` **export object** (Cloudflare / Service Workers). Both run the same contract:
7313
+ * read the proof header, switch on the {@link VerifyPaymentResult} `kind`, write the right status +
7314
+ * headers back out — so a merchant's route is a single call instead of a switch.
7315
+ *
7316
+ * import { createPaywall, toFetchHandler, toWorker } from '@piprail/sdk'
7317
+ * const gate = createPaywall({ chain: 'base', amount: '0.05', payTo: '0xYourWallet' })
7318
+ *
7319
+ * export const GET = toFetchHandler(gate, () => Response.json({ secret: 42 })) // Next / Netlify / Bun / Deno / Hono …
7320
+ * export default toWorker(gate, () => Response.json({ secret: 42 })) // a Cloudflare Worker
7321
+ *
7322
+ * Pure + browser-safe — Web `Request`/`Response`/`Headers` only (no viem, no `node:`). Express keeps
7323
+ * its dedicated {@link requirePayment} middleware; a Node-native framework with its own `req`/`reply`
7324
+ * (Fastify, …) drives `gate.verify()` directly (see the framework-adapters docs). {@link proxyTo} is a
7325
+ * ready-made `serve` that forwards paid requests to an existing backend — gate any API, any language.
7326
+ */
7327
+
7328
+ /**
7329
+ * What to serve once a payment is verified — your protected resource, as a Web `Response`. It
7330
+ * receives the original `request` **plus whatever extra arguments the runtime passed the handler**
7331
+ * (a Cloudflare Worker's `env`/`ctx`, a Next.js route `context` with `params`, …), forwarded
7332
+ * untouched — so a protected handler can reach framework context without a second wrapper.
7333
+ */
7334
+ type Serve = (request: Request, ...rest: unknown[]) => Response | Promise<Response>;
7335
+ /**
7336
+ * The universal adapter: wrap a gate as a `fetch` handler `(request, ...rest) => Response`. Drop the
7337
+ * result into **any** runtime that hands a handler a `Request` and wants a `Response` back — Next.js
7338
+ * route handlers (`export const GET = …`), Netlify Functions, `Bun.serve({ fetch })`,
7339
+ * `Deno.serve(…)`, Vercel Edge, Hono (`(c) => handler(c.req.raw)`), an AWS Lambda Web adapter, Fastly
7340
+ * Compute. Any extra runtime arguments are forwarded to `serve` untouched.
7341
+ *
7342
+ * - **settled payment** → calls `serve`, returns its `Response` with the `payment-response` headers (v2 + v1) added;
7343
+ * - **missing / rejected proof** → a conformant `402` carrying the full challenge (so a standard x402 client can retry);
7344
+ * - **server-side settle failure** ({@link SettlementError}) → `502` — NEVER `402` (the buyer's authorization is still valid + unused).
7345
+ */
7346
+ declare function toFetchHandler(gate: PaymentGate, serve: Serve): (request: Request, ...rest: unknown[]) => Promise<Response>;
7347
+ /**
7348
+ * The `{ fetch }` export object for runtimes that take one — Cloudflare Workers / Service Workers:
7349
+ * `export default toWorker(gate, serve)`. Identical behaviour to {@link toFetchHandler}; the
7350
+ * runtime's `fetch(request, env, ctx)` arguments are forwarded to `serve` (so it can read bindings /
7351
+ * `ctx.waitUntil`). (Other runtimes that take an object — `Bun.serve`, `Deno.serve` — can use either
7352
+ * this or `toFetchHandler` in their `fetch` field.)
7353
+ */
7354
+ declare function toWorker(gate: PaymentGate, serve: Serve): {
7355
+ fetch: (request: Request, ...rest: unknown[]) => Promise<Response>;
7356
+ };
7357
+ /**
7358
+ * A {@link Serve} that forwards the (already-paid) request to an upstream `origin`, untouched — so you
7359
+ * can put a payment gate in FRONT of an existing API in any language, without changing it. Preserves
7360
+ * the method, path, query, body, and headers; strips the x402 proof headers so they don't leak
7361
+ * upstream. The origin NEVER sees an unpaid request — the gate rejects those before `serve` runs.
7362
+ * Compose with the adapters: `toWorker(gate, proxyTo('https://my-api.example.com'))`.
7363
+ */
7364
+ declare function proxyTo(origin: string): Serve;
7365
+
7227
7366
  /**
7228
7367
  * Mode-B settlement: delegate a standard `exact` payment to a THIRD-PARTY x402
7229
7368
  * facilitator the MERCHANT chooses (Coinbase CDP, x402.org, or any). PipRail hosts
@@ -8396,4 +8535,4 @@ interface McpPaymentTool {
8396
8535
  */
8397
8536
  declare function createMcpPaymentTool(options: McpPaymentToolOptions): McpPaymentTool;
8398
8537
 
8399
- export { type A2AArtifact, type A2AExtensionDeclaration, type A2AMessage, type A2AMetadata, type A2APart, type A2APaymentHandler, type A2APaymentHandlerOptions, type A2APaymentStatus, type A2ATask, type A2ATaskRecord, type A2ATaskState, type A2ATaskStore, A2A_ERROR_KEY, A2A_EXTENSIONS_HEADER, A2A_PAYLOAD_KEY, A2A_RECEIPTS_KEY, A2A_REQUIRED_KEY, A2A_STATUS_KEY, A2A_X402_EXTENSION_URI_V01, A2A_X402_EXTENSION_URI_V02, type AcceptOption, AddressId, type AgentTool, type AlgorandToken, type AptosToken, AssetId, BRAND, BUILTIN_DENOMS, type BazaarExtension, type BuildExactParams, CHAINS, Caip2, type ChainFamily, type ChainInput, type ChainName, type ChainPreset, type ChainSelector, type ChallengeTriage, type ChallengeVerdict, type ConfirmInfo, ConfirmationTimeoutError, type CostEstimate, type CountStatus, DENOM_PRECISION, DIRECTORY_INFO, type DeclineReasonCode, type DeliverAttempt, type DeliverReceiptOptions, type DeliverResult, type DenomRemaining, type DirectoryInfo, type DiscoverOptions, type DiscoveredRail, type DiscoveredResource, type DiscoveryDescriptor, type DiscoverySigner, type DiscoverySort, type DiscoverySource, type DomainClaim, type DomainVerification, EIP3009_TYPES, EXACT_NETWORK_SLUGS, type EvmToken, type ExactAccept, type ExactAuthorization, ExactPaymentPayloadAny, type ExactRailOption, type ExpressLikeMiddleware, type ExpressLikeNext, type ExpressLikeRequest, type ExpressLikeResponse, type FacilitatorConfig, type FacilitatorPaymentRequirements, type FacilitatorSupportedKind, type FailedPayment, GENERATOR, InsufficientFundsError, InvalidConfigError, InvalidEnvelopeError, KNOWN_FACILITATORS, type KnownFacilitator, type ListingVisibility, MCP_PAYMENT_META_KEY, MCP_PAYMENT_RESPONSE_META_KEY, type ManifestInput, MaxRetriesExceededError, type McpContentBlock, type McpPaymentMeta, type McpPaymentTool, type McpPaymentToolOptions, type McpToolCallParams, type McpToolResult, MissingDriverError, MultiChainPayer, type MultiChainPayerOptions, type NearToken, NoCompatibleAcceptError, NonReplayableBodyError, type OpenApiDocument, type OpenApiOperation, PERMIT2_ADDRESS, PERMIT2_PROXY_CHAIN_IDS, PERMIT2_UPTO_WITNESS_TYPES, PERMIT2_WITNESS_TYPES, PIPRAIL_AGENT_GUIDE, POWERED_BY, PaidReceipt, type PayBlocker, type PayOption, type PayWarning, type PayingClient, PaymentDeclinedError, type PaymentDriver, type PaymentGate, type PaymentIntent, type PaymentPlan, type PaymentPolicy, type PaymentRail, type PaymentScheme, PaymentTimeoutError, Permit2UptoPaymentPayload, PipRailClient, type PipRailClientOptions, type PipRailCostQuote, PipRailError, type PipRailEvent, type PipRailQuote, PipRailReceipt, type PolicyDecision, type PolicyDenyCode, REGISTER_ATTRIBUTION, type ReceiptInput, type ReceiptOption, type ReceiptVerification, RecipientNotReadyError, type RecipientReason, type RegisterInput, type RegisterOptions, type RegisterOutcome, type RequirePaymentOptions, type ResolveOptions, type ResolvedChain, type ResolvedNetwork, type ResolvedToken, type ResourceDescription, type SearchOpenIndexesOptions, type SelfDescribeEndpoint, type SelfDescribeRail, type SelfDescription, type SessionBudget, SettleOutcome, type SettleViaFacilitatorInput, SettlementError, SignedReceipt, type SolanaToken, SpendLedger, SpendRecord, type SpendRemaining, SpendStore, SpendSummary, type StellarToken, type SuiToken, type TokenInfo, type TokenInput, type TonToken, type ToolAnnotations, type TronToken, UPTO_PROXY_CHAIN_IDS, UnknownTokenError, UnsupportedNetworkError, UnsupportedSchemeError, type UptoRailOption, VERIFY_CODE_TO_A2A_ERROR, VerifyErrorCode, type VerifyPaymentResult, VerifyResult, type WalletBalance, type WalletHandle, type WalletInput, WalletRequiredError, type WellKnownX402, type WellKnownX402Item, type WellKnownX402Manifest, WrongChainError, WrongFamilyError, X402AcceptEntry, X402AnyAccept, X402Challenge, type X402DnsRecord, X402ExactAcceptEntry, type X402InvalidBody, X402Receipt, X402UptoAcceptEntry, X402_EXACT_PERMIT2_PROXY, X402_UPTO_PERMIT2_PROXY, type XrplToken, agentGuide, appendAttribution, appendKeywords, buildBazaarExtension, buildEndpointInfo, buildExactAuthorization, buildMcpPaymentMeta, buildOpenApi, buildSelfDescription, buildWellKnownX402, buildWellKnownX402Manifest, buildX402DnsTxt, chainIdForExactNetwork, claim402IndexDomain, classifyChallenge, createA2APaymentHandler, createMcpPaymentTool, createPaymentGate, decorateOutcome, deliverReceipt, denomOf, describeChallenge, discoveryHeaders, eip3009Abi, encodeXPaymentHeader, evaluatePolicy, explainDecline, facilitatorCoverage, fetchAcross, firstKeylessFacilitator, formatSpendReport, fromA2APaymentPayload, fromA2APaymentRequired, fromMcpPayment, fromMcpPaymentRequired, fromMcpPaymentResponse, getDirectoryInfo, isMcpPaymentRequired, isPermit2ProxyChain, isUptoProxyChain, knownFacilitatorsFor, normalizeNetwork, parseExactRequirements, parseFacilitatorSupported, paymentTools, planAcross, rankResources, readExactDomain, register402Index, registerDriver, registerX402Scan, renderLandingPage, requirePayment, resolveChain, scoreResource, searchOpenIndexes, settleViaFacilitator, summarizePlan, toA2AErrorCode, toA2APaymentFailed, toA2APaymentReceipts, toA2APaymentRequired, toInsufficientFundsError, toInvalidBody, toMcpPaymentRequired, toMcpPaymentResponse, verify402IndexDomain };
8538
+ export { type A2AArtifact, type A2AExtensionDeclaration, type A2AMessage, type A2AMetadata, type A2APart, type A2APaymentHandler, type A2APaymentHandlerOptions, type A2APaymentStatus, type A2ATask, type A2ATaskRecord, type A2ATaskState, type A2ATaskStore, A2A_ERROR_KEY, A2A_EXTENSIONS_HEADER, A2A_PAYLOAD_KEY, A2A_RECEIPTS_KEY, A2A_REQUIRED_KEY, A2A_STATUS_KEY, A2A_X402_EXTENSION_URI_V01, A2A_X402_EXTENSION_URI_V02, type AcceptOption, AddressId, type AgentTool, type AlgorandToken, type AptosToken, AssetId, BRAND, BUILTIN_DENOMS, type BazaarExtension, type BuildExactParams, CHAINS, Caip2, type ChainFamily, type ChainInput, type ChainName, type ChainPreset, type ChainSelector, type ChallengeTriage, type ChallengeVerdict, type ConfirmInfo, ConfirmationTimeoutError, type CostEstimate, type CountStatus, DENOM_PRECISION, DIRECTORY_INFO, type DeclineReasonCode, type DeliverAttempt, type DeliverReceiptOptions, type DeliverResult, type DenomRemaining, type DirectoryInfo, type DiscoverOptions, type DiscoveredRail, type DiscoveredResource, type DiscoveryDescriptor, type DiscoverySigner, type DiscoverySort, type DiscoverySource, type DomainClaim, type DomainVerification, EIP3009_TYPES, EXACT_NETWORK_SLUGS, type EvmToken, type ExactAccept, type ExactAuthorization, ExactPaymentPayloadAny, type ExactRailOption, type ExpressLikeMiddleware, type ExpressLikeNext, type ExpressLikeRequest, type ExpressLikeResponse, type FacilitatorConfig, type FacilitatorPaymentRequirements, type FacilitatorSupportedKind, type FailedPayment, GENERATOR, type GateSelfTest, InsufficientFundsError, InvalidConfigError, InvalidEnvelopeError, KNOWN_FACILITATORS, type KnownFacilitator, type ListingVisibility, MCP_PAYMENT_META_KEY, MCP_PAYMENT_RESPONSE_META_KEY, type ManifestInput, MaxRetriesExceededError, type McpContentBlock, type McpPaymentMeta, type McpPaymentTool, type McpPaymentToolOptions, type McpToolCallParams, type McpToolResult, MissingDriverError, MultiChainPayer, type MultiChainPayerOptions, type NearToken, NoCompatibleAcceptError, NonReplayableBodyError, type OpenApiDocument, type OpenApiOperation, PERMIT2_ADDRESS, PERMIT2_PROXY_CHAIN_IDS, PERMIT2_UPTO_WITNESS_TYPES, PERMIT2_WITNESS_TYPES, PIPRAIL_AGENT_GUIDE, POWERED_BY, PaidReceipt, type PayBlocker, type PayOption, type PayWarning, type PayingClient, PaymentDeclinedError, type PaymentDriver, type PaymentGate, type PaymentIntent, type PaymentPlan, type PaymentPolicy, type PaymentRail, type PaymentScheme, PaymentTimeoutError, type PaywallOptions, Permit2UptoPaymentPayload, PipRailClient, type PipRailClientOptions, type PipRailCostQuote, PipRailError, type PipRailEvent, type PipRailQuote, PipRailReceipt, type PolicyDecision, type PolicyDenyCode, REGISTER_ATTRIBUTION, type ReceiptInput, type ReceiptOption, type ReceiptVerification, RecipientNotReadyError, type RecipientReason, type RegisterInput, type RegisterOptions, type RegisterOutcome, type RequirePaymentOptions, type ResolveOptions, type ResolvedChain, type ResolvedNetwork, type ResolvedToken, type ResourceDescription, type SearchOpenIndexesOptions, type SelfDescribeEndpoint, type SelfDescribeRail, type SelfDescription, type Serve, type SessionBudget, SettleOutcome, type SettleViaFacilitatorInput, SettlementError, SignedReceipt, type SolanaToken, SpendLedger, SpendRecord, type SpendRemaining, SpendStore, SpendSummary, type StellarToken, type SuiToken, type TipJarOptions, type TokenInfo, type TokenInput, type TonToken, type ToolAnnotations, type TronToken, UPTO_PROXY_CHAIN_IDS, UnknownTokenError, UnsupportedNetworkError, UnsupportedSchemeError, type UptoRailOption, VERIFY_CODE_TO_A2A_ERROR, VerifyErrorCode, type VerifyPaymentResult, VerifyResult, type WalletBalance, type WalletHandle, type WalletInput, WalletRequiredError, type WellKnownX402, type WellKnownX402Item, type WellKnownX402Manifest, WrongChainError, WrongFamilyError, X402AcceptEntry, X402AnyAccept, X402Challenge, type X402DnsRecord, X402ExactAcceptEntry, type X402InvalidBody, X402Receipt, X402UptoAcceptEntry, X402_EXACT_PERMIT2_PROXY, X402_UPTO_PERMIT2_PROXY, type XrplToken, agentGuide, appendAttribution, appendKeywords, buildBazaarExtension, buildEndpointInfo, buildExactAuthorization, buildMcpPaymentMeta, buildOpenApi, buildSelfDescription, buildWellKnownX402, buildWellKnownX402Manifest, buildX402DnsTxt, chainIdForExactNetwork, claim402IndexDomain, classifyChallenge, createA2APaymentHandler, createMcpPaymentTool, createPaymentGate, createPaywall, createTipJar, decorateOutcome, deliverReceipt, denomOf, describeChallenge, discoveryHeaders, eip3009Abi, encodeXPaymentHeader, evaluatePolicy, explainDecline, facilitatorCoverage, fetchAcross, firstKeylessFacilitator, formatSpendReport, fromA2APaymentPayload, fromA2APaymentRequired, fromMcpPayment, fromMcpPaymentRequired, fromMcpPaymentResponse, getDirectoryInfo, isMcpPaymentRequired, isPermit2ProxyChain, isUptoProxyChain, knownFacilitatorsFor, normalizeNetwork, parseExactRequirements, parseFacilitatorSupported, paymentTools, planAcross, proxyTo, rankResources, readExactDomain, register402Index, registerDriver, registerX402Scan, renderLandingPage, requirePayment, resolveChain, scoreResource, searchOpenIndexes, settleViaFacilitator, summarizePlan, toA2AErrorCode, toA2APaymentFailed, toA2APaymentReceipts, toA2APaymentRequired, toFetchHandler, toInsufficientFundsError, toInvalidBody, toMcpPaymentRequired, toMcpPaymentResponse, toWorker, verify402IndexDomain };
package/dist/index.d.ts CHANGED
@@ -7169,6 +7169,34 @@ declare function toInvalidBody(result: {
7169
7169
  error: string;
7170
7170
  detail: string;
7171
7171
  }): X402InvalidBody;
7172
+ /**
7173
+ * The result of {@link PaymentGate.selfTest} — a read-only config check. NEVER throws, and never
7174
+ * touches the network beyond the same lazy driver/token resolution the first `challenge()` does
7175
+ * (no signing, no sending). `ok:true` with the resolved `rails` when the config is sound; `ok:false`
7176
+ * with a human `error` when something's wrong (no payTo, a malformed address for the family, an
7177
+ * unknown token, an unresolvable chain). Powers a scaffolder's "✅ your endpoint is configured"
7178
+ * step and a merchant's `npm run verify`.
7179
+ */
7180
+ interface GateSelfTest {
7181
+ ok: boolean;
7182
+ /** One entry per resolved payment option (empty when `ok:false`). */
7183
+ rails: Array<{
7184
+ /** CAIP-2 network, e.g. `eip155:8453`. */
7185
+ network: string;
7186
+ asset: string;
7187
+ symbol?: string;
7188
+ decimals: number;
7189
+ /** Human amount the gate charges (for a tip jar, the minimum/floor). */
7190
+ amount: string;
7191
+ payTo: AddressId;
7192
+ /** The schemes this rail offers, e.g. `['onchain-proof']` or `['exact', 'onchain-proof']`. */
7193
+ schemes: string[];
7194
+ }>;
7195
+ /** Non-fatal nudges (e.g. a custom token with no built-in symbol to double-check). */
7196
+ warnings: string[];
7197
+ /** Present only when `ok:false` — the human reason the config can't serve a payment. */
7198
+ error?: string;
7199
+ }
7172
7200
  interface PaymentGate {
7173
7201
  /** Build a fresh 402 challenge (new nonce) for a resource URL. */
7174
7202
  challenge(resourceUrl?: string): Promise<{
@@ -7203,6 +7231,13 @@ interface PaymentGate {
7203
7231
  * The SDK never serves it itself (headless by charter). Agents/crawlers keep the JSON 402.
7204
7232
  */
7205
7233
  landingPage(challenge: X402Challenge): string;
7234
+ /**
7235
+ * Read-only config check — resolve the gate's rails WITHOUT signing or sending, and report what
7236
+ * it would charge (or why it can't). Never throws; runs the same lazy resolution as the first
7237
+ * `challenge()`. The merchant's "did I wire this right?" and a scaffolder's post-deploy smoke
7238
+ * step. See {@link GateSelfTest}.
7239
+ */
7240
+ selfTest(): Promise<GateSelfTest>;
7206
7241
  }
7207
7242
  declare function createPaymentGate(options: RequirePaymentOptions): PaymentGate;
7208
7243
  interface ExpressLikeRequest {
@@ -7224,6 +7259,110 @@ type ExpressLikeMiddleware = (req: ExpressLikeRequest, res: ExpressLikeResponse,
7224
7259
  */
7225
7260
  declare function requirePayment(options: RequirePaymentOptions): ExpressLikeMiddleware;
7226
7261
 
7262
+ /**
7263
+ * The advanced gate options a preset forwards verbatim — every {@link RequirePaymentOptions} field
7264
+ * EXCEPT the `chain`/`token`/`amount`/`payTo` quartet (each preset re-declares those with its own
7265
+ * shape) and the multi-chain `accept` array (use {@link createPaymentGate} directly for a multi-rail
7266
+ * gate). So `onPaid`, `exact`, `receipts`, `discovery`, `isUsed`/`markUsed`, … all pass through.
7267
+ */
7268
+ type GateExtras = Omit<RequirePaymentOptions, 'chain' | 'token' | 'amount' | 'payTo' | 'accept'>;
7269
+ /** Options for {@link createPaywall}. */
7270
+ interface PaywallOptions extends GateExtras {
7271
+ /** Which chain to be paid on. EVM (`'base'`|`'bnb'`|…) or a non-EVM family name. */
7272
+ chain: ChainSelector;
7273
+ /** Token to charge in. Defaults to **USDC**. */
7274
+ token?: TokenInput;
7275
+ /** The fixed price, human-readable, e.g. `'0.05'`. */
7276
+ amount: string;
7277
+ /** Your receiving wallet address — no private key (receiving needs only the address). */
7278
+ payTo: AddressId;
7279
+ }
7280
+ /**
7281
+ * Gate one resource behind a fixed price — the API / SaaS / premium-content case. Sugar over
7282
+ * {@link createPaymentGate} with `token` defaulting to USDC; every other gate option is forwarded
7283
+ * unchanged, so the resulting gate (and its 402) is identical to the hand-written equivalent.
7284
+ */
7285
+ declare function createPaywall({ token, ...rest }: PaywallOptions): PaymentGate;
7286
+ /** Options for {@link createTipJar}. */
7287
+ interface TipJarOptions extends GateExtras {
7288
+ /** Which chain to be paid on. */
7289
+ chain: ChainSelector;
7290
+ /** Token to accept. Defaults to **USDC**. */
7291
+ token?: TokenInput;
7292
+ /**
7293
+ * The MINIMUM tip, human-readable, e.g. `'1.00'`. The gate accepts any payment **≥ min** — the
7294
+ * on-chain verify rejects only an under-payment (`amount_too_low`), so a payer can always give
7295
+ * more. There is no upper bound; the minimum is a floor, not a fixed price.
7296
+ */
7297
+ min: string;
7298
+ /** Your receiving wallet address. */
7299
+ payTo: AddressId;
7300
+ }
7301
+ /**
7302
+ * An open "pay what you want (≥ a minimum)" gate — the creator / tip / donation case. Sugar over
7303
+ * {@link createPaymentGate} that sets the challenge `amount` to `min`; because the gate accepts an
7304
+ * over-payment, the minimum is a floor. Everything else (`onPaid`, etc.) forwards unchanged.
7305
+ */
7306
+ declare function createTipJar({ token, min, ...rest }: TipJarOptions): PaymentGate;
7307
+
7308
+ /**
7309
+ * Built-in framework adapters — turn a {@link PaymentGate} into a request handler for any
7310
+ * WHATWG-`fetch` runtime. There are only TWO real shapes among fetch runtimes, so there are two
7311
+ * adapters: a plain handler **function** (Next.js, Netlify, Bun, Deno, Vercel Edge, Hono, Lambda),
7312
+ * and the `{ fetch }` **export object** (Cloudflare / Service Workers). Both run the same contract:
7313
+ * read the proof header, switch on the {@link VerifyPaymentResult} `kind`, write the right status +
7314
+ * headers back out — so a merchant's route is a single call instead of a switch.
7315
+ *
7316
+ * import { createPaywall, toFetchHandler, toWorker } from '@piprail/sdk'
7317
+ * const gate = createPaywall({ chain: 'base', amount: '0.05', payTo: '0xYourWallet' })
7318
+ *
7319
+ * export const GET = toFetchHandler(gate, () => Response.json({ secret: 42 })) // Next / Netlify / Bun / Deno / Hono …
7320
+ * export default toWorker(gate, () => Response.json({ secret: 42 })) // a Cloudflare Worker
7321
+ *
7322
+ * Pure + browser-safe — Web `Request`/`Response`/`Headers` only (no viem, no `node:`). Express keeps
7323
+ * its dedicated {@link requirePayment} middleware; a Node-native framework with its own `req`/`reply`
7324
+ * (Fastify, …) drives `gate.verify()` directly (see the framework-adapters docs). {@link proxyTo} is a
7325
+ * ready-made `serve` that forwards paid requests to an existing backend — gate any API, any language.
7326
+ */
7327
+
7328
+ /**
7329
+ * What to serve once a payment is verified — your protected resource, as a Web `Response`. It
7330
+ * receives the original `request` **plus whatever extra arguments the runtime passed the handler**
7331
+ * (a Cloudflare Worker's `env`/`ctx`, a Next.js route `context` with `params`, …), forwarded
7332
+ * untouched — so a protected handler can reach framework context without a second wrapper.
7333
+ */
7334
+ type Serve = (request: Request, ...rest: unknown[]) => Response | Promise<Response>;
7335
+ /**
7336
+ * The universal adapter: wrap a gate as a `fetch` handler `(request, ...rest) => Response`. Drop the
7337
+ * result into **any** runtime that hands a handler a `Request` and wants a `Response` back — Next.js
7338
+ * route handlers (`export const GET = …`), Netlify Functions, `Bun.serve({ fetch })`,
7339
+ * `Deno.serve(…)`, Vercel Edge, Hono (`(c) => handler(c.req.raw)`), an AWS Lambda Web adapter, Fastly
7340
+ * Compute. Any extra runtime arguments are forwarded to `serve` untouched.
7341
+ *
7342
+ * - **settled payment** → calls `serve`, returns its `Response` with the `payment-response` headers (v2 + v1) added;
7343
+ * - **missing / rejected proof** → a conformant `402` carrying the full challenge (so a standard x402 client can retry);
7344
+ * - **server-side settle failure** ({@link SettlementError}) → `502` — NEVER `402` (the buyer's authorization is still valid + unused).
7345
+ */
7346
+ declare function toFetchHandler(gate: PaymentGate, serve: Serve): (request: Request, ...rest: unknown[]) => Promise<Response>;
7347
+ /**
7348
+ * The `{ fetch }` export object for runtimes that take one — Cloudflare Workers / Service Workers:
7349
+ * `export default toWorker(gate, serve)`. Identical behaviour to {@link toFetchHandler}; the
7350
+ * runtime's `fetch(request, env, ctx)` arguments are forwarded to `serve` (so it can read bindings /
7351
+ * `ctx.waitUntil`). (Other runtimes that take an object — `Bun.serve`, `Deno.serve` — can use either
7352
+ * this or `toFetchHandler` in their `fetch` field.)
7353
+ */
7354
+ declare function toWorker(gate: PaymentGate, serve: Serve): {
7355
+ fetch: (request: Request, ...rest: unknown[]) => Promise<Response>;
7356
+ };
7357
+ /**
7358
+ * A {@link Serve} that forwards the (already-paid) request to an upstream `origin`, untouched — so you
7359
+ * can put a payment gate in FRONT of an existing API in any language, without changing it. Preserves
7360
+ * the method, path, query, body, and headers; strips the x402 proof headers so they don't leak
7361
+ * upstream. The origin NEVER sees an unpaid request — the gate rejects those before `serve` runs.
7362
+ * Compose with the adapters: `toWorker(gate, proxyTo('https://my-api.example.com'))`.
7363
+ */
7364
+ declare function proxyTo(origin: string): Serve;
7365
+
7227
7366
  /**
7228
7367
  * Mode-B settlement: delegate a standard `exact` payment to a THIRD-PARTY x402
7229
7368
  * facilitator the MERCHANT chooses (Coinbase CDP, x402.org, or any). PipRail hosts
@@ -8396,4 +8535,4 @@ interface McpPaymentTool {
8396
8535
  */
8397
8536
  declare function createMcpPaymentTool(options: McpPaymentToolOptions): McpPaymentTool;
8398
8537
 
8399
- export { type A2AArtifact, type A2AExtensionDeclaration, type A2AMessage, type A2AMetadata, type A2APart, type A2APaymentHandler, type A2APaymentHandlerOptions, type A2APaymentStatus, type A2ATask, type A2ATaskRecord, type A2ATaskState, type A2ATaskStore, A2A_ERROR_KEY, A2A_EXTENSIONS_HEADER, A2A_PAYLOAD_KEY, A2A_RECEIPTS_KEY, A2A_REQUIRED_KEY, A2A_STATUS_KEY, A2A_X402_EXTENSION_URI_V01, A2A_X402_EXTENSION_URI_V02, type AcceptOption, AddressId, type AgentTool, type AlgorandToken, type AptosToken, AssetId, BRAND, BUILTIN_DENOMS, type BazaarExtension, type BuildExactParams, CHAINS, Caip2, type ChainFamily, type ChainInput, type ChainName, type ChainPreset, type ChainSelector, type ChallengeTriage, type ChallengeVerdict, type ConfirmInfo, ConfirmationTimeoutError, type CostEstimate, type CountStatus, DENOM_PRECISION, DIRECTORY_INFO, type DeclineReasonCode, type DeliverAttempt, type DeliverReceiptOptions, type DeliverResult, type DenomRemaining, type DirectoryInfo, type DiscoverOptions, type DiscoveredRail, type DiscoveredResource, type DiscoveryDescriptor, type DiscoverySigner, type DiscoverySort, type DiscoverySource, type DomainClaim, type DomainVerification, EIP3009_TYPES, EXACT_NETWORK_SLUGS, type EvmToken, type ExactAccept, type ExactAuthorization, ExactPaymentPayloadAny, type ExactRailOption, type ExpressLikeMiddleware, type ExpressLikeNext, type ExpressLikeRequest, type ExpressLikeResponse, type FacilitatorConfig, type FacilitatorPaymentRequirements, type FacilitatorSupportedKind, type FailedPayment, GENERATOR, InsufficientFundsError, InvalidConfigError, InvalidEnvelopeError, KNOWN_FACILITATORS, type KnownFacilitator, type ListingVisibility, MCP_PAYMENT_META_KEY, MCP_PAYMENT_RESPONSE_META_KEY, type ManifestInput, MaxRetriesExceededError, type McpContentBlock, type McpPaymentMeta, type McpPaymentTool, type McpPaymentToolOptions, type McpToolCallParams, type McpToolResult, MissingDriverError, MultiChainPayer, type MultiChainPayerOptions, type NearToken, NoCompatibleAcceptError, NonReplayableBodyError, type OpenApiDocument, type OpenApiOperation, PERMIT2_ADDRESS, PERMIT2_PROXY_CHAIN_IDS, PERMIT2_UPTO_WITNESS_TYPES, PERMIT2_WITNESS_TYPES, PIPRAIL_AGENT_GUIDE, POWERED_BY, PaidReceipt, type PayBlocker, type PayOption, type PayWarning, type PayingClient, PaymentDeclinedError, type PaymentDriver, type PaymentGate, type PaymentIntent, type PaymentPlan, type PaymentPolicy, type PaymentRail, type PaymentScheme, PaymentTimeoutError, Permit2UptoPaymentPayload, PipRailClient, type PipRailClientOptions, type PipRailCostQuote, PipRailError, type PipRailEvent, type PipRailQuote, PipRailReceipt, type PolicyDecision, type PolicyDenyCode, REGISTER_ATTRIBUTION, type ReceiptInput, type ReceiptOption, type ReceiptVerification, RecipientNotReadyError, type RecipientReason, type RegisterInput, type RegisterOptions, type RegisterOutcome, type RequirePaymentOptions, type ResolveOptions, type ResolvedChain, type ResolvedNetwork, type ResolvedToken, type ResourceDescription, type SearchOpenIndexesOptions, type SelfDescribeEndpoint, type SelfDescribeRail, type SelfDescription, type SessionBudget, SettleOutcome, type SettleViaFacilitatorInput, SettlementError, SignedReceipt, type SolanaToken, SpendLedger, SpendRecord, type SpendRemaining, SpendStore, SpendSummary, type StellarToken, type SuiToken, type TokenInfo, type TokenInput, type TonToken, type ToolAnnotations, type TronToken, UPTO_PROXY_CHAIN_IDS, UnknownTokenError, UnsupportedNetworkError, UnsupportedSchemeError, type UptoRailOption, VERIFY_CODE_TO_A2A_ERROR, VerifyErrorCode, type VerifyPaymentResult, VerifyResult, type WalletBalance, type WalletHandle, type WalletInput, WalletRequiredError, type WellKnownX402, type WellKnownX402Item, type WellKnownX402Manifest, WrongChainError, WrongFamilyError, X402AcceptEntry, X402AnyAccept, X402Challenge, type X402DnsRecord, X402ExactAcceptEntry, type X402InvalidBody, X402Receipt, X402UptoAcceptEntry, X402_EXACT_PERMIT2_PROXY, X402_UPTO_PERMIT2_PROXY, type XrplToken, agentGuide, appendAttribution, appendKeywords, buildBazaarExtension, buildEndpointInfo, buildExactAuthorization, buildMcpPaymentMeta, buildOpenApi, buildSelfDescription, buildWellKnownX402, buildWellKnownX402Manifest, buildX402DnsTxt, chainIdForExactNetwork, claim402IndexDomain, classifyChallenge, createA2APaymentHandler, createMcpPaymentTool, createPaymentGate, decorateOutcome, deliverReceipt, denomOf, describeChallenge, discoveryHeaders, eip3009Abi, encodeXPaymentHeader, evaluatePolicy, explainDecline, facilitatorCoverage, fetchAcross, firstKeylessFacilitator, formatSpendReport, fromA2APaymentPayload, fromA2APaymentRequired, fromMcpPayment, fromMcpPaymentRequired, fromMcpPaymentResponse, getDirectoryInfo, isMcpPaymentRequired, isPermit2ProxyChain, isUptoProxyChain, knownFacilitatorsFor, normalizeNetwork, parseExactRequirements, parseFacilitatorSupported, paymentTools, planAcross, rankResources, readExactDomain, register402Index, registerDriver, registerX402Scan, renderLandingPage, requirePayment, resolveChain, scoreResource, searchOpenIndexes, settleViaFacilitator, summarizePlan, toA2AErrorCode, toA2APaymentFailed, toA2APaymentReceipts, toA2APaymentRequired, toInsufficientFundsError, toInvalidBody, toMcpPaymentRequired, toMcpPaymentResponse, verify402IndexDomain };
8538
+ export { type A2AArtifact, type A2AExtensionDeclaration, type A2AMessage, type A2AMetadata, type A2APart, type A2APaymentHandler, type A2APaymentHandlerOptions, type A2APaymentStatus, type A2ATask, type A2ATaskRecord, type A2ATaskState, type A2ATaskStore, A2A_ERROR_KEY, A2A_EXTENSIONS_HEADER, A2A_PAYLOAD_KEY, A2A_RECEIPTS_KEY, A2A_REQUIRED_KEY, A2A_STATUS_KEY, A2A_X402_EXTENSION_URI_V01, A2A_X402_EXTENSION_URI_V02, type AcceptOption, AddressId, type AgentTool, type AlgorandToken, type AptosToken, AssetId, BRAND, BUILTIN_DENOMS, type BazaarExtension, type BuildExactParams, CHAINS, Caip2, type ChainFamily, type ChainInput, type ChainName, type ChainPreset, type ChainSelector, type ChallengeTriage, type ChallengeVerdict, type ConfirmInfo, ConfirmationTimeoutError, type CostEstimate, type CountStatus, DENOM_PRECISION, DIRECTORY_INFO, type DeclineReasonCode, type DeliverAttempt, type DeliverReceiptOptions, type DeliverResult, type DenomRemaining, type DirectoryInfo, type DiscoverOptions, type DiscoveredRail, type DiscoveredResource, type DiscoveryDescriptor, type DiscoverySigner, type DiscoverySort, type DiscoverySource, type DomainClaim, type DomainVerification, EIP3009_TYPES, EXACT_NETWORK_SLUGS, type EvmToken, type ExactAccept, type ExactAuthorization, ExactPaymentPayloadAny, type ExactRailOption, type ExpressLikeMiddleware, type ExpressLikeNext, type ExpressLikeRequest, type ExpressLikeResponse, type FacilitatorConfig, type FacilitatorPaymentRequirements, type FacilitatorSupportedKind, type FailedPayment, GENERATOR, type GateSelfTest, InsufficientFundsError, InvalidConfigError, InvalidEnvelopeError, KNOWN_FACILITATORS, type KnownFacilitator, type ListingVisibility, MCP_PAYMENT_META_KEY, MCP_PAYMENT_RESPONSE_META_KEY, type ManifestInput, MaxRetriesExceededError, type McpContentBlock, type McpPaymentMeta, type McpPaymentTool, type McpPaymentToolOptions, type McpToolCallParams, type McpToolResult, MissingDriverError, MultiChainPayer, type MultiChainPayerOptions, type NearToken, NoCompatibleAcceptError, NonReplayableBodyError, type OpenApiDocument, type OpenApiOperation, PERMIT2_ADDRESS, PERMIT2_PROXY_CHAIN_IDS, PERMIT2_UPTO_WITNESS_TYPES, PERMIT2_WITNESS_TYPES, PIPRAIL_AGENT_GUIDE, POWERED_BY, PaidReceipt, type PayBlocker, type PayOption, type PayWarning, type PayingClient, PaymentDeclinedError, type PaymentDriver, type PaymentGate, type PaymentIntent, type PaymentPlan, type PaymentPolicy, type PaymentRail, type PaymentScheme, PaymentTimeoutError, type PaywallOptions, Permit2UptoPaymentPayload, PipRailClient, type PipRailClientOptions, type PipRailCostQuote, PipRailError, type PipRailEvent, type PipRailQuote, PipRailReceipt, type PolicyDecision, type PolicyDenyCode, REGISTER_ATTRIBUTION, type ReceiptInput, type ReceiptOption, type ReceiptVerification, RecipientNotReadyError, type RecipientReason, type RegisterInput, type RegisterOptions, type RegisterOutcome, type RequirePaymentOptions, type ResolveOptions, type ResolvedChain, type ResolvedNetwork, type ResolvedToken, type ResourceDescription, type SearchOpenIndexesOptions, type SelfDescribeEndpoint, type SelfDescribeRail, type SelfDescription, type Serve, type SessionBudget, SettleOutcome, type SettleViaFacilitatorInput, SettlementError, SignedReceipt, type SolanaToken, SpendLedger, SpendRecord, type SpendRemaining, SpendStore, SpendSummary, type StellarToken, type SuiToken, type TipJarOptions, type TokenInfo, type TokenInput, type TonToken, type ToolAnnotations, type TronToken, UPTO_PROXY_CHAIN_IDS, UnknownTokenError, UnsupportedNetworkError, UnsupportedSchemeError, type UptoRailOption, VERIFY_CODE_TO_A2A_ERROR, VerifyErrorCode, type VerifyPaymentResult, VerifyResult, type WalletBalance, type WalletHandle, type WalletInput, WalletRequiredError, type WellKnownX402, type WellKnownX402Item, type WellKnownX402Manifest, WrongChainError, WrongFamilyError, X402AcceptEntry, X402AnyAccept, X402Challenge, type X402DnsRecord, X402ExactAcceptEntry, type X402InvalidBody, X402Receipt, X402UptoAcceptEntry, X402_EXACT_PERMIT2_PROXY, X402_UPTO_PERMIT2_PROXY, type XrplToken, agentGuide, appendAttribution, appendKeywords, buildBazaarExtension, buildEndpointInfo, buildExactAuthorization, buildMcpPaymentMeta, buildOpenApi, buildSelfDescription, buildWellKnownX402, buildWellKnownX402Manifest, buildX402DnsTxt, chainIdForExactNetwork, claim402IndexDomain, classifyChallenge, createA2APaymentHandler, createMcpPaymentTool, createPaymentGate, createPaywall, createTipJar, decorateOutcome, deliverReceipt, denomOf, describeChallenge, discoveryHeaders, eip3009Abi, encodeXPaymentHeader, evaluatePolicy, explainDecline, facilitatorCoverage, fetchAcross, firstKeylessFacilitator, formatSpendReport, fromA2APaymentPayload, fromA2APaymentRequired, fromMcpPayment, fromMcpPaymentRequired, fromMcpPaymentResponse, getDirectoryInfo, isMcpPaymentRequired, isPermit2ProxyChain, isUptoProxyChain, knownFacilitatorsFor, normalizeNetwork, parseExactRequirements, parseFacilitatorSupported, paymentTools, planAcross, proxyTo, rankResources, readExactDomain, register402Index, registerDriver, registerX402Scan, renderLandingPage, requirePayment, resolveChain, scoreResource, searchOpenIndexes, settleViaFacilitator, summarizePlan, toA2AErrorCode, toA2APaymentFailed, toA2APaymentReceipts, toA2APaymentRequired, toFetchHandler, toInsufficientFundsError, toInvalidBody, toMcpPaymentRequired, toMcpPaymentResponse, toWorker, verify402IndexDomain };
package/dist/index.js CHANGED
@@ -7499,7 +7499,36 @@ function createPaymentGate(options) {
7499
7499
  await settleTx(idKey, result.kind === "paid");
7500
7500
  return result.kind === "paid" ? echoPaymentIdentifier(result, id) : result;
7501
7501
  }
7502
- return { challenge, verify, verifyObject, describe, landingPage };
7502
+ async function selfTest() {
7503
+ try {
7504
+ const specs = await ready();
7505
+ const warnings = [];
7506
+ const rails = specs.map((s) => {
7507
+ if (!s.symbol) {
7508
+ warnings.push(
7509
+ `${s.asset} on ${s.net.network}: custom token (no built-in symbol) \u2014 double-check the address + decimals.`
7510
+ );
7511
+ }
7512
+ return {
7513
+ network: s.net.network,
7514
+ asset: s.asset,
7515
+ ...s.symbol ? { symbol: s.symbol } : {},
7516
+ decimals: s.decimals,
7517
+ amount: s.amountFormatted,
7518
+ payTo: s.payTo,
7519
+ schemes: [
7520
+ ...s.exact ? ["exact"] : [],
7521
+ ...s.upto ? ["upto"] : [],
7522
+ "onchain-proof"
7523
+ ]
7524
+ };
7525
+ });
7526
+ return { ok: true, rails, warnings };
7527
+ } catch (err) {
7528
+ return { ok: false, rails: [], warnings: [], error: err instanceof Error ? err.message : String(err) };
7529
+ }
7530
+ }
7531
+ return { challenge, verify, verifyObject, describe, landingPage, selfTest };
7503
7532
  }
7504
7533
  function requirePayment(options) {
7505
7534
  if (options.upto) {
@@ -7551,6 +7580,87 @@ function normaliseHeader(value) {
7551
7580
  return value;
7552
7581
  }
7553
7582
 
7583
+ // src/merchant.ts
7584
+ function createPaywall({ token = "USDC", ...rest }) {
7585
+ return createPaymentGate({ token, ...rest });
7586
+ }
7587
+ function createTipJar({ token = "USDC", min, ...rest }) {
7588
+ return createPaymentGate({ token, amount: min, ...rest });
7589
+ }
7590
+
7591
+ // src/adapters.ts
7592
+ function jsonResponse(body, status, headers) {
7593
+ return new Response(JSON.stringify(body), {
7594
+ status,
7595
+ headers: { "content-type": "application/json; charset=utf-8", ...headers ?? {} }
7596
+ });
7597
+ }
7598
+ function withSettlementHeaders(res, receiptHeader) {
7599
+ const headers = new Headers();
7600
+ res.headers.forEach((value, key) => {
7601
+ if (key.toLowerCase() !== "set-cookie") headers.append(key, value);
7602
+ });
7603
+ const src = res.headers;
7604
+ const cookies = typeof src.getSetCookie === "function" ? src.getSetCookie() : (() => {
7605
+ const combined = res.headers.get("set-cookie");
7606
+ return combined ? [combined] : [];
7607
+ })();
7608
+ for (const cookie of cookies) headers.append("set-cookie", cookie);
7609
+ headers.set(HEADER_RESPONSE, receiptHeader);
7610
+ headers.set(HEADER_RESPONSE_V1, receiptHeader);
7611
+ return new Response(res.body, { status: res.status, statusText: res.statusText, headers });
7612
+ }
7613
+ function toFetchHandler(gate, serve) {
7614
+ return async (request, ...rest) => {
7615
+ let result;
7616
+ try {
7617
+ const sig = request.headers.get(HEADER_SIGNATURE) ?? request.headers.get(HEADER_SIGNATURE_V1) ?? void 0;
7618
+ result = await gate.verify(sig);
7619
+ } catch (err) {
7620
+ if (err instanceof SettlementError) {
7621
+ return jsonResponse(
7622
+ {
7623
+ x402Version: 2,
7624
+ error: "settlement_failed",
7625
+ detail: err.message,
7626
+ fallback: "The gasless `exact` settlement failed. This resource also accepts `onchain-proof` \u2014 retry by paying that rail yourself (you broadcast the transfer and pay the gas)."
7627
+ },
7628
+ 502
7629
+ );
7630
+ }
7631
+ throw err;
7632
+ }
7633
+ if (result.kind === "paid") {
7634
+ const res = await serve(request, ...rest);
7635
+ return withSettlementHeaders(res, result.receiptHeader);
7636
+ }
7637
+ return jsonResponse(result.challenge, 402, { [HEADER_REQUIRED]: result.requiredHeader });
7638
+ };
7639
+ }
7640
+ function toWorker(gate, serve) {
7641
+ return { fetch: toFetchHandler(gate, serve) };
7642
+ }
7643
+ function proxyTo(origin) {
7644
+ const base2 = origin.replace(/\/+$/, "");
7645
+ return (request) => {
7646
+ const inUrl = new URL(request.url);
7647
+ const target = base2 + inUrl.pathname + inUrl.search;
7648
+ const headers = new Headers(request.headers);
7649
+ headers.delete(HEADER_SIGNATURE);
7650
+ headers.delete(HEADER_SIGNATURE_V1);
7651
+ const init = {
7652
+ method: request.method,
7653
+ headers,
7654
+ redirect: "manual"
7655
+ };
7656
+ if (request.method !== "GET" && request.method !== "HEAD") {
7657
+ init.body = request.body;
7658
+ init.duplex = "half";
7659
+ }
7660
+ return fetch(target, init);
7661
+ };
7662
+ }
7663
+
7554
7664
  // src/receipts.ts
7555
7665
  var DEFAULT_RETRIES = 5;
7556
7666
  var DEFAULT_TIMEOUT_MS = 1e4;
@@ -8092,6 +8202,8 @@ export {
8092
8202
  createA2APaymentHandler,
8093
8203
  createMcpPaymentTool,
8094
8204
  createPaymentGate,
8205
+ createPaywall,
8206
+ createTipJar,
8095
8207
  decodeBase64Json,
8096
8208
  decorateOutcome,
8097
8209
  deliverReceipt,
@@ -8133,6 +8245,7 @@ export {
8133
8245
  paymentTools,
8134
8246
  pickAccept,
8135
8247
  planAcross,
8248
+ proxyTo,
8136
8249
  rankResources,
8137
8250
  readExactDomain,
8138
8251
  readPaymentIdentifier,
@@ -8150,9 +8263,11 @@ export {
8150
8263
  toA2APaymentFailed,
8151
8264
  toA2APaymentReceipts,
8152
8265
  toA2APaymentRequired,
8266
+ toFetchHandler,
8153
8267
  toInsufficientFundsError,
8154
8268
  toInvalidBody,
8155
8269
  toMcpPaymentRequired,
8156
8270
  toMcpPaymentResponse,
8271
+ toWorker,
8157
8272
  verify402IndexDomain
8158
8273
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@piprail/sdk",
3
- "version": "2.14.2",
3
+ "version": "2.15.0",
4
4
  "description": "Accept x402 crypto payments across 29 chains — every major EVM chain plus Solana, TON, Tron, NEAR, Sui, Aptos, Algorand, Stellar & XRPL — in a couple of lines. No backend, no database, no fee; payments settle straight to your wallet.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",