@piprail/sdk 1.19.0 → 1.20.1
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 +52 -0
- package/dist/index.cjs +36 -9
- package/dist/index.d.cts +25 -11
- package/dist/index.d.ts +25 -11
- package/dist/index.js +35 -8
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,58 @@ 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.1] — 2026-06-11 — gate replay store: bounded + exception-safe
|
|
8
|
+
|
|
9
|
+
Patch — internal robustness on the gate's built-in replay protection. No API change, no visible
|
|
10
|
+
behaviour change, defaults identical.
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
- **Bounded the default used-proof set.** It's now evicted past the replay window
|
|
14
|
+
(`maxTimeoutSeconds`) instead of growing for the life of the process — safe because the driver's
|
|
15
|
+
recency check rejects any proof that old anyway, so a dropped entry still can't be replayed. A
|
|
16
|
+
long-lived gate no longer slowly leaks memory. Custom `isUsed`/`markUsed` stores are unaffected
|
|
17
|
+
(give them a TTL = the window).
|
|
18
|
+
- **`onchain-proof` verification is now claim-release exception-safe.** If a driver's `verify()`
|
|
19
|
+
*throws* (an unexpected RPC exception) rather than returning a rejection, the gate now releases the
|
|
20
|
+
proof reservation before rethrowing — so a transient blip can't permanently burn an otherwise-valid
|
|
21
|
+
proof. This matches the `exact` path, which already did it.
|
|
22
|
+
|
|
23
|
+
### Docs
|
|
24
|
+
- Rewrote **[Replay protection & recovery](https://docs.piprail.com/accepting-payments/replay-protection/)**
|
|
25
|
+
with the full "paid but didn't receive — what happens to the payment?" model (a recoverability
|
|
26
|
+
matrix, the at-most-once-by-design rationale, the bounded-memory behaviour, and the client's
|
|
27
|
+
never-re-pay `.ref` recovery).
|
|
28
|
+
|
|
29
|
+
## [1.20.0] — 2026-06-11 — discovery hardening: conformance-locked, accurate timing, PipRail-attributed
|
|
30
|
+
|
|
31
|
+
A minor release focused on the discovery/registration subsystem — verified live against the real
|
|
32
|
+
402 Index + the deployed demo's wire, then locked as a contract. No payment-path change; the lazy-chunk
|
|
33
|
+
invariant holds.
|
|
34
|
+
|
|
35
|
+
### Changed — registration attribution is now ON by default (opt-out)
|
|
36
|
+
- `client.register()` / `register402Index()` now attribute the listing to PipRail by default: a
|
|
37
|
+
`via: '@piprail/sdk'` provenance field **plus** a tasteful `· Built with @piprail/sdk` suffix on the
|
|
38
|
+
**description** (the one field an index displays) — the same unobtrusive "Made with X" marker as the
|
|
39
|
+
OpenAPI `x-generator`. It's metadata only (never changes how a resource is paid, ranked, or found),
|
|
40
|
+
is **deduped** (never double-stamps a description already naming PipRail), never fabricates a missing
|
|
41
|
+
description, and is **length-guarded**. **Opt out with `attribution: false`.** (Was opt-in/off before
|
|
42
|
+
— this is the one default change in the release; everything else is additive.)
|
|
43
|
+
- New pure exports: **`appendAttribution(description)`** and **`REGISTER_ATTRIBUTION`**.
|
|
44
|
+
|
|
45
|
+
### Fixed — registration timing/visibility now matches reality
|
|
46
|
+
- The 402 Index caveat + register `detail` overstated the gate ("not searchable until approved"). Live
|
|
47
|
+
evidence (the demo is self-registered, `domain_verified: 0`, yet fully searchable) shows a self-
|
|
48
|
+
registered listing becomes searchable once it passes 402 Index's automated health + payment-validity
|
|
49
|
+
checks — no domain verification required. Domain verification is the **instant, guaranteed** path
|
|
50
|
+
(+ a verified badge). Wording corrected across `DIRECTORY_INFO`, the docs, and the llms files.
|
|
51
|
+
|
|
52
|
+
### Added — an x402 conformance contract (test)
|
|
53
|
+
- `test/discovery-conformance.test.ts` encodes, as executable predicates, the x402 v2 PaymentRequirements
|
|
54
|
+
envelope (CAIP-2 networks, atomic-unit string amounts, the EIP-712 domain on an `exact` rail) **and**
|
|
55
|
+
x402scan's `validateResource` gate (HTTPS · v2 · non-empty accepts · resolvable input schema · ≥1
|
|
56
|
+
Base/Solana rail), asserted against the live demo's captured wire and the SDK's own generated output —
|
|
57
|
+
so a regression that would make a PipRail endpoint un-listable fails CI.
|
|
58
|
+
|
|
7
59
|
## [1.19.0] — 2026-06-11 — gasless `exact` on 3 more chains (Monad · zkSync Era · Injective)
|
|
8
60
|
|
|
9
61
|
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
|
|
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
|
-
...
|
|
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
|
-
...
|
|
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
|
|
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
|
-
|
|
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") {
|
|
@@ -4205,14 +4215,23 @@ function createPaymentGate(options) {
|
|
|
4205
4215
|
};
|
|
4206
4216
|
}
|
|
4207
4217
|
const hasCustomStore = Boolean(options.isUsed || options.markUsed);
|
|
4208
|
-
const localUsed = /* @__PURE__ */ new
|
|
4218
|
+
const localUsed = /* @__PURE__ */ new Map();
|
|
4219
|
+
const replayWindowMs = maxTimeoutSeconds * 1e3;
|
|
4220
|
+
function pruneUsed(now) {
|
|
4221
|
+
for (const [key, expiry] of localUsed) {
|
|
4222
|
+
if (expiry > now) break;
|
|
4223
|
+
localUsed.delete(key);
|
|
4224
|
+
}
|
|
4225
|
+
}
|
|
4209
4226
|
async function claimTx(ref) {
|
|
4210
4227
|
if (hasCustomStore) {
|
|
4211
4228
|
return options.isUsed ? Boolean(await options.isUsed(ref)) : false;
|
|
4212
4229
|
}
|
|
4213
4230
|
const key = ref.toLowerCase();
|
|
4231
|
+
const now = Date.now();
|
|
4232
|
+
pruneUsed(now);
|
|
4214
4233
|
if (localUsed.has(key)) return true;
|
|
4215
|
-
localUsed.
|
|
4234
|
+
localUsed.set(key, now + replayWindowMs);
|
|
4216
4235
|
return false;
|
|
4217
4236
|
}
|
|
4218
4237
|
async function settleTx(ref, ok) {
|
|
@@ -4372,7 +4391,13 @@ function createPaymentGate(options) {
|
|
|
4372
4391
|
}
|
|
4373
4392
|
const ref = sig.payload.txHash;
|
|
4374
4393
|
if (await claimTx(ref)) return rejection("tx_already_used", `Proof ${ref} was already redeemed.`);
|
|
4375
|
-
|
|
4394
|
+
let result;
|
|
4395
|
+
try {
|
|
4396
|
+
result = await spec.net.verify(ref, buildAccept(spec, sig.payload.nonce));
|
|
4397
|
+
} catch (err) {
|
|
4398
|
+
await settleTx(ref, false);
|
|
4399
|
+
throw err;
|
|
4400
|
+
}
|
|
4376
4401
|
if (!result.ok) {
|
|
4377
4402
|
await settleTx(ref, false);
|
|
4378
4403
|
return rejection(result.error, result.detail);
|
|
@@ -4682,4 +4707,6 @@ async function deliverReceipt(receipt, options) {
|
|
|
4682
4707
|
|
|
4683
4708
|
|
|
4684
4709
|
|
|
4685
|
-
|
|
4710
|
+
|
|
4711
|
+
|
|
4712
|
+
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
|
-
*
|
|
4476
|
-
*
|
|
4477
|
-
*
|
|
4478
|
-
*
|
|
4479
|
-
*
|
|
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
|
-
*
|
|
5109
|
-
*
|
|
5110
|
-
*
|
|
5111
|
-
* `
|
|
5112
|
-
*
|
|
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
|
-
*
|
|
4476
|
-
*
|
|
4477
|
-
*
|
|
4478
|
-
*
|
|
4479
|
-
*
|
|
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
|
-
*
|
|
5109
|
-
*
|
|
5110
|
-
*
|
|
5111
|
-
* `
|
|
5112
|
-
*
|
|
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
|
|
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
|
-
...
|
|
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
|
-
...
|
|
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
|
|
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
|
-
|
|
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") {
|
|
@@ -4205,14 +4215,23 @@ function createPaymentGate(options) {
|
|
|
4205
4215
|
};
|
|
4206
4216
|
}
|
|
4207
4217
|
const hasCustomStore = Boolean(options.isUsed || options.markUsed);
|
|
4208
|
-
const localUsed = /* @__PURE__ */ new
|
|
4218
|
+
const localUsed = /* @__PURE__ */ new Map();
|
|
4219
|
+
const replayWindowMs = maxTimeoutSeconds * 1e3;
|
|
4220
|
+
function pruneUsed(now) {
|
|
4221
|
+
for (const [key, expiry] of localUsed) {
|
|
4222
|
+
if (expiry > now) break;
|
|
4223
|
+
localUsed.delete(key);
|
|
4224
|
+
}
|
|
4225
|
+
}
|
|
4209
4226
|
async function claimTx(ref) {
|
|
4210
4227
|
if (hasCustomStore) {
|
|
4211
4228
|
return options.isUsed ? Boolean(await options.isUsed(ref)) : false;
|
|
4212
4229
|
}
|
|
4213
4230
|
const key = ref.toLowerCase();
|
|
4231
|
+
const now = Date.now();
|
|
4232
|
+
pruneUsed(now);
|
|
4214
4233
|
if (localUsed.has(key)) return true;
|
|
4215
|
-
localUsed.
|
|
4234
|
+
localUsed.set(key, now + replayWindowMs);
|
|
4216
4235
|
return false;
|
|
4217
4236
|
}
|
|
4218
4237
|
async function settleTx(ref, ok) {
|
|
@@ -4372,7 +4391,13 @@ function createPaymentGate(options) {
|
|
|
4372
4391
|
}
|
|
4373
4392
|
const ref = sig.payload.txHash;
|
|
4374
4393
|
if (await claimTx(ref)) return rejection("tx_already_used", `Proof ${ref} was already redeemed.`);
|
|
4375
|
-
|
|
4394
|
+
let result;
|
|
4395
|
+
try {
|
|
4396
|
+
result = await spec.net.verify(ref, buildAccept(spec, sig.payload.nonce));
|
|
4397
|
+
} catch (err) {
|
|
4398
|
+
await settleTx(ref, false);
|
|
4399
|
+
throw err;
|
|
4400
|
+
}
|
|
4376
4401
|
if (!result.ok) {
|
|
4377
4402
|
await settleTx(ref, false);
|
|
4378
4403
|
return rejection(result.error, result.detail);
|
|
@@ -4629,6 +4654,7 @@ export {
|
|
|
4629
4654
|
PaymentTimeoutError,
|
|
4630
4655
|
PipRailClient,
|
|
4631
4656
|
PipRailError,
|
|
4657
|
+
REGISTER_ATTRIBUTION,
|
|
4632
4658
|
RecipientNotReadyError,
|
|
4633
4659
|
SettlementError,
|
|
4634
4660
|
UnknownTokenError,
|
|
@@ -4638,6 +4664,7 @@ export {
|
|
|
4638
4664
|
WrongFamilyError,
|
|
4639
4665
|
X402_EXACT_PERMIT2_PROXY,
|
|
4640
4666
|
agentGuide,
|
|
4667
|
+
appendAttribution,
|
|
4641
4668
|
buildBazaarExtension,
|
|
4642
4669
|
buildChallengeHeader,
|
|
4643
4670
|
buildExactAuthorization,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@piprail/sdk",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.20.1",
|
|
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",
|