@piprail/sdk 1.19.0 → 1.20.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,36 @@ 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.20.0] — 2026-06-11 — discovery hardening: conformance-locked, accurate timing, PipRail-attributed
8
+
9
+ A minor release focused on the discovery/registration subsystem — verified live against the real
10
+ 402 Index + the deployed demo's wire, then locked as a contract. No payment-path change; the lazy-chunk
11
+ invariant holds.
12
+
13
+ ### Changed — registration attribution is now ON by default (opt-out)
14
+ - `client.register()` / `register402Index()` now attribute the listing to PipRail by default: a
15
+ `via: '@piprail/sdk'` provenance field **plus** a tasteful `· Built with @piprail/sdk` suffix on the
16
+ **description** (the one field an index displays) — the same unobtrusive "Made with X" marker as the
17
+ OpenAPI `x-generator`. It's metadata only (never changes how a resource is paid, ranked, or found),
18
+ is **deduped** (never double-stamps a description already naming PipRail), never fabricates a missing
19
+ description, and is **length-guarded**. **Opt out with `attribution: false`.** (Was opt-in/off before
20
+ — this is the one default change in the release; everything else is additive.)
21
+ - New pure exports: **`appendAttribution(description)`** and **`REGISTER_ATTRIBUTION`**.
22
+
23
+ ### Fixed — registration timing/visibility now matches reality
24
+ - The 402 Index caveat + register `detail` overstated the gate ("not searchable until approved"). Live
25
+ evidence (the demo is self-registered, `domain_verified: 0`, yet fully searchable) shows a self-
26
+ registered listing becomes searchable once it passes 402 Index's automated health + payment-validity
27
+ checks — no domain verification required. Domain verification is the **instant, guaranteed** path
28
+ (+ a verified badge). Wording corrected across `DIRECTORY_INFO`, the docs, and the llms files.
29
+
30
+ ### Added — an x402 conformance contract (test)
31
+ - `test/discovery-conformance.test.ts` encodes, as executable predicates, the x402 v2 PaymentRequirements
32
+ envelope (CAIP-2 networks, atomic-unit string amounts, the EIP-712 domain on an `exact` rail) **and**
33
+ x402scan's `validateResource` gate (HTTPS · v2 · non-empty accepts · resolvable input schema · ≥1
34
+ Base/Solana rail), asserted against the live demo's captured wire and the SDK's own generated output —
35
+ so a regression that would make a PipRail endpoint un-listable fails CI.
36
+
7
37
  ## [1.19.0] — 2026-06-11 — gasless `exact` on 3 more chains (Monad · zkSync Era · Injective)
8
38
 
9
39
  A minor, fully additive release — defaults byte-identical (`exact` stays opt-in), no new dependency,
package/dist/index.cjs CHANGED
@@ -1881,7 +1881,7 @@ var DIRECTORY_INFO = {
1881
1881
  chains: null,
1882
1882
  onSuccess: "pending-review",
1883
1883
  readByDiscover: true,
1884
- caveat: "402 Index probes your URL on submit, then lists it as PENDING REVIEW \u2014 a self-registered resource is NOT in search until approved. Verify your domain on 402index.io for instant approval; otherwise it appears after manual review, so retry discover() later."
1884
+ caveat: "402 Index probes your URL on submit (rejecting anything that does not return a real 402), then lists it \u2014 a self-registered resource becomes searchable once it passes automated health + payment-validity checks, with NO domain verification required (observed live: searchable within ~2 days for a healthy endpoint). Verify your domain on 402index.io for instant, guaranteed approval + a verified badge, which also flips every pending listing on that domain live at once."
1885
1885
  },
1886
1886
  x402scan: {
1887
1887
  source: "x402scan",
@@ -2046,16 +2046,18 @@ function railFrom402IndexFields(o) {
2046
2046
  }
2047
2047
  async function register402Index(input) {
2048
2048
  try {
2049
+ const attributionOn = input.attribution !== false;
2050
+ const description = attributionOn ? appendAttribution(input.description) : input.description;
2049
2051
  const payload = {
2050
2052
  url: input.url,
2051
2053
  name: _nullishCoalesce(input.name, () => ( hostOf(input.url))),
2052
2054
  protocol: "x402",
2053
- ...input.description ? { description: input.description } : {},
2055
+ ...description ? { description } : {},
2054
2056
  ...typeof input.priceUsd === "number" ? { price_usd: input.priceUsd } : {},
2055
2057
  ...input.asset ? { payment_asset: input.asset } : {},
2056
2058
  ...input.network ? { payment_network: input.network } : {},
2057
2059
  ...input.method ? { http_method: input.method.toUpperCase() } : {},
2058
- ...input.attribution ? { via: "@piprail/sdk" } : {}
2060
+ ...attributionOn ? { via: "@piprail/sdk" } : {}
2059
2061
  };
2060
2062
  const res = await fetch(INDEX402_REGISTER, {
2061
2063
  method: "POST",
@@ -2071,7 +2073,7 @@ async function register402Index(input) {
2071
2073
  ok: true,
2072
2074
  status: res.status,
2073
2075
  ...live ? { visibility: "live" } : {},
2074
- detail: _nullishCoalesce(msg, () => ( (live ? "Registered + live on 402 Index (domain verified)." : "Registered on 402 Index \u2014 pending review (verify your domain on 402index.io for instant approval).")))
2076
+ detail: _nullishCoalesce(msg, () => ( (live ? "Registered + live on 402 Index (domain verified)." : "Registered on 402 Index \u2014 probed on submit, then searchable once it passes automated health + payment checks (verify your domain on 402index.io for instant approval + a verified badge).")))
2075
2077
  };
2076
2078
  }
2077
2079
  const why = await readIndexError(res);
@@ -2302,6 +2304,13 @@ function hostOf(url) {
2302
2304
  function errMsg(err) {
2303
2305
  return err instanceof Error ? err.message : String(err);
2304
2306
  }
2307
+ var REGISTER_ATTRIBUTION = "\xB7 Built with @piprail/sdk";
2308
+ function appendAttribution(description) {
2309
+ if (!description) return description;
2310
+ if (/piprail/i.test(description)) return description;
2311
+ const next = `${description.trimEnd()} ${REGISTER_ATTRIBUTION}`;
2312
+ return next.length <= 500 ? next : description;
2313
+ }
2305
2314
  function encodeBase642(str) {
2306
2315
  if (typeof Buffer !== "undefined") return Buffer.from(str, "utf8").toString("base64");
2307
2316
  if (typeof btoa === "function" && typeof TextEncoder !== "undefined") {
@@ -2823,7 +2832,8 @@ var PipRailClient = (_class2 = class {
2823
2832
  ...opts.asset ? { asset: opts.asset } : {},
2824
2833
  ...networkSlug ? { network: networkSlug } : {},
2825
2834
  ...opts.method ? { method: opts.method } : {},
2826
- ...opts.attribution ? { attribution: true } : {}
2835
+ // Attribution is default-ON; forward an explicit opt-out, else let register402Index default it.
2836
+ ...opts.attribution === false ? { attribution: false } : {}
2827
2837
  })
2828
2838
  );
2829
2839
  } else if (target === "x402scan") {
@@ -4682,4 +4692,6 @@ async function deliverReceipt(receipt, options) {
4682
4692
 
4683
4693
 
4684
4694
 
4685
- exports.CHAINS = CHAINS; exports.ConfirmationTimeoutError = _chunkPA6YD3HLcjs.ConfirmationTimeoutError; exports.DIRECTORY_INFO = DIRECTORY_INFO; exports.EIP3009_TYPES = EIP3009_TYPES; exports.EXACT_NETWORK_SLUGS = EXACT_NETWORK_SLUGS; 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 = _chunkPA6YD3HLcjs.InsufficientFundsError; exports.InvalidEnvelopeError = _chunkPA6YD3HLcjs.InvalidEnvelopeError; exports.MaxRetriesExceededError = _chunkPA6YD3HLcjs.MaxRetriesExceededError; exports.MissingDriverError = _chunkPA6YD3HLcjs.MissingDriverError; exports.NoCompatibleAcceptError = _chunkPA6YD3HLcjs.NoCompatibleAcceptError; exports.NonReplayableBodyError = _chunkPA6YD3HLcjs.NonReplayableBodyError; exports.PERMIT2_ADDRESS = PERMIT2_ADDRESS; exports.PERMIT2_PROXY_CHAIN_IDS = PERMIT2_PROXY_CHAIN_IDS; exports.PERMIT2_WITNESS_TYPES = PERMIT2_WITNESS_TYPES; exports.PIPRAIL_AGENT_GUIDE = PIPRAIL_AGENT_GUIDE; exports.PaymentDeclinedError = _chunkPA6YD3HLcjs.PaymentDeclinedError; exports.PaymentTimeoutError = _chunkPA6YD3HLcjs.PaymentTimeoutError; exports.PipRailClient = PipRailClient; exports.PipRailError = _chunkPA6YD3HLcjs.PipRailError; exports.RecipientNotReadyError = _chunkPA6YD3HLcjs.RecipientNotReadyError; exports.SettlementError = _chunkPA6YD3HLcjs.SettlementError; exports.UnknownTokenError = _chunkPA6YD3HLcjs.UnknownTokenError; exports.UnsupportedNetworkError = _chunkPA6YD3HLcjs.UnsupportedNetworkError; exports.UnsupportedSchemeError = _chunkPA6YD3HLcjs.UnsupportedSchemeError; exports.WrongChainError = _chunkPA6YD3HLcjs.WrongChainError; exports.WrongFamilyError = _chunkPA6YD3HLcjs.WrongFamilyError; exports.X402_EXACT_PERMIT2_PROXY = X402_EXACT_PERMIT2_PROXY; exports.agentGuide = agentGuide; exports.buildBazaarExtension = buildBazaarExtension; exports.buildChallengeHeader = buildChallengeHeader; exports.buildExactAuthorization = buildExactAuthorization; exports.buildExactSignatureHeader = buildExactSignatureHeader; exports.buildOpenApi = buildOpenApi; exports.buildReceiptHeader = buildReceiptHeader; exports.buildSignatureHeader = buildSignatureHeader; exports.buildWellKnownX402 = buildWellKnownX402; exports.buildX402DnsTxt = buildX402DnsTxt; exports.chainIdForExactNetwork = chainIdForExactNetwork; exports.claim402IndexDomain = claim402IndexDomain; exports.classifyChallenge = classifyChallenge; exports.createPaymentGate = createPaymentGate; exports.decorateOutcome = decorateOutcome; exports.deliverReceipt = deliverReceipt; exports.eip3009Abi = eip3009Abi; exports.encodeXPaymentHeader = encodeXPaymentHeader; exports.evaluatePolicy = evaluatePolicy; exports.explainDecline = explainDecline; exports.formatSpendReport = formatSpendReport; exports.getDirectoryInfo = getDirectoryInfo; exports.isPermit2ProxyChain = isPermit2ProxyChain; exports.normalizeNetwork = normalizeNetwork; exports.parseChallenge = parseChallenge; exports.parseExactPaymentHeader = parseExactPaymentHeader; exports.parseExactRequirements = parseExactRequirements; exports.parseReceipt = parseReceipt; exports.parseSettleResponse = parseSettleResponse; exports.parseSignatureHeader = parseSignatureHeader; exports.paymentTools = paymentTools; exports.pickAccept = pickAccept; exports.planAcross = planAcross; exports.readExactDomain = readExactDomain; exports.register402Index = register402Index; exports.registerDriver = registerDriver; exports.registerX402Scan = registerX402Scan; exports.requirePayment = requirePayment; exports.resolveChain = resolveChain; exports.searchOpenIndexes = searchOpenIndexes; exports.settleViaFacilitator = settleViaFacilitator; exports.summarizePlan = summarizePlan; exports.toInsufficientFundsError = _chunkPA6YD3HLcjs.toInsufficientFundsError; exports.toInvalidBody = toInvalidBody; exports.verify402IndexDomain = verify402IndexDomain;
4695
+
4696
+
4697
+ exports.CHAINS = CHAINS; exports.ConfirmationTimeoutError = _chunkPA6YD3HLcjs.ConfirmationTimeoutError; exports.DIRECTORY_INFO = DIRECTORY_INFO; exports.EIP3009_TYPES = EIP3009_TYPES; exports.EXACT_NETWORK_SLUGS = EXACT_NETWORK_SLUGS; 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 = _chunkPA6YD3HLcjs.InsufficientFundsError; exports.InvalidEnvelopeError = _chunkPA6YD3HLcjs.InvalidEnvelopeError; exports.MaxRetriesExceededError = _chunkPA6YD3HLcjs.MaxRetriesExceededError; exports.MissingDriverError = _chunkPA6YD3HLcjs.MissingDriverError; exports.NoCompatibleAcceptError = _chunkPA6YD3HLcjs.NoCompatibleAcceptError; exports.NonReplayableBodyError = _chunkPA6YD3HLcjs.NonReplayableBodyError; exports.PERMIT2_ADDRESS = PERMIT2_ADDRESS; exports.PERMIT2_PROXY_CHAIN_IDS = PERMIT2_PROXY_CHAIN_IDS; exports.PERMIT2_WITNESS_TYPES = PERMIT2_WITNESS_TYPES; exports.PIPRAIL_AGENT_GUIDE = PIPRAIL_AGENT_GUIDE; exports.PaymentDeclinedError = _chunkPA6YD3HLcjs.PaymentDeclinedError; exports.PaymentTimeoutError = _chunkPA6YD3HLcjs.PaymentTimeoutError; exports.PipRailClient = PipRailClient; exports.PipRailError = _chunkPA6YD3HLcjs.PipRailError; exports.REGISTER_ATTRIBUTION = REGISTER_ATTRIBUTION; exports.RecipientNotReadyError = _chunkPA6YD3HLcjs.RecipientNotReadyError; exports.SettlementError = _chunkPA6YD3HLcjs.SettlementError; exports.UnknownTokenError = _chunkPA6YD3HLcjs.UnknownTokenError; exports.UnsupportedNetworkError = _chunkPA6YD3HLcjs.UnsupportedNetworkError; exports.UnsupportedSchemeError = _chunkPA6YD3HLcjs.UnsupportedSchemeError; exports.WrongChainError = _chunkPA6YD3HLcjs.WrongChainError; exports.WrongFamilyError = _chunkPA6YD3HLcjs.WrongFamilyError; exports.X402_EXACT_PERMIT2_PROXY = X402_EXACT_PERMIT2_PROXY; exports.agentGuide = agentGuide; exports.appendAttribution = appendAttribution; exports.buildBazaarExtension = buildBazaarExtension; exports.buildChallengeHeader = buildChallengeHeader; exports.buildExactAuthorization = buildExactAuthorization; exports.buildExactSignatureHeader = buildExactSignatureHeader; exports.buildOpenApi = buildOpenApi; exports.buildReceiptHeader = buildReceiptHeader; exports.buildSignatureHeader = buildSignatureHeader; exports.buildWellKnownX402 = buildWellKnownX402; exports.buildX402DnsTxt = buildX402DnsTxt; exports.chainIdForExactNetwork = chainIdForExactNetwork; exports.claim402IndexDomain = claim402IndexDomain; exports.classifyChallenge = classifyChallenge; exports.createPaymentGate = createPaymentGate; exports.decorateOutcome = decorateOutcome; exports.deliverReceipt = deliverReceipt; exports.eip3009Abi = eip3009Abi; exports.encodeXPaymentHeader = encodeXPaymentHeader; exports.evaluatePolicy = evaluatePolicy; exports.explainDecline = explainDecline; exports.formatSpendReport = formatSpendReport; exports.getDirectoryInfo = getDirectoryInfo; exports.isPermit2ProxyChain = isPermit2ProxyChain; exports.normalizeNetwork = normalizeNetwork; exports.parseChallenge = parseChallenge; exports.parseExactPaymentHeader = parseExactPaymentHeader; exports.parseExactRequirements = parseExactRequirements; exports.parseReceipt = parseReceipt; exports.parseSettleResponse = parseSettleResponse; exports.parseSignatureHeader = parseSignatureHeader; exports.paymentTools = paymentTools; exports.pickAccept = pickAccept; exports.planAcross = planAcross; exports.readExactDomain = readExactDomain; exports.register402Index = register402Index; exports.registerDriver = registerDriver; exports.registerX402Scan = registerX402Scan; exports.requirePayment = requirePayment; exports.resolveChain = resolveChain; exports.searchOpenIndexes = searchOpenIndexes; exports.settleViaFacilitator = settleViaFacilitator; exports.summarizePlan = summarizePlan; exports.toInsufficientFundsError = _chunkPA6YD3HLcjs.toInsufficientFundsError; exports.toInvalidBody = toInvalidBody; exports.verify402IndexDomain = verify402IndexDomain;
package/dist/index.d.cts CHANGED
@@ -4472,11 +4472,14 @@ interface RegisterInput {
4472
4472
  /** HTTP method the resource answers on. Default 'GET'. */
4473
4473
  method?: string;
4474
4474
  /**
4475
- * Opt-in (default off): add a `via: '@piprail/sdk'` tag to the listing payload. It's the
4476
- * MERCHANT's listing on a third-party index, so we never tag it by default; and it's
4477
- * **best-effort** an index may ignore an unrecognised field. The reliable, always-on
4478
- * attribution is the `User-Agent` on the request + the `x-generator` stamp in your
4479
- * emitted `/openapi.json`. Off by default keeps your listing clean and can't be seen as spam.
4475
+ * Attribute the listing to PipRail. **Default ON** (set `false` to opt out). When on, the
4476
+ * payload gets a `via: '@piprail/sdk'` provenance field AND a compact Built with
4477
+ * @piprail/sdk` suffix on the description (see {@link appendAttribution}) the one field an
4478
+ * index displays, so the listing is *visibly* built with PipRail as it spreads, the same
4479
+ * unobtrusive "Made with X" marker as the `/openapi.json` `x-generator`. It's metadata only:
4480
+ * never changes how the resource is paid or ranked, never double-stamps a description that
4481
+ * already mentions PipRail, and never fabricates one you didn't provide. The `User-Agent`
4482
+ * carries PipRail on every request regardless.
4480
4483
  */
4481
4484
  attribution?: boolean;
4482
4485
  }
@@ -4603,6 +4606,16 @@ declare function claim402IndexDomain(domainOrUrl: string, opts?: {
4603
4606
  * `servicesCount` approved). No funds move. Never throws.
4604
4607
  */
4605
4608
  declare function verify402IndexDomain(domainOrUrl: string): Promise<DomainVerification>;
4609
+ /** The compact "Made with X" marker {@link appendAttribution} adds to a listing's
4610
+ * description by default (the elegant, universally-accepted Swagger/Hugo pattern).
4611
+ * Middot-separated so it reads as metadata, never as part of the merchant's prose. */
4612
+ declare const REGISTER_ATTRIBUTION = "\u00B7 Built with @piprail/sdk";
4613
+ /** Append {@link REGISTER_ATTRIBUTION} to a listing description — *tastefully*. Pure.
4614
+ * Returns the description unchanged when it's absent (we never fabricate one), already
4615
+ * mentions PipRail (never double-stamp), or the result would exceed a sane listing cap
4616
+ * (≤ 500 chars). This is the only attribution an index actually DISPLAYS, so it's how a
4617
+ * registered listing stays visibly "built with PipRail" — opt out with `attribution:false`. */
4618
+ declare function appendAttribution(description: string | undefined): string | undefined;
4606
4619
 
4607
4620
  interface PaymentPolicy {
4608
4621
  /** Per-payment ceiling, human-readable (e.g. '0.10'). Compared using the
@@ -5105,11 +5118,12 @@ interface RegisterOptions {
5105
5118
  */
5106
5119
  targets?: DiscoverySource[];
5107
5120
  /**
5108
- * Opt-in (default off): tag the listing as built with PipRail (`via: '@piprail/sdk'`).
5109
- * It's a third-party listing, so we never tag it by default and it's best-effort (the
5110
- * index may ignore the field). The always-on, reliable attribution is the request
5111
- * `User-Agent` + the `x-generator` stamp in your emitted `/openapi.json` (see
5112
- * `buildOpenApi`). Leave off unless you specifically want the listing tagged.
5121
+ * Attribute the listing to PipRail. **Default ON** (set `false` to opt out). When on, the
5122
+ * listing gets a `via: '@piprail/sdk'` provenance field plus a compact Built with
5123
+ * @piprail/sdk` suffix on the description the same unobtrusive "Made with X" marker as the
5124
+ * `/openapi.json` `x-generator`. Metadata only: it never changes how the resource is paid or
5125
+ * ranked, never double-stamps a description that already names PipRail, and never fabricates
5126
+ * one. The request `User-Agent` carries PipRail regardless.
5113
5127
  */
5114
5128
  attribution?: boolean;
5115
5129
  }
@@ -6685,4 +6699,4 @@ declare const PERMIT2_WITNESS_TYPES: {
6685
6699
  }];
6686
6700
  };
6687
6701
 
6688
- export { type AcceptOption, type AddressId, type AgentTool, type AlgorandToken, type AptosToken, type AssetId, type BazaarExtension, type BuildExactParams, CHAINS, type Caip2, type ChainFamily, type ChainInput, type ChainName, type ChainPreset, type ChainSelector, type ChallengeTriage, type ChallengeVerdict, type ConfirmInfo, ConfirmationTimeoutError, type CostEstimate, DIRECTORY_INFO, type DeclineReasonCode, type DeliverAttempt, type DeliverReceiptOptions, type DeliverResult, type DirectoryInfo, type DiscoverOptions, type DiscoveredRail, type DiscoveredResource, type DiscoveryDescriptor, type DiscoverySigner, type DiscoverySource, type DomainClaim, type DomainVerification, EIP3009_TYPES, EXACT_NETWORK_SLUGS, type EvmToken, type ExactAccept, type ExactAuthorization, type ExactAuthorizationWire, type ExactPaymentPayload, type ExactPaymentPayloadAny, type ExactRailOption, type ExpressLikeMiddleware, type ExpressLikeNext, type ExpressLikeRequest, type ExpressLikeResponse, type FacilitatorConfig, type FacilitatorPaymentRequirements, GENERATOR, HEADER_REQUIRED, HEADER_RESPONSE, HEADER_RESPONSE_V1, HEADER_SIGNATURE, HEADER_SIGNATURE_V1, InsufficientFundsError, InvalidEnvelopeError, type ListingVisibility, type ManifestInput, MaxRetriesExceededError, MissingDriverError, type NearToken, NoCompatibleAcceptError, NonReplayableBodyError, type OpenApiDocument, type OpenApiOperation, PERMIT2_ADDRESS, PERMIT2_PROXY_CHAIN_IDS, PERMIT2_WITNESS_TYPES, PIPRAIL_AGENT_GUIDE, type PaidReceipt, type ParsedExactPayment, type PayBlocker, type PayOption, type PayWarning, PaymentDeclinedError, type PaymentDriver, type PaymentGate, type PaymentIntent, type PaymentPlan, type PaymentPolicy, type PaymentRail, type PaymentScheme, PaymentTimeoutError, type Permit2Authorization, type Permit2PaymentPayload, PipRailClient, type PipRailClientOptions, type PipRailCostQuote, PipRailError, type PipRailEvent, type PipRailQuote, type PolicyDecision, type PolicyDenyCode, RecipientNotReadyError, type RecipientReason, type RegisterInput, type RegisterOptions, type RegisterOutcome, type RequirePaymentOptions, type ResolveOptions, type ResolvedChain, type ResolvedNetwork, type ResolvedToken, type ResourceDescription, type SearchOpenIndexesOptions, type SessionBudget, type SettleOutcome, type SettleViaFacilitatorInput, SettlementError, type SolanaToken, type SpendAssetTotal, type SpendRecord, type SpendRemaining, type SpendSummary, type StellarToken, type SuiToken, type TokenInfo, type TokenInput, type TonToken, type ToolAnnotations, type TronToken, UnknownTokenError, UnsupportedNetworkError, UnsupportedSchemeError, type VerifyErrorCode, type VerifyPaymentResult, type VerifyResult, type WalletBalance, type WalletHandle, type WalletInput, type WellKnownX402, WrongChainError, WrongFamilyError, type X402AcceptEntry, type X402AnyAccept, type X402Challenge, type X402DnsRecord, type X402ExactAcceptEntry, type X402InvalidBody, type X402PaymentSignature, type X402Receipt, type X402ResourceObject, X402_EXACT_PERMIT2_PROXY, type XrplToken, agentGuide, buildBazaarExtension, buildChallengeHeader, buildExactAuthorization, buildExactSignatureHeader, buildOpenApi, buildReceiptHeader, buildSignatureHeader, buildWellKnownX402, buildX402DnsTxt, chainIdForExactNetwork, claim402IndexDomain, classifyChallenge, createPaymentGate, decorateOutcome, deliverReceipt, eip3009Abi, encodeXPaymentHeader, evaluatePolicy, explainDecline, formatSpendReport, getDirectoryInfo, isPermit2ProxyChain, normalizeNetwork, parseChallenge, parseExactPaymentHeader, parseExactRequirements, parseReceipt, parseSettleResponse, parseSignatureHeader, paymentTools, pickAccept, planAcross, readExactDomain, register402Index, registerDriver, registerX402Scan, requirePayment, resolveChain, searchOpenIndexes, settleViaFacilitator, summarizePlan, toInsufficientFundsError, toInvalidBody, verify402IndexDomain };
6702
+ export { type AcceptOption, type AddressId, type AgentTool, type AlgorandToken, type AptosToken, type AssetId, type BazaarExtension, type BuildExactParams, CHAINS, type Caip2, type ChainFamily, type ChainInput, type ChainName, type ChainPreset, type ChainSelector, type ChallengeTriage, type ChallengeVerdict, type ConfirmInfo, ConfirmationTimeoutError, type CostEstimate, DIRECTORY_INFO, type DeclineReasonCode, type DeliverAttempt, type DeliverReceiptOptions, type DeliverResult, type DirectoryInfo, type DiscoverOptions, type DiscoveredRail, type DiscoveredResource, type DiscoveryDescriptor, type DiscoverySigner, type DiscoverySource, type DomainClaim, type DomainVerification, EIP3009_TYPES, EXACT_NETWORK_SLUGS, type EvmToken, type ExactAccept, type ExactAuthorization, type ExactAuthorizationWire, type ExactPaymentPayload, type ExactPaymentPayloadAny, type ExactRailOption, type ExpressLikeMiddleware, type ExpressLikeNext, type ExpressLikeRequest, type ExpressLikeResponse, type FacilitatorConfig, type FacilitatorPaymentRequirements, GENERATOR, HEADER_REQUIRED, HEADER_RESPONSE, HEADER_RESPONSE_V1, HEADER_SIGNATURE, HEADER_SIGNATURE_V1, InsufficientFundsError, InvalidEnvelopeError, type ListingVisibility, type ManifestInput, MaxRetriesExceededError, MissingDriverError, type NearToken, NoCompatibleAcceptError, NonReplayableBodyError, type OpenApiDocument, type OpenApiOperation, PERMIT2_ADDRESS, PERMIT2_PROXY_CHAIN_IDS, PERMIT2_WITNESS_TYPES, PIPRAIL_AGENT_GUIDE, type PaidReceipt, type ParsedExactPayment, type PayBlocker, type PayOption, type PayWarning, PaymentDeclinedError, type PaymentDriver, type PaymentGate, type PaymentIntent, type PaymentPlan, type PaymentPolicy, type PaymentRail, type PaymentScheme, PaymentTimeoutError, type Permit2Authorization, type Permit2PaymentPayload, PipRailClient, type PipRailClientOptions, type PipRailCostQuote, PipRailError, type PipRailEvent, type PipRailQuote, type PolicyDecision, type PolicyDenyCode, REGISTER_ATTRIBUTION, RecipientNotReadyError, type RecipientReason, type RegisterInput, type RegisterOptions, type RegisterOutcome, type RequirePaymentOptions, type ResolveOptions, type ResolvedChain, type ResolvedNetwork, type ResolvedToken, type ResourceDescription, type SearchOpenIndexesOptions, type SessionBudget, type SettleOutcome, type SettleViaFacilitatorInput, SettlementError, type SolanaToken, type SpendAssetTotal, type SpendRecord, type SpendRemaining, type SpendSummary, type StellarToken, type SuiToken, type TokenInfo, type TokenInput, type TonToken, type ToolAnnotations, type TronToken, UnknownTokenError, UnsupportedNetworkError, UnsupportedSchemeError, type VerifyErrorCode, type VerifyPaymentResult, type VerifyResult, type WalletBalance, type WalletHandle, type WalletInput, type WellKnownX402, WrongChainError, WrongFamilyError, type X402AcceptEntry, type X402AnyAccept, type X402Challenge, type X402DnsRecord, type X402ExactAcceptEntry, type X402InvalidBody, type X402PaymentSignature, type X402Receipt, type X402ResourceObject, X402_EXACT_PERMIT2_PROXY, type XrplToken, agentGuide, appendAttribution, buildBazaarExtension, buildChallengeHeader, buildExactAuthorization, buildExactSignatureHeader, buildOpenApi, buildReceiptHeader, buildSignatureHeader, buildWellKnownX402, buildX402DnsTxt, chainIdForExactNetwork, claim402IndexDomain, classifyChallenge, createPaymentGate, decorateOutcome, deliverReceipt, eip3009Abi, encodeXPaymentHeader, evaluatePolicy, explainDecline, formatSpendReport, getDirectoryInfo, isPermit2ProxyChain, normalizeNetwork, parseChallenge, parseExactPaymentHeader, parseExactRequirements, parseReceipt, parseSettleResponse, parseSignatureHeader, paymentTools, pickAccept, planAcross, readExactDomain, register402Index, registerDriver, registerX402Scan, requirePayment, resolveChain, searchOpenIndexes, settleViaFacilitator, summarizePlan, toInsufficientFundsError, toInvalidBody, verify402IndexDomain };
package/dist/index.d.ts CHANGED
@@ -4472,11 +4472,14 @@ interface RegisterInput {
4472
4472
  /** HTTP method the resource answers on. Default 'GET'. */
4473
4473
  method?: string;
4474
4474
  /**
4475
- * Opt-in (default off): add a `via: '@piprail/sdk'` tag to the listing payload. It's the
4476
- * MERCHANT's listing on a third-party index, so we never tag it by default; and it's
4477
- * **best-effort** an index may ignore an unrecognised field. The reliable, always-on
4478
- * attribution is the `User-Agent` on the request + the `x-generator` stamp in your
4479
- * emitted `/openapi.json`. Off by default keeps your listing clean and can't be seen as spam.
4475
+ * Attribute the listing to PipRail. **Default ON** (set `false` to opt out). When on, the
4476
+ * payload gets a `via: '@piprail/sdk'` provenance field AND a compact Built with
4477
+ * @piprail/sdk` suffix on the description (see {@link appendAttribution}) the one field an
4478
+ * index displays, so the listing is *visibly* built with PipRail as it spreads, the same
4479
+ * unobtrusive "Made with X" marker as the `/openapi.json` `x-generator`. It's metadata only:
4480
+ * never changes how the resource is paid or ranked, never double-stamps a description that
4481
+ * already mentions PipRail, and never fabricates one you didn't provide. The `User-Agent`
4482
+ * carries PipRail on every request regardless.
4480
4483
  */
4481
4484
  attribution?: boolean;
4482
4485
  }
@@ -4603,6 +4606,16 @@ declare function claim402IndexDomain(domainOrUrl: string, opts?: {
4603
4606
  * `servicesCount` approved). No funds move. Never throws.
4604
4607
  */
4605
4608
  declare function verify402IndexDomain(domainOrUrl: string): Promise<DomainVerification>;
4609
+ /** The compact "Made with X" marker {@link appendAttribution} adds to a listing's
4610
+ * description by default (the elegant, universally-accepted Swagger/Hugo pattern).
4611
+ * Middot-separated so it reads as metadata, never as part of the merchant's prose. */
4612
+ declare const REGISTER_ATTRIBUTION = "\u00B7 Built with @piprail/sdk";
4613
+ /** Append {@link REGISTER_ATTRIBUTION} to a listing description — *tastefully*. Pure.
4614
+ * Returns the description unchanged when it's absent (we never fabricate one), already
4615
+ * mentions PipRail (never double-stamp), or the result would exceed a sane listing cap
4616
+ * (≤ 500 chars). This is the only attribution an index actually DISPLAYS, so it's how a
4617
+ * registered listing stays visibly "built with PipRail" — opt out with `attribution:false`. */
4618
+ declare function appendAttribution(description: string | undefined): string | undefined;
4606
4619
 
4607
4620
  interface PaymentPolicy {
4608
4621
  /** Per-payment ceiling, human-readable (e.g. '0.10'). Compared using the
@@ -5105,11 +5118,12 @@ interface RegisterOptions {
5105
5118
  */
5106
5119
  targets?: DiscoverySource[];
5107
5120
  /**
5108
- * Opt-in (default off): tag the listing as built with PipRail (`via: '@piprail/sdk'`).
5109
- * It's a third-party listing, so we never tag it by default and it's best-effort (the
5110
- * index may ignore the field). The always-on, reliable attribution is the request
5111
- * `User-Agent` + the `x-generator` stamp in your emitted `/openapi.json` (see
5112
- * `buildOpenApi`). Leave off unless you specifically want the listing tagged.
5121
+ * Attribute the listing to PipRail. **Default ON** (set `false` to opt out). When on, the
5122
+ * listing gets a `via: '@piprail/sdk'` provenance field plus a compact Built with
5123
+ * @piprail/sdk` suffix on the description the same unobtrusive "Made with X" marker as the
5124
+ * `/openapi.json` `x-generator`. Metadata only: it never changes how the resource is paid or
5125
+ * ranked, never double-stamps a description that already names PipRail, and never fabricates
5126
+ * one. The request `User-Agent` carries PipRail regardless.
5113
5127
  */
5114
5128
  attribution?: boolean;
5115
5129
  }
@@ -6685,4 +6699,4 @@ declare const PERMIT2_WITNESS_TYPES: {
6685
6699
  }];
6686
6700
  };
6687
6701
 
6688
- export { type AcceptOption, type AddressId, type AgentTool, type AlgorandToken, type AptosToken, type AssetId, type BazaarExtension, type BuildExactParams, CHAINS, type Caip2, type ChainFamily, type ChainInput, type ChainName, type ChainPreset, type ChainSelector, type ChallengeTriage, type ChallengeVerdict, type ConfirmInfo, ConfirmationTimeoutError, type CostEstimate, DIRECTORY_INFO, type DeclineReasonCode, type DeliverAttempt, type DeliverReceiptOptions, type DeliverResult, type DirectoryInfo, type DiscoverOptions, type DiscoveredRail, type DiscoveredResource, type DiscoveryDescriptor, type DiscoverySigner, type DiscoverySource, type DomainClaim, type DomainVerification, EIP3009_TYPES, EXACT_NETWORK_SLUGS, type EvmToken, type ExactAccept, type ExactAuthorization, type ExactAuthorizationWire, type ExactPaymentPayload, type ExactPaymentPayloadAny, type ExactRailOption, type ExpressLikeMiddleware, type ExpressLikeNext, type ExpressLikeRequest, type ExpressLikeResponse, type FacilitatorConfig, type FacilitatorPaymentRequirements, GENERATOR, HEADER_REQUIRED, HEADER_RESPONSE, HEADER_RESPONSE_V1, HEADER_SIGNATURE, HEADER_SIGNATURE_V1, InsufficientFundsError, InvalidEnvelopeError, type ListingVisibility, type ManifestInput, MaxRetriesExceededError, MissingDriverError, type NearToken, NoCompatibleAcceptError, NonReplayableBodyError, type OpenApiDocument, type OpenApiOperation, PERMIT2_ADDRESS, PERMIT2_PROXY_CHAIN_IDS, PERMIT2_WITNESS_TYPES, PIPRAIL_AGENT_GUIDE, type PaidReceipt, type ParsedExactPayment, type PayBlocker, type PayOption, type PayWarning, PaymentDeclinedError, type PaymentDriver, type PaymentGate, type PaymentIntent, type PaymentPlan, type PaymentPolicy, type PaymentRail, type PaymentScheme, PaymentTimeoutError, type Permit2Authorization, type Permit2PaymentPayload, PipRailClient, type PipRailClientOptions, type PipRailCostQuote, PipRailError, type PipRailEvent, type PipRailQuote, type PolicyDecision, type PolicyDenyCode, RecipientNotReadyError, type RecipientReason, type RegisterInput, type RegisterOptions, type RegisterOutcome, type RequirePaymentOptions, type ResolveOptions, type ResolvedChain, type ResolvedNetwork, type ResolvedToken, type ResourceDescription, type SearchOpenIndexesOptions, type SessionBudget, type SettleOutcome, type SettleViaFacilitatorInput, SettlementError, type SolanaToken, type SpendAssetTotal, type SpendRecord, type SpendRemaining, type SpendSummary, type StellarToken, type SuiToken, type TokenInfo, type TokenInput, type TonToken, type ToolAnnotations, type TronToken, UnknownTokenError, UnsupportedNetworkError, UnsupportedSchemeError, type VerifyErrorCode, type VerifyPaymentResult, type VerifyResult, type WalletBalance, type WalletHandle, type WalletInput, type WellKnownX402, WrongChainError, WrongFamilyError, type X402AcceptEntry, type X402AnyAccept, type X402Challenge, type X402DnsRecord, type X402ExactAcceptEntry, type X402InvalidBody, type X402PaymentSignature, type X402Receipt, type X402ResourceObject, X402_EXACT_PERMIT2_PROXY, type XrplToken, agentGuide, buildBazaarExtension, buildChallengeHeader, buildExactAuthorization, buildExactSignatureHeader, buildOpenApi, buildReceiptHeader, buildSignatureHeader, buildWellKnownX402, buildX402DnsTxt, chainIdForExactNetwork, claim402IndexDomain, classifyChallenge, createPaymentGate, decorateOutcome, deliverReceipt, eip3009Abi, encodeXPaymentHeader, evaluatePolicy, explainDecline, formatSpendReport, getDirectoryInfo, isPermit2ProxyChain, normalizeNetwork, parseChallenge, parseExactPaymentHeader, parseExactRequirements, parseReceipt, parseSettleResponse, parseSignatureHeader, paymentTools, pickAccept, planAcross, readExactDomain, register402Index, registerDriver, registerX402Scan, requirePayment, resolveChain, searchOpenIndexes, settleViaFacilitator, summarizePlan, toInsufficientFundsError, toInvalidBody, verify402IndexDomain };
6702
+ export { type AcceptOption, type AddressId, type AgentTool, type AlgorandToken, type AptosToken, type AssetId, type BazaarExtension, type BuildExactParams, CHAINS, type Caip2, type ChainFamily, type ChainInput, type ChainName, type ChainPreset, type ChainSelector, type ChallengeTriage, type ChallengeVerdict, type ConfirmInfo, ConfirmationTimeoutError, type CostEstimate, DIRECTORY_INFO, type DeclineReasonCode, type DeliverAttempt, type DeliverReceiptOptions, type DeliverResult, type DirectoryInfo, type DiscoverOptions, type DiscoveredRail, type DiscoveredResource, type DiscoveryDescriptor, type DiscoverySigner, type DiscoverySource, type DomainClaim, type DomainVerification, EIP3009_TYPES, EXACT_NETWORK_SLUGS, type EvmToken, type ExactAccept, type ExactAuthorization, type ExactAuthorizationWire, type ExactPaymentPayload, type ExactPaymentPayloadAny, type ExactRailOption, type ExpressLikeMiddleware, type ExpressLikeNext, type ExpressLikeRequest, type ExpressLikeResponse, type FacilitatorConfig, type FacilitatorPaymentRequirements, GENERATOR, HEADER_REQUIRED, HEADER_RESPONSE, HEADER_RESPONSE_V1, HEADER_SIGNATURE, HEADER_SIGNATURE_V1, InsufficientFundsError, InvalidEnvelopeError, type ListingVisibility, type ManifestInput, MaxRetriesExceededError, MissingDriverError, type NearToken, NoCompatibleAcceptError, NonReplayableBodyError, type OpenApiDocument, type OpenApiOperation, PERMIT2_ADDRESS, PERMIT2_PROXY_CHAIN_IDS, PERMIT2_WITNESS_TYPES, PIPRAIL_AGENT_GUIDE, type PaidReceipt, type ParsedExactPayment, type PayBlocker, type PayOption, type PayWarning, PaymentDeclinedError, type PaymentDriver, type PaymentGate, type PaymentIntent, type PaymentPlan, type PaymentPolicy, type PaymentRail, type PaymentScheme, PaymentTimeoutError, type Permit2Authorization, type Permit2PaymentPayload, PipRailClient, type PipRailClientOptions, type PipRailCostQuote, PipRailError, type PipRailEvent, type PipRailQuote, type PolicyDecision, type PolicyDenyCode, REGISTER_ATTRIBUTION, RecipientNotReadyError, type RecipientReason, type RegisterInput, type RegisterOptions, type RegisterOutcome, type RequirePaymentOptions, type ResolveOptions, type ResolvedChain, type ResolvedNetwork, type ResolvedToken, type ResourceDescription, type SearchOpenIndexesOptions, type SessionBudget, type SettleOutcome, type SettleViaFacilitatorInput, SettlementError, type SolanaToken, type SpendAssetTotal, type SpendRecord, type SpendRemaining, type SpendSummary, type StellarToken, type SuiToken, type TokenInfo, type TokenInput, type TonToken, type ToolAnnotations, type TronToken, UnknownTokenError, UnsupportedNetworkError, UnsupportedSchemeError, type VerifyErrorCode, type VerifyPaymentResult, type VerifyResult, type WalletBalance, type WalletHandle, type WalletInput, type WellKnownX402, WrongChainError, WrongFamilyError, type X402AcceptEntry, type X402AnyAccept, type X402Challenge, type X402DnsRecord, type X402ExactAcceptEntry, type X402InvalidBody, type X402PaymentSignature, type X402Receipt, type X402ResourceObject, X402_EXACT_PERMIT2_PROXY, type XrplToken, agentGuide, appendAttribution, buildBazaarExtension, buildChallengeHeader, buildExactAuthorization, buildExactSignatureHeader, buildOpenApi, buildReceiptHeader, buildSignatureHeader, buildWellKnownX402, buildX402DnsTxt, chainIdForExactNetwork, claim402IndexDomain, classifyChallenge, createPaymentGate, decorateOutcome, deliverReceipt, eip3009Abi, encodeXPaymentHeader, evaluatePolicy, explainDecline, formatSpendReport, getDirectoryInfo, isPermit2ProxyChain, normalizeNetwork, parseChallenge, parseExactPaymentHeader, parseExactRequirements, parseReceipt, parseSettleResponse, parseSignatureHeader, paymentTools, pickAccept, planAcross, readExactDomain, register402Index, registerDriver, registerX402Scan, requirePayment, resolveChain, searchOpenIndexes, settleViaFacilitator, summarizePlan, toInsufficientFundsError, toInvalidBody, verify402IndexDomain };
package/dist/index.js CHANGED
@@ -1881,7 +1881,7 @@ var DIRECTORY_INFO = {
1881
1881
  chains: null,
1882
1882
  onSuccess: "pending-review",
1883
1883
  readByDiscover: true,
1884
- caveat: "402 Index probes your URL on submit, then lists it as PENDING REVIEW \u2014 a self-registered resource is NOT in search until approved. Verify your domain on 402index.io for instant approval; otherwise it appears after manual review, so retry discover() later."
1884
+ caveat: "402 Index probes your URL on submit (rejecting anything that does not return a real 402), then lists it \u2014 a self-registered resource becomes searchable once it passes automated health + payment-validity checks, with NO domain verification required (observed live: searchable within ~2 days for a healthy endpoint). Verify your domain on 402index.io for instant, guaranteed approval + a verified badge, which also flips every pending listing on that domain live at once."
1885
1885
  },
1886
1886
  x402scan: {
1887
1887
  source: "x402scan",
@@ -2046,16 +2046,18 @@ function railFrom402IndexFields(o) {
2046
2046
  }
2047
2047
  async function register402Index(input) {
2048
2048
  try {
2049
+ const attributionOn = input.attribution !== false;
2050
+ const description = attributionOn ? appendAttribution(input.description) : input.description;
2049
2051
  const payload = {
2050
2052
  url: input.url,
2051
2053
  name: input.name ?? hostOf(input.url),
2052
2054
  protocol: "x402",
2053
- ...input.description ? { description: input.description } : {},
2055
+ ...description ? { description } : {},
2054
2056
  ...typeof input.priceUsd === "number" ? { price_usd: input.priceUsd } : {},
2055
2057
  ...input.asset ? { payment_asset: input.asset } : {},
2056
2058
  ...input.network ? { payment_network: input.network } : {},
2057
2059
  ...input.method ? { http_method: input.method.toUpperCase() } : {},
2058
- ...input.attribution ? { via: "@piprail/sdk" } : {}
2060
+ ...attributionOn ? { via: "@piprail/sdk" } : {}
2059
2061
  };
2060
2062
  const res = await fetch(INDEX402_REGISTER, {
2061
2063
  method: "POST",
@@ -2071,7 +2073,7 @@ async function register402Index(input) {
2071
2073
  ok: true,
2072
2074
  status: res.status,
2073
2075
  ...live ? { visibility: "live" } : {},
2074
- detail: msg ?? (live ? "Registered + live on 402 Index (domain verified)." : "Registered on 402 Index \u2014 pending review (verify your domain on 402index.io for instant approval).")
2076
+ detail: msg ?? (live ? "Registered + live on 402 Index (domain verified)." : "Registered on 402 Index \u2014 probed on submit, then searchable once it passes automated health + payment checks (verify your domain on 402index.io for instant approval + a verified badge).")
2075
2077
  };
2076
2078
  }
2077
2079
  const why = await readIndexError(res);
@@ -2302,6 +2304,13 @@ function hostOf(url) {
2302
2304
  function errMsg(err) {
2303
2305
  return err instanceof Error ? err.message : String(err);
2304
2306
  }
2307
+ var REGISTER_ATTRIBUTION = "\xB7 Built with @piprail/sdk";
2308
+ function appendAttribution(description) {
2309
+ if (!description) return description;
2310
+ if (/piprail/i.test(description)) return description;
2311
+ const next = `${description.trimEnd()} ${REGISTER_ATTRIBUTION}`;
2312
+ return next.length <= 500 ? next : description;
2313
+ }
2305
2314
  function encodeBase642(str) {
2306
2315
  if (typeof Buffer !== "undefined") return Buffer.from(str, "utf8").toString("base64");
2307
2316
  if (typeof btoa === "function" && typeof TextEncoder !== "undefined") {
@@ -2823,7 +2832,8 @@ var PipRailClient = class {
2823
2832
  ...opts.asset ? { asset: opts.asset } : {},
2824
2833
  ...networkSlug ? { network: networkSlug } : {},
2825
2834
  ...opts.method ? { method: opts.method } : {},
2826
- ...opts.attribution ? { attribution: true } : {}
2835
+ // Attribution is default-ON; forward an explicit opt-out, else let register402Index default it.
2836
+ ...opts.attribution === false ? { attribution: false } : {}
2827
2837
  })
2828
2838
  );
2829
2839
  } else if (target === "x402scan") {
@@ -4629,6 +4639,7 @@ export {
4629
4639
  PaymentTimeoutError,
4630
4640
  PipRailClient,
4631
4641
  PipRailError,
4642
+ REGISTER_ATTRIBUTION,
4632
4643
  RecipientNotReadyError,
4633
4644
  SettlementError,
4634
4645
  UnknownTokenError,
@@ -4638,6 +4649,7 @@ export {
4638
4649
  WrongFamilyError,
4639
4650
  X402_EXACT_PERMIT2_PROXY,
4640
4651
  agentGuide,
4652
+ appendAttribution,
4641
4653
  buildBazaarExtension,
4642
4654
  buildChallengeHeader,
4643
4655
  buildExactAuthorization,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@piprail/sdk",
3
- "version": "1.19.0",
3
+ "version": "1.20.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",