@piprail/sdk 1.12.0 → 1.13.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 +33 -0
- package/README.md +21 -9
- package/dist/index.cjs +142 -99
- package/dist/index.d.cts +56 -7
- package/dist/index.d.ts +56 -7
- package/dist/index.js +114 -71
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,37 @@ 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.13.1] — 2026-06-10
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
- **`register()` visibility is now accurate for a verified domain.** 402 Index returns a structured
|
|
11
|
+
`service.status` — a register from a domain you've verified comes back `'active'`, so the outcome now
|
|
12
|
+
reports `visibility:'live'` instead of the conservative `'pending-review'` default (`decorateOutcome`
|
|
13
|
+
honours a visibility the adapter already set). The `detail` already surfaced 402 Index's own message;
|
|
14
|
+
now `visibility` and `detail` agree.
|
|
15
|
+
|
|
16
|
+
## [1.13.0] — 2026-06-10
|
|
17
|
+
|
|
18
|
+
### Added — gate `discovery` option (one flag → x402scan-listable)
|
|
19
|
+
- **`createPaymentGate`/`requirePayment` now take an opt-in `discovery` option** that emits an
|
|
20
|
+
`extensions.bazaar` block **in the 402 challenge itself** — so the gate alone satisfies x402scan's
|
|
21
|
+
mandatory input-schema check (no separately-served file needed). `discovery: true` for a no-input
|
|
22
|
+
GET, or a `DiscoveryDescriptor` (`{ method, queryParams, output }`). Omitting it leaves the challenge
|
|
23
|
+
byte-identical. New export `buildBazaarExtension` + the `DiscoveryDescriptor`/`BazaarExtension` types.
|
|
24
|
+
- `DomainClaim` now also surfaces `verificationToken`, and `verificationHash` is **always** populated —
|
|
25
|
+
from the API, or computed as `sha256(verificationToken)` — so an agent always has the exact bytes to serve.
|
|
26
|
+
|
|
27
|
+
### Fixed — conformance bug hunt (20-agent audit, every finding verified against the live API)
|
|
28
|
+
- **`hostOf` returned `''` for a bare `host:port`** (`new URL('x.com:8080')` parses the host as a scheme) —
|
|
29
|
+
`claimDomain`/`verifyDomain` now extract the host correctly.
|
|
30
|
+
- **`indexes.ts` base64 was Latin1-only** (`btoa`) — now UTF-8-safe, matching `x402.ts` (a non-ASCII SIWX
|
|
31
|
+
field could have thrown in the browser).
|
|
32
|
+
- **SIWX message** now reads `chainId` from `supportedChains[]` as a fallback (not only `info.chainId`),
|
|
33
|
+
so it always signs the correct `Chain ID`.
|
|
34
|
+
- Removed an invented `x-payment-info.bazaar:{discoverable:true}` marker from `buildOpenApi` (no index read it).
|
|
35
|
+
- Documented the caveat that the open indexes' agents are standard `exact` clients — advertise an `exact`
|
|
36
|
+
rail to be *payable*, not just listed (README + the `piprail_register` MCP tool).
|
|
37
|
+
|
|
7
38
|
## [1.12.0] — 2026-06-09
|
|
8
39
|
|
|
9
40
|
### Added — One-call domain verification (pending-review → searchable)
|
|
@@ -593,6 +624,8 @@ straight into your wallet. The API is small and self-contained.
|
|
|
593
624
|
to your wallet; PipRail never holds funds.
|
|
594
625
|
- `viem ^2.21` is a peer dependency. Node 20+ or a modern browser.
|
|
595
626
|
|
|
627
|
+
[1.13.1]: https://www.npmjs.com/package/@piprail/sdk
|
|
628
|
+
[1.13.0]: https://www.npmjs.com/package/@piprail/sdk
|
|
596
629
|
[1.12.0]: https://www.npmjs.com/package/@piprail/sdk
|
|
597
630
|
[1.11.0]: https://www.npmjs.com/package/@piprail/sdk
|
|
598
631
|
[1.10.0]: https://www.npmjs.com/package/@piprail/sdk
|
package/README.md
CHANGED
|
@@ -206,22 +206,34 @@ listing won't appear here, so don't read that absence as failure. `network` defa
|
|
|
206
206
|
chain); pass `'any'` for every chain, or a CAIP-2 id (`'eip155:8453'`). Slugs map to CAIP-2 via
|
|
207
207
|
`SLUG_TO_CAIP2`; an unresolved network is kept, never hidden.
|
|
208
208
|
|
|
209
|
-
**4) Make your endpoint self-describing**
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
listing accepted:
|
|
209
|
+
**4) Make your endpoint self-describing.** **x402scan REQUIRES an input schema or it won't list you.**
|
|
210
|
+
The simplest path: set the gate's `discovery` option — it emits an `extensions.bazaar` block **in the 402
|
|
211
|
+
itself**, so the challenge alone is x402scan-listable (no extra file to serve):
|
|
213
212
|
|
|
214
213
|
```ts
|
|
215
|
-
|
|
214
|
+
// `discovery: true` for a no-input GET, or describe the request:
|
|
215
|
+
const gate = createPaymentGate({
|
|
216
|
+
chain: 'base', token: 'USDC', amount: '0.05', payTo,
|
|
217
|
+
exact: { settle: { facilitator: 'https://facilitator.payai.network' } }, // be payable by exact clients (see caveat)
|
|
218
|
+
discovery: { method: 'GET', output: { type: 'json', example: { ok: true } } },
|
|
219
|
+
})
|
|
220
|
+
```
|
|
216
221
|
|
|
217
|
-
|
|
222
|
+
Optionally also serve the static discovery files (richer listings; OpenAPI carries the `x-generator`
|
|
223
|
+
attribution stamp) from your own origin — all pure, no I/O:
|
|
224
|
+
|
|
225
|
+
```ts
|
|
226
|
+
import { buildOpenApi, buildWellKnownX402, buildX402DnsTxt } from '@piprail/sdk'
|
|
218
227
|
const desc = await gate.describe('https://api.example.com/report')
|
|
219
|
-
const openapi = buildOpenApi({ origin: 'https://api.example.com', resources: [desc] })
|
|
220
|
-
|
|
221
|
-
const wellKnown = buildWellKnownX402({ resources: [desc] }) // serve at /.well-known/x402
|
|
228
|
+
const openapi = buildOpenApi({ origin: 'https://api.example.com', resources: [desc] }) // → /openapi.json
|
|
229
|
+
const wellKnown = buildWellKnownX402({ resources: [desc] }) // → /.well-known/x402
|
|
222
230
|
// buildX402DnsTxt(...) emits the _x402 DNS line too.
|
|
223
231
|
```
|
|
224
232
|
|
|
233
|
+
> **Caveat — be *payable*, not just listed.** The open indexes' agents are overwhelmingly standard
|
|
234
|
+
> `exact` clients; a default `onchain-proof`-only gate gets listed but they can't pay it. Advertise an
|
|
235
|
+
> `exact` rail (above) so a discovered resource is actually payable.
|
|
236
|
+
|
|
225
237
|
**Know each index before you call** — the facts are one import, `DIRECTORY_INFO`, and `register()`
|
|
226
238
|
projects them onto every outcome (`visibility` + `note`), so an agent never has to guess:
|
|
227
239
|
|
package/dist/index.cjs
CHANGED
|
@@ -1339,7 +1339,7 @@ function getDirectoryInfo(source) {
|
|
|
1339
1339
|
}
|
|
1340
1340
|
function decorateOutcome(o) {
|
|
1341
1341
|
const info = DIRECTORY_INFO[o.source];
|
|
1342
|
-
return { ...o, visibility: o.ok ? info.onSuccess : "not-listable", note: info.caveat };
|
|
1342
|
+
return { ...o, visibility: _nullishCoalesce(o.visibility, () => ( (o.ok ? info.onSuccess : "not-listable"))), note: info.caveat };
|
|
1343
1343
|
}
|
|
1344
1344
|
var BAZAAR_URL = "https://api.cdp.coinbase.com/platform/v2/x402/discovery/resources";
|
|
1345
1345
|
var INDEX402_SEARCH = "https://402index.io/api/v1/services";
|
|
@@ -1495,12 +1495,15 @@ async function register402Index(input) {
|
|
|
1495
1495
|
body: JSON.stringify(payload)
|
|
1496
1496
|
});
|
|
1497
1497
|
if (res.ok) {
|
|
1498
|
-
const
|
|
1498
|
+
const body = await res.json().catch(() => ({}));
|
|
1499
|
+
const msg = typeof body.message === "string" && body.message.length > 0 ? body.message : void 0;
|
|
1500
|
+
const live = _optionalChain([body, 'access', _8 => _8.service, 'optionalAccess', _9 => _9.status]) === "active";
|
|
1499
1501
|
return {
|
|
1500
1502
|
source: "402index",
|
|
1501
1503
|
ok: true,
|
|
1502
1504
|
status: res.status,
|
|
1503
|
-
|
|
1505
|
+
...live ? { visibility: "live" } : {},
|
|
1506
|
+
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).")))
|
|
1504
1507
|
};
|
|
1505
1508
|
}
|
|
1506
1509
|
const why = await readIndexError(res);
|
|
@@ -1514,14 +1517,6 @@ async function register402Index(input) {
|
|
|
1514
1517
|
return { source: "402index", ok: false, detail: errMsg(err) };
|
|
1515
1518
|
}
|
|
1516
1519
|
}
|
|
1517
|
-
async function readIndexMessage(res) {
|
|
1518
|
-
try {
|
|
1519
|
-
const body = await res.json();
|
|
1520
|
-
return typeof body.message === "string" && body.message.length > 0 ? body.message : void 0;
|
|
1521
|
-
} catch (e17) {
|
|
1522
|
-
return void 0;
|
|
1523
|
-
}
|
|
1524
|
-
}
|
|
1525
1520
|
async function readIndexError(res) {
|
|
1526
1521
|
try {
|
|
1527
1522
|
const body = await res.json();
|
|
@@ -1529,7 +1524,7 @@ async function readIndexError(res) {
|
|
|
1529
1524
|
(p) => typeof p === "string" && p.length > 0
|
|
1530
1525
|
);
|
|
1531
1526
|
return parts.length ? [...new Set(parts)].join(" \u2014 ") : void 0;
|
|
1532
|
-
} catch (
|
|
1527
|
+
} catch (e17) {
|
|
1533
1528
|
return void 0;
|
|
1534
1529
|
}
|
|
1535
1530
|
}
|
|
@@ -1593,11 +1588,14 @@ async function claim402IndexDomain(domainOrUrl, opts = {}) {
|
|
|
1593
1588
|
if (!res.ok) {
|
|
1594
1589
|
return { ok: false, domain, httpStatus: res.status, detail: _nullishCoalesce(pickString(body, "error", "detail", "message"), () => ( `402 Index claim returned HTTP ${res.status}.`)) };
|
|
1595
1590
|
}
|
|
1591
|
+
const verificationToken = pickString(body, "verification_token");
|
|
1592
|
+
const verificationHash = await _asyncNullishCoalesce(pickString(body, "verification_hash"), async () => ( (verificationToken ? await sha256Hex(verificationToken) : void 0)));
|
|
1596
1593
|
return {
|
|
1597
1594
|
ok: true,
|
|
1598
1595
|
domain,
|
|
1599
1596
|
httpStatus: res.status,
|
|
1600
|
-
...optionalString("verificationHash",
|
|
1597
|
+
...optionalString("verificationHash", verificationHash),
|
|
1598
|
+
...optionalString("verificationToken", verificationToken),
|
|
1601
1599
|
...optionalString("verificationUrl", pickString(body, "verification_url")),
|
|
1602
1600
|
...optionalString("instructions", pickString(body, "instructions"))
|
|
1603
1601
|
};
|
|
@@ -1605,6 +1603,10 @@ async function claim402IndexDomain(domainOrUrl, opts = {}) {
|
|
|
1605
1603
|
return { ok: false, domain, detail: errMsg(err) };
|
|
1606
1604
|
}
|
|
1607
1605
|
}
|
|
1606
|
+
async function sha256Hex(input) {
|
|
1607
|
+
const digest = await globalThis.crypto.subtle.digest("SHA-256", new TextEncoder().encode(input));
|
|
1608
|
+
return Array.from(new Uint8Array(digest)).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
1609
|
+
}
|
|
1608
1610
|
async function verify402IndexDomain(domainOrUrl) {
|
|
1609
1611
|
const domain = hostOf(domainOrUrl);
|
|
1610
1612
|
try {
|
|
@@ -1632,13 +1634,19 @@ async function readSiwxInfo(res) {
|
|
|
1632
1634
|
try {
|
|
1633
1635
|
const body = await res.json();
|
|
1634
1636
|
const ext = body.extensions;
|
|
1635
|
-
const siwx = _optionalChain([ext, 'optionalAccess',
|
|
1636
|
-
const info = _nullishCoalesce(_optionalChain([siwx, 'optionalAccess',
|
|
1637
|
+
const siwx = _optionalChain([ext, 'optionalAccess', _10 => _10["sign-in-with-x"]]);
|
|
1638
|
+
const info = _nullishCoalesce(_optionalChain([siwx, 'optionalAccess', _11 => _11.info]), () => ( siwx));
|
|
1639
|
+
if (info && info.chainId == null && Array.isArray(_optionalChain([siwx, 'optionalAccess', _12 => _12.supportedChains]))) {
|
|
1640
|
+
const evm = siwx.supportedChains.find(
|
|
1641
|
+
(c) => typeof _optionalChain([c, 'optionalAccess', _13 => _13.chainId]) === "string" && c.chainId.startsWith("eip155:")
|
|
1642
|
+
);
|
|
1643
|
+
if (evm && typeof evm.chainId === "string") info.chainId = evm.chainId;
|
|
1644
|
+
}
|
|
1637
1645
|
if (info && typeof info.domain === "string" && info.domain.length > 0 && typeof info.nonce === "string" && info.nonce.length > 0 && typeof info.uri === "string" && info.uri.length > 0) {
|
|
1638
1646
|
return info;
|
|
1639
1647
|
}
|
|
1640
1648
|
return null;
|
|
1641
|
-
} catch (
|
|
1649
|
+
} catch (e18) {
|
|
1642
1650
|
return null;
|
|
1643
1651
|
}
|
|
1644
1652
|
}
|
|
@@ -1686,7 +1694,7 @@ function mapRails(accepts) {
|
|
|
1686
1694
|
}
|
|
1687
1695
|
function matchesQuery(r, query) {
|
|
1688
1696
|
const q = query.toLowerCase();
|
|
1689
|
-
return r.resource.toLowerCase().includes(q) || (_nullishCoalesce(_optionalChain([r, 'access',
|
|
1697
|
+
return r.resource.toLowerCase().includes(q) || (_nullishCoalesce(_optionalChain([r, 'access', _14 => _14.name, 'optionalAccess', _15 => _15.toLowerCase, 'call', _16 => _16(), 'access', _17 => _17.includes, 'call', _18 => _18(q)]), () => ( false))) || (_nullishCoalesce(_optionalChain([r, 'access', _19 => _19.description, 'optionalAccess', _20 => _20.toLowerCase, 'call', _21 => _21(), 'access', _22 => _22.includes, 'call', _23 => _23(q)]), () => ( false)));
|
|
1690
1698
|
}
|
|
1691
1699
|
function pickString(o, ...keys) {
|
|
1692
1700
|
for (const k of keys) {
|
|
@@ -1717,8 +1725,9 @@ function firstArray(o, ...keys) {
|
|
|
1717
1725
|
}
|
|
1718
1726
|
function hostOf(url) {
|
|
1719
1727
|
try {
|
|
1720
|
-
|
|
1721
|
-
|
|
1728
|
+
const withScheme = /^[a-z][a-z0-9+.-]*:\/\//i.test(url) ? url : `https://${url}`;
|
|
1729
|
+
return new URL(withScheme).hostname || url;
|
|
1730
|
+
} catch (e19) {
|
|
1722
1731
|
return url;
|
|
1723
1732
|
}
|
|
1724
1733
|
}
|
|
@@ -1726,8 +1735,13 @@ function errMsg(err) {
|
|
|
1726
1735
|
return err instanceof Error ? err.message : String(err);
|
|
1727
1736
|
}
|
|
1728
1737
|
function encodeBase642(str) {
|
|
1729
|
-
if (typeof btoa === "function") return btoa(str);
|
|
1730
1738
|
if (typeof Buffer !== "undefined") return Buffer.from(str, "utf8").toString("base64");
|
|
1739
|
+
if (typeof btoa === "function" && typeof TextEncoder !== "undefined") {
|
|
1740
|
+
const bytes = new TextEncoder().encode(str);
|
|
1741
|
+
let binary = "";
|
|
1742
|
+
for (let i = 0; i < bytes.length; i++) binary += String.fromCharCode(bytes[i]);
|
|
1743
|
+
return btoa(binary);
|
|
1744
|
+
}
|
|
1731
1745
|
throw new Error("No base64 encoder available in this runtime.");
|
|
1732
1746
|
}
|
|
1733
1747
|
|
|
@@ -1824,7 +1838,7 @@ var SpendLedger = (_class = class {constructor() { _class.prototype.__init.call(
|
|
|
1824
1838
|
}
|
|
1825
1839
|
/** Running total (base units) already spent on this (network, asset). */
|
|
1826
1840
|
totalFor(network, asset) {
|
|
1827
|
-
return _nullishCoalesce(_optionalChain([this, 'access',
|
|
1841
|
+
return _nullishCoalesce(_optionalChain([this, 'access', _24 => _24.buckets, 'access', _25 => _25.get, 'call', _26 => _26(keyFor(network, asset)), 'optionalAccess', _27 => _27.total]), () => ( 0n));
|
|
1828
1842
|
}
|
|
1829
1843
|
/** An immutable snapshot of all spend so far. */
|
|
1830
1844
|
summary() {
|
|
@@ -1873,7 +1887,7 @@ var PipRailClient = (_class2 = class {
|
|
|
1873
1887
|
safeEmit(event) {
|
|
1874
1888
|
try {
|
|
1875
1889
|
this.onEvent(event);
|
|
1876
|
-
} catch (
|
|
1890
|
+
} catch (e20) {
|
|
1877
1891
|
}
|
|
1878
1892
|
}
|
|
1879
1893
|
/** Auto-mount the chain's driver, resolve the network, and bind the wallet — once. */
|
|
@@ -1898,7 +1912,7 @@ var PipRailClient = (_class2 = class {
|
|
|
1898
1912
|
* as-is) or a plain object (serialised as JSON).
|
|
1899
1913
|
*/
|
|
1900
1914
|
post(url, body, init) {
|
|
1901
|
-
const headers = new Headers(_optionalChain([init, 'optionalAccess',
|
|
1915
|
+
const headers = new Headers(_optionalChain([init, 'optionalAccess', _28 => _28.headers]));
|
|
1902
1916
|
let payload;
|
|
1903
1917
|
if (body === void 0 || body === null) {
|
|
1904
1918
|
payload = void 0;
|
|
@@ -1929,7 +1943,7 @@ var PipRailClient = (_class2 = class {
|
|
|
1929
1943
|
* "0.05 USDC on Base, within budget → pay it." No funds move.
|
|
1930
1944
|
*/
|
|
1931
1945
|
async quote(url, init) {
|
|
1932
|
-
const res = await fetch(url, { ..._nullishCoalesce(init, () => ( {})), method: _nullishCoalesce(_optionalChain([init, 'optionalAccess',
|
|
1946
|
+
const res = await fetch(url, { ..._nullishCoalesce(init, () => ( {})), method: _nullishCoalesce(_optionalChain([init, 'optionalAccess', _29 => _29.method]), () => ( "GET")) });
|
|
1933
1947
|
if (res.status !== 402) return null;
|
|
1934
1948
|
const { quote } = await this.resolveChallenge(url, res);
|
|
1935
1949
|
return quote;
|
|
@@ -1948,7 +1962,7 @@ var PipRailClient = (_class2 = class {
|
|
|
1948
1962
|
* on Tron, where a USD₮ transfer can cost real TRX.
|
|
1949
1963
|
*/
|
|
1950
1964
|
async estimateCost(url, init) {
|
|
1951
|
-
const res = await fetch(url, { ..._nullishCoalesce(init, () => ( {})), method: _nullishCoalesce(_optionalChain([init, 'optionalAccess',
|
|
1965
|
+
const res = await fetch(url, { ..._nullishCoalesce(init, () => ( {})), method: _nullishCoalesce(_optionalChain([init, 'optionalAccess', _30 => _30.method]), () => ( "GET")) });
|
|
1952
1966
|
if (res.status !== 402) return null;
|
|
1953
1967
|
const { net, accept, quote } = await this.resolveChallenge(url, res);
|
|
1954
1968
|
const cost = await net.estimateCost(accept);
|
|
@@ -1979,7 +1993,7 @@ var PipRailClient = (_class2 = class {
|
|
|
1979
1993
|
* the plan yourself. No funds move.
|
|
1980
1994
|
*/
|
|
1981
1995
|
async planPayment(url, init) {
|
|
1982
|
-
const res = await fetch(url, { ..._nullishCoalesce(init, () => ( {})), method: _nullishCoalesce(_optionalChain([init, 'optionalAccess',
|
|
1996
|
+
const res = await fetch(url, { ..._nullishCoalesce(init, () => ( {})), method: _nullishCoalesce(_optionalChain([init, 'optionalAccess', _31 => _31.method]), () => ( "GET")) });
|
|
1983
1997
|
if (res.status !== 402) return null;
|
|
1984
1998
|
const challenge = await parseChallenge(res);
|
|
1985
1999
|
if (!challenge) {
|
|
@@ -2146,7 +2160,7 @@ var PipRailClient = (_class2 = class {
|
|
|
2146
2160
|
* streams throw `NonReplayableBodyError`.
|
|
2147
2161
|
*/
|
|
2148
2162
|
async fetch(url, init) {
|
|
2149
|
-
const body = _optionalChain([init, 'optionalAccess',
|
|
2163
|
+
const body = _optionalChain([init, 'optionalAccess', _32 => _32.body]);
|
|
2150
2164
|
if (body !== void 0 && body !== null && !isReplayableBodyInit(body)) {
|
|
2151
2165
|
throw new (0, _chunkMDLZJGLYcjs.NonReplayableBodyError)(
|
|
2152
2166
|
"fetch(): init.body is not replayable. Pass a string, FormData, URLSearchParams, ArrayBuffer, or Blob \u2014 not a ReadableStream."
|
|
@@ -2158,7 +2172,7 @@ var PipRailClient = (_class2 = class {
|
|
|
2158
2172
|
const { net, wallet, challenge } = resolved;
|
|
2159
2173
|
let accept = resolved.accept;
|
|
2160
2174
|
let quote = resolved.quote;
|
|
2161
|
-
const autoRoute = _nullishCoalesce(_nullishCoalesce(_optionalChain([init, 'optionalAccess',
|
|
2175
|
+
const autoRoute = _nullishCoalesce(_nullishCoalesce(_optionalChain([init, 'optionalAccess', _33 => _33.autoRoute]), () => ( this.opts.autoRoute)), () => ( false));
|
|
2162
2176
|
if (autoRoute) {
|
|
2163
2177
|
const plan = await this.planFromChallenge(net, wallet, challenge, url);
|
|
2164
2178
|
if (!plan.best) {
|
|
@@ -2320,8 +2334,8 @@ var PipRailClient = (_class2 = class {
|
|
|
2320
2334
|
}
|
|
2321
2335
|
const amountBase = BigInt(accept.amount);
|
|
2322
2336
|
const described = net.describeAsset(accept.asset);
|
|
2323
|
-
const decimals = _nullishCoalesce(_optionalChain([described, 'optionalAccess',
|
|
2324
|
-
const symbol = _nullishCoalesce(_optionalChain([described, 'optionalAccess',
|
|
2337
|
+
const decimals = _nullishCoalesce(_optionalChain([described, 'optionalAccess', _34 => _34.decimals]), () => ( accept.extra.decimals));
|
|
2338
|
+
const symbol = _nullishCoalesce(_optionalChain([described, 'optionalAccess', _35 => _35.symbol]), () => ( accept.extra.symbol));
|
|
2325
2339
|
const amountFormatted = _chunkMDLZJGLYcjs.formatUnits.call(void 0, amountBase, decimals);
|
|
2326
2340
|
const intent = {
|
|
2327
2341
|
host: hostOf2(url),
|
|
@@ -2430,7 +2444,7 @@ var PipRailClient = (_class2 = class {
|
|
|
2430
2444
|
accepted: accept,
|
|
2431
2445
|
payload: { nonce: accept.extra.nonce, txHash: ref }
|
|
2432
2446
|
};
|
|
2433
|
-
const headers = new Headers(_optionalChain([originalInit, 'optionalAccess',
|
|
2447
|
+
const headers = new Headers(_optionalChain([originalInit, 'optionalAccess', _36 => _36.headers]));
|
|
2434
2448
|
headers.set(HEADER_SIGNATURE, buildSignatureHeader(signature));
|
|
2435
2449
|
let lastResponse = null;
|
|
2436
2450
|
let lastReason = null;
|
|
@@ -2445,7 +2459,7 @@ var PipRailClient = (_class2 = class {
|
|
|
2445
2459
|
() => timeoutController.abort(),
|
|
2446
2460
|
this.retryTimeoutMs
|
|
2447
2461
|
);
|
|
2448
|
-
const signal = _optionalChain([originalInit, 'optionalAccess',
|
|
2462
|
+
const signal = _optionalChain([originalInit, 'optionalAccess', _37 => _37.signal]) && typeof AbortSignal.any === "function" ? AbortSignal.any([timeoutController.signal, originalInit.signal]) : timeoutController.signal;
|
|
2449
2463
|
try {
|
|
2450
2464
|
lastResponse = await fetch(url, {
|
|
2451
2465
|
..._nullishCoalesce(originalInit, () => ( {})),
|
|
@@ -2485,7 +2499,7 @@ var PipRailClient = (_class2 = class {
|
|
|
2485
2499
|
function safeBig(s) {
|
|
2486
2500
|
try {
|
|
2487
2501
|
return BigInt(s);
|
|
2488
|
-
} catch (
|
|
2502
|
+
} catch (e21) {
|
|
2489
2503
|
return 0n;
|
|
2490
2504
|
}
|
|
2491
2505
|
}
|
|
@@ -2518,10 +2532,10 @@ function buildFundingHint(options, chainLabel) {
|
|
|
2518
2532
|
return `Couldn't fully read your wallet on ${chainLabel} (RPC throttled) \u2014 retry; you may already be able to pay ${target.quote.amountFormatted} ${sym}.`;
|
|
2519
2533
|
}
|
|
2520
2534
|
const parts = [];
|
|
2521
|
-
if (target.blockers.includes("INSUFFICIENT_TOKEN") && _optionalChain([target, 'access',
|
|
2535
|
+
if (target.blockers.includes("INSUFFICIENT_TOKEN") && _optionalChain([target, 'access', _38 => _38.shortfall, 'optionalAccess', _39 => _39.token])) {
|
|
2522
2536
|
parts.push(`top up ${target.shortfall.token} ${sym}`);
|
|
2523
2537
|
}
|
|
2524
|
-
if (target.blockers.includes("INSUFFICIENT_GAS") && _optionalChain([target, 'access',
|
|
2538
|
+
if (target.blockers.includes("INSUFFICIENT_GAS") && _optionalChain([target, 'access', _40 => _40.shortfall, 'optionalAccess', _41 => _41.native])) {
|
|
2525
2539
|
parts.push(`add ~${target.shortfall.native} ${target.cost.feeSymbol} for gas`);
|
|
2526
2540
|
}
|
|
2527
2541
|
return parts.length ? `Can't settle on ${chainLabel}: ${parts.join(" and ")} (to pay ${target.quote.amountFormatted} ${sym}).` : `Can't settle on ${chainLabel} for ${target.quote.amountFormatted} ${sym}.`;
|
|
@@ -2535,7 +2549,7 @@ async function planAcross(clients, url, init) {
|
|
|
2535
2549
|
const status = best ? "ready" : options.some((o) => o.state === "unknown") ? "unknown" : "blocked";
|
|
2536
2550
|
return {
|
|
2537
2551
|
url,
|
|
2538
|
-
network: _nullishCoalesce(_optionalChain([best, 'optionalAccess',
|
|
2552
|
+
network: _nullishCoalesce(_optionalChain([best, 'optionalAccess', _42 => _42.accept, 'access', _43 => _43.network]), () => ( live[0].network)),
|
|
2539
2553
|
status,
|
|
2540
2554
|
payable: best !== null,
|
|
2541
2555
|
best,
|
|
@@ -2551,7 +2565,7 @@ function railOnNetwork(rail, matches) {
|
|
|
2551
2565
|
function hostOf2(url) {
|
|
2552
2566
|
try {
|
|
2553
2567
|
return new URL(url).hostname;
|
|
2554
|
-
} catch (
|
|
2568
|
+
} catch (e22) {
|
|
2555
2569
|
return url;
|
|
2556
2570
|
}
|
|
2557
2571
|
}
|
|
@@ -2568,8 +2582,8 @@ function isReplayableBodyInit(value) {
|
|
|
2568
2582
|
async function readInvalidReason(response) {
|
|
2569
2583
|
try {
|
|
2570
2584
|
const body = await response.clone().json();
|
|
2571
|
-
const ext = _optionalChain([body, 'optionalAccess',
|
|
2572
|
-
const piprail = _optionalChain([ext, 'optionalAccess',
|
|
2585
|
+
const ext = _optionalChain([body, 'optionalAccess', _44 => _44.extensions]);
|
|
2586
|
+
const piprail = _optionalChain([ext, 'optionalAccess', _45 => _45.piprail]);
|
|
2573
2587
|
if (piprail && typeof piprail.code === "string") {
|
|
2574
2588
|
return {
|
|
2575
2589
|
error: piprail.code,
|
|
@@ -2582,7 +2596,7 @@ async function readInvalidReason(response) {
|
|
|
2582
2596
|
detail: typeof body.detail === "string" ? body.detail : ""
|
|
2583
2597
|
};
|
|
2584
2598
|
}
|
|
2585
|
-
} catch (
|
|
2599
|
+
} catch (e23) {
|
|
2586
2600
|
}
|
|
2587
2601
|
return null;
|
|
2588
2602
|
}
|
|
@@ -2593,7 +2607,7 @@ async function readBody(res) {
|
|
|
2593
2607
|
if (!text) return null;
|
|
2594
2608
|
try {
|
|
2595
2609
|
return JSON.parse(text);
|
|
2596
|
-
} catch (
|
|
2610
|
+
} catch (e24) {
|
|
2597
2611
|
return text;
|
|
2598
2612
|
}
|
|
2599
2613
|
}
|
|
@@ -2773,7 +2787,7 @@ function paymentTools(client) {
|
|
|
2773
2787
|
},
|
|
2774
2788
|
{
|
|
2775
2789
|
name: "piprail_register",
|
|
2776
|
-
description: "List an x402 payment-gated resource YOU run on the open indexes so other agents can discover it. Default target is 402 Index \u2014 no auth, no signature, no payment; a self-registered listing is pending review (verify your domain on 402index.io for instant approval). Returns one outcome per index ({ source, ok, detail, visibility, note }); a step the chain can't satisfy comes back ok:false with the reason. Moves no funds; nothing is PipRail-hosted.",
|
|
2790
|
+
description: "List an x402 payment-gated resource YOU run on the open indexes so other agents can discover it. Default target is 402 Index \u2014 no auth, no signature, no payment; a self-registered listing is pending review (verify your domain on 402index.io for instant approval). Returns one outcome per index ({ source, ok, detail, visibility, note }); a step the chain can't satisfy comes back ok:false with the reason. Moves no funds; nothing is PipRail-hosted. NOTE: index/agent payers are overwhelmingly standard `exact` clients \u2014 a default onchain-proof-only gate gets listed but they cannot pay it, so add an `exact` rail (and set the gate's `discovery` option, required for x402scan) to be usefully discoverable AND payable.",
|
|
2777
2791
|
annotations: {
|
|
2778
2792
|
title: "Register an x402 endpoint",
|
|
2779
2793
|
readOnlyHint: false,
|
|
@@ -2807,6 +2821,87 @@ function paymentTools(client) {
|
|
|
2807
2821
|
];
|
|
2808
2822
|
}
|
|
2809
2823
|
|
|
2824
|
+
// src/discovery.ts
|
|
2825
|
+
var GENERATOR = "@piprail/sdk \xB7 https://piprail.com";
|
|
2826
|
+
function buildBazaarExtension(descriptor = {}) {
|
|
2827
|
+
const method = (_nullishCoalesce(descriptor.method, () => ( "GET"))).toUpperCase();
|
|
2828
|
+
const queryParams = _nullishCoalesce(descriptor.queryParams, () => ( {}));
|
|
2829
|
+
return {
|
|
2830
|
+
info: {
|
|
2831
|
+
input: { type: "http", method, queryParams },
|
|
2832
|
+
output: _nullishCoalesce(descriptor.output, () => ( { type: "json" }))
|
|
2833
|
+
},
|
|
2834
|
+
schema: {
|
|
2835
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
2836
|
+
type: "object",
|
|
2837
|
+
properties: {
|
|
2838
|
+
input: {
|
|
2839
|
+
type: "object",
|
|
2840
|
+
properties: {
|
|
2841
|
+
type: { type: "string", const: "http" },
|
|
2842
|
+
method: { type: "string", enum: ["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD"] },
|
|
2843
|
+
queryParams: { type: "object", properties: queryParams, additionalProperties: false }
|
|
2844
|
+
},
|
|
2845
|
+
required: ["type", "method"],
|
|
2846
|
+
additionalProperties: false
|
|
2847
|
+
}
|
|
2848
|
+
},
|
|
2849
|
+
required: ["input"]
|
|
2850
|
+
}
|
|
2851
|
+
};
|
|
2852
|
+
}
|
|
2853
|
+
function pathOf(url) {
|
|
2854
|
+
try {
|
|
2855
|
+
return new URL(url).pathname || "/";
|
|
2856
|
+
} catch (e25) {
|
|
2857
|
+
return url.startsWith("/") ? url : `/${url}`;
|
|
2858
|
+
}
|
|
2859
|
+
}
|
|
2860
|
+
function buildOpenApi(input) {
|
|
2861
|
+
const paths = {};
|
|
2862
|
+
for (const r of input.resources) {
|
|
2863
|
+
const path = pathOf(r.url);
|
|
2864
|
+
const method = (_nullishCoalesce(r.method, () => ( "GET"))).toLowerCase();
|
|
2865
|
+
const op = {
|
|
2866
|
+
...r.description ? { summary: r.description } : {},
|
|
2867
|
+
responses: {
|
|
2868
|
+
"200": { description: "Paid \u2014 the resource." },
|
|
2869
|
+
"402": { description: "Payment required (x402)." }
|
|
2870
|
+
},
|
|
2871
|
+
"x-payment-info": {
|
|
2872
|
+
x402Version: 2,
|
|
2873
|
+
accepts: r.accepts
|
|
2874
|
+
}
|
|
2875
|
+
};
|
|
2876
|
+
paths[path] = { ..._nullishCoalesce(paths[path], () => ( {})), [method]: op };
|
|
2877
|
+
}
|
|
2878
|
+
return {
|
|
2879
|
+
openapi: "3.1.0",
|
|
2880
|
+
info: { title: _nullishCoalesce(input.title, () => ( "PipRail x402 resources")), version: _nullishCoalesce(input.version, () => ( "1.0.0")) },
|
|
2881
|
+
servers: [{ url: input.origin }],
|
|
2882
|
+
paths,
|
|
2883
|
+
// "Built with @piprail/sdk" — default on (opt out with attribution:false). At the
|
|
2884
|
+
// document ROOT so `info` stays exactly { title, version }.
|
|
2885
|
+
...input.attribution === false ? {} : { "x-generator": GENERATOR },
|
|
2886
|
+
...input.ownershipProofs && input.ownershipProofs.length > 0 ? { "x-agentcash-provenance": { ownershipProofs: input.ownershipProofs } } : {}
|
|
2887
|
+
};
|
|
2888
|
+
}
|
|
2889
|
+
function buildWellKnownX402(input) {
|
|
2890
|
+
return {
|
|
2891
|
+
version: 1,
|
|
2892
|
+
resources: input.resources.map((r) => r.url),
|
|
2893
|
+
...input.ownershipProofs && input.ownershipProofs.length > 0 ? { ownershipProofs: input.ownershipProofs } : {}
|
|
2894
|
+
};
|
|
2895
|
+
}
|
|
2896
|
+
function buildX402DnsTxt(input) {
|
|
2897
|
+
const descriptor = input.descriptor ? `descriptor=${input.descriptor};` : "";
|
|
2898
|
+
return {
|
|
2899
|
+
name: `_x402.${input.host}`,
|
|
2900
|
+
type: "TXT",
|
|
2901
|
+
value: `v=x4021;${descriptor}url=${input.discoveryUrl}`
|
|
2902
|
+
};
|
|
2903
|
+
}
|
|
2904
|
+
|
|
2810
2905
|
// src/facilitator.ts
|
|
2811
2906
|
function safeStringify(value) {
|
|
2812
2907
|
return JSON.stringify(value, (_k, v) => typeof v === "bigint" ? v.toString() : v);
|
|
@@ -3055,6 +3150,8 @@ function createPaymentGate(options) {
|
|
|
3055
3150
|
async function makeChallenge(resourceUrl, opts) {
|
|
3056
3151
|
const specs = await ready();
|
|
3057
3152
|
const nonce = genNonce();
|
|
3153
|
+
const bazaar = options.discovery ? { bazaar: buildBazaarExtension(options.discovery === true ? {} : options.discovery) } : void 0;
|
|
3154
|
+
const extensions = { ...bazaar, ..._optionalChain([opts, 'optionalAccess', _46 => _46.extensions]) };
|
|
3058
3155
|
const challenge2 = {
|
|
3059
3156
|
x402Version: 2,
|
|
3060
3157
|
resource: {
|
|
@@ -3062,8 +3159,8 @@ function createPaymentGate(options) {
|
|
|
3062
3159
|
...options.description ? { description: options.description } : {}
|
|
3063
3160
|
},
|
|
3064
3161
|
accepts: buildAccepts(specs, nonce),
|
|
3065
|
-
..._optionalChain([opts, 'optionalAccess',
|
|
3066
|
-
...
|
|
3162
|
+
..._optionalChain([opts, 'optionalAccess', _47 => _47.error]) ? { error: opts.error } : {},
|
|
3163
|
+
...Object.keys(extensions).length > 0 ? { extensions } : {}
|
|
3067
3164
|
};
|
|
3068
3165
|
return { challenge: challenge2, requiredHeader: buildChallengeHeader(challenge2) };
|
|
3069
3166
|
}
|
|
@@ -3250,60 +3347,6 @@ function normaliseHeader(value) {
|
|
|
3250
3347
|
return value;
|
|
3251
3348
|
}
|
|
3252
3349
|
|
|
3253
|
-
// src/discovery.ts
|
|
3254
|
-
var GENERATOR = "@piprail/sdk \xB7 https://piprail.com";
|
|
3255
|
-
function pathOf(url) {
|
|
3256
|
-
try {
|
|
3257
|
-
return new URL(url).pathname || "/";
|
|
3258
|
-
} catch (e28) {
|
|
3259
|
-
return url.startsWith("/") ? url : `/${url}`;
|
|
3260
|
-
}
|
|
3261
|
-
}
|
|
3262
|
-
function buildOpenApi(input) {
|
|
3263
|
-
const paths = {};
|
|
3264
|
-
for (const r of input.resources) {
|
|
3265
|
-
const path = pathOf(r.url);
|
|
3266
|
-
const method = (_nullishCoalesce(r.method, () => ( "GET"))).toLowerCase();
|
|
3267
|
-
const op = {
|
|
3268
|
-
...r.description ? { summary: r.description } : {},
|
|
3269
|
-
responses: {
|
|
3270
|
-
"200": { description: "Paid \u2014 the resource." },
|
|
3271
|
-
"402": { description: "Payment required (x402)." }
|
|
3272
|
-
},
|
|
3273
|
-
"x-payment-info": {
|
|
3274
|
-
x402Version: 2,
|
|
3275
|
-
accepts: r.accepts,
|
|
3276
|
-
bazaar: { discoverable: true }
|
|
3277
|
-
}
|
|
3278
|
-
};
|
|
3279
|
-
paths[path] = { ..._nullishCoalesce(paths[path], () => ( {})), [method]: op };
|
|
3280
|
-
}
|
|
3281
|
-
return {
|
|
3282
|
-
openapi: "3.1.0",
|
|
3283
|
-
info: { title: _nullishCoalesce(input.title, () => ( "PipRail x402 resources")), version: _nullishCoalesce(input.version, () => ( "1.0.0")) },
|
|
3284
|
-
servers: [{ url: input.origin }],
|
|
3285
|
-
paths,
|
|
3286
|
-
// "Built with @piprail/sdk" — default on (opt out with attribution:false). At the
|
|
3287
|
-
// document ROOT so `info` stays exactly { title, version }.
|
|
3288
|
-
...input.attribution === false ? {} : { "x-generator": GENERATOR },
|
|
3289
|
-
...input.ownershipProofs && input.ownershipProofs.length > 0 ? { "x-agentcash-provenance": { ownershipProofs: input.ownershipProofs } } : {}
|
|
3290
|
-
};
|
|
3291
|
-
}
|
|
3292
|
-
function buildWellKnownX402(input) {
|
|
3293
|
-
return {
|
|
3294
|
-
version: 1,
|
|
3295
|
-
resources: input.resources.map((r) => r.url),
|
|
3296
|
-
...input.ownershipProofs && input.ownershipProofs.length > 0 ? { ownershipProofs: input.ownershipProofs } : {}
|
|
3297
|
-
};
|
|
3298
|
-
}
|
|
3299
|
-
function buildX402DnsTxt(input) {
|
|
3300
|
-
const descriptor = input.descriptor ? `descriptor=${input.descriptor};` : "";
|
|
3301
|
-
return {
|
|
3302
|
-
name: `_x402.${input.host}`,
|
|
3303
|
-
type: "TXT",
|
|
3304
|
-
value: `v=x4021;${descriptor}url=${input.discoveryUrl}`
|
|
3305
|
-
};
|
|
3306
|
-
}
|
|
3307
3350
|
|
|
3308
3351
|
|
|
3309
3352
|
|
|
@@ -3367,4 +3410,4 @@ function buildX402DnsTxt(input) {
|
|
|
3367
3410
|
|
|
3368
3411
|
|
|
3369
3412
|
|
|
3370
|
-
exports.CHAINS = CHAINS; exports.ConfirmationTimeoutError = _chunkMDLZJGLYcjs.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 = _chunkMDLZJGLYcjs.InsufficientFundsError; exports.InvalidEnvelopeError = _chunkMDLZJGLYcjs.InvalidEnvelopeError; exports.MaxRetriesExceededError = _chunkMDLZJGLYcjs.MaxRetriesExceededError; exports.MissingDriverError = _chunkMDLZJGLYcjs.MissingDriverError; exports.NoCompatibleAcceptError = _chunkMDLZJGLYcjs.NoCompatibleAcceptError; exports.NonReplayableBodyError = _chunkMDLZJGLYcjs.NonReplayableBodyError; exports.PaymentDeclinedError = _chunkMDLZJGLYcjs.PaymentDeclinedError; exports.PaymentTimeoutError = _chunkMDLZJGLYcjs.PaymentTimeoutError; exports.PipRailClient = PipRailClient; exports.PipRailError = _chunkMDLZJGLYcjs.PipRailError; exports.RecipientNotReadyError = _chunkMDLZJGLYcjs.RecipientNotReadyError; exports.SettlementError = _chunkMDLZJGLYcjs.SettlementError; exports.UnknownTokenError = _chunkMDLZJGLYcjs.UnknownTokenError; exports.UnsupportedNetworkError = _chunkMDLZJGLYcjs.UnsupportedNetworkError; exports.WrongChainError = _chunkMDLZJGLYcjs.WrongChainError; exports.WrongFamilyError = _chunkMDLZJGLYcjs.WrongFamilyError; exports.buildChallengeHeader = buildChallengeHeader; exports.buildExactAuthorization = buildExactAuthorization; exports.buildOpenApi = buildOpenApi; exports.buildReceiptHeader = buildReceiptHeader; exports.buildSignatureHeader = buildSignatureHeader; exports.buildWellKnownX402 = buildWellKnownX402; exports.buildX402DnsTxt = buildX402DnsTxt; exports.chainIdForExactNetwork = chainIdForExactNetwork; exports.claim402IndexDomain = claim402IndexDomain; exports.createPaymentGate = createPaymentGate; exports.decorateOutcome = decorateOutcome; exports.eip3009Abi = eip3009Abi; exports.encodeXPaymentHeader = encodeXPaymentHeader; exports.evaluatePolicy = evaluatePolicy; exports.getDirectoryInfo = getDirectoryInfo; exports.normalizeNetwork = normalizeNetwork; exports.parseChallenge = parseChallenge; exports.parseExactPaymentHeader = parseExactPaymentHeader; exports.parseExactRequirements = parseExactRequirements; exports.parseReceipt = parseReceipt; 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.toInsufficientFundsError = _chunkMDLZJGLYcjs.toInsufficientFundsError; exports.toInvalidBody = toInvalidBody; exports.verify402IndexDomain = verify402IndexDomain;
|
|
3413
|
+
exports.CHAINS = CHAINS; exports.ConfirmationTimeoutError = _chunkMDLZJGLYcjs.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 = _chunkMDLZJGLYcjs.InsufficientFundsError; exports.InvalidEnvelopeError = _chunkMDLZJGLYcjs.InvalidEnvelopeError; exports.MaxRetriesExceededError = _chunkMDLZJGLYcjs.MaxRetriesExceededError; exports.MissingDriverError = _chunkMDLZJGLYcjs.MissingDriverError; exports.NoCompatibleAcceptError = _chunkMDLZJGLYcjs.NoCompatibleAcceptError; exports.NonReplayableBodyError = _chunkMDLZJGLYcjs.NonReplayableBodyError; exports.PaymentDeclinedError = _chunkMDLZJGLYcjs.PaymentDeclinedError; exports.PaymentTimeoutError = _chunkMDLZJGLYcjs.PaymentTimeoutError; exports.PipRailClient = PipRailClient; exports.PipRailError = _chunkMDLZJGLYcjs.PipRailError; exports.RecipientNotReadyError = _chunkMDLZJGLYcjs.RecipientNotReadyError; exports.SettlementError = _chunkMDLZJGLYcjs.SettlementError; exports.UnknownTokenError = _chunkMDLZJGLYcjs.UnknownTokenError; exports.UnsupportedNetworkError = _chunkMDLZJGLYcjs.UnsupportedNetworkError; exports.WrongChainError = _chunkMDLZJGLYcjs.WrongChainError; exports.WrongFamilyError = _chunkMDLZJGLYcjs.WrongFamilyError; exports.buildBazaarExtension = buildBazaarExtension; exports.buildChallengeHeader = buildChallengeHeader; exports.buildExactAuthorization = buildExactAuthorization; exports.buildOpenApi = buildOpenApi; exports.buildReceiptHeader = buildReceiptHeader; exports.buildSignatureHeader = buildSignatureHeader; exports.buildWellKnownX402 = buildWellKnownX402; exports.buildX402DnsTxt = buildX402DnsTxt; exports.chainIdForExactNetwork = chainIdForExactNetwork; exports.claim402IndexDomain = claim402IndexDomain; exports.createPaymentGate = createPaymentGate; exports.decorateOutcome = decorateOutcome; exports.eip3009Abi = eip3009Abi; exports.encodeXPaymentHeader = encodeXPaymentHeader; exports.evaluatePolicy = evaluatePolicy; exports.getDirectoryInfo = getDirectoryInfo; exports.normalizeNetwork = normalizeNetwork; exports.parseChallenge = parseChallenge; exports.parseExactPaymentHeader = parseExactPaymentHeader; exports.parseExactRequirements = parseExactRequirements; exports.parseReceipt = parseReceipt; 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.toInsufficientFundsError = _chunkMDLZJGLYcjs.toInsufficientFundsError; exports.toInvalidBody = toInvalidBody; exports.verify402IndexDomain = verify402IndexDomain;
|
package/dist/index.d.cts
CHANGED
|
@@ -4370,9 +4370,14 @@ declare function registerX402Scan(input: {
|
|
|
4370
4370
|
interface DomainClaim {
|
|
4371
4371
|
ok: boolean;
|
|
4372
4372
|
domain: string;
|
|
4373
|
-
/**
|
|
4373
|
+
/** The exact text to serve as the ENTIRE body of `verificationUrl` — this is what
|
|
4374
|
+
* 402 Index fetches and checks (the SHA-256 of the token). Always populated on
|
|
4375
|
+
* success: read from the response, or computed as `sha256(verificationToken)` if
|
|
4376
|
+
* the API returns only the token. Serve THIS. */
|
|
4374
4377
|
verificationHash?: string;
|
|
4375
|
-
/**
|
|
4378
|
+
/** The raw 64-hex token 402 Index issued (the preimage of `verificationHash`). */
|
|
4379
|
+
verificationToken?: string;
|
|
4380
|
+
/** Where to serve `verificationHash` — your `https://<domain>/.well-known/402index-verify.txt`. */
|
|
4376
4381
|
verificationUrl?: string;
|
|
4377
4382
|
/** 402 Index's own human instructions. */
|
|
4378
4383
|
instructions?: string;
|
|
@@ -5129,10 +5134,6 @@ interface OpenApiOperation {
|
|
|
5129
5134
|
'x-payment-info': {
|
|
5130
5135
|
x402Version: 2;
|
|
5131
5136
|
accepts: PaymentRail[];
|
|
5132
|
-
/** Bazaar-style input schema marker so a strict index doesn't "skip" the op. */
|
|
5133
|
-
bazaar: {
|
|
5134
|
-
discoverable: true;
|
|
5135
|
-
};
|
|
5136
5137
|
};
|
|
5137
5138
|
}
|
|
5138
5139
|
/** x402scan's legacy origin file (`/.well-known/x402`). */
|
|
@@ -5141,6 +5142,46 @@ interface WellKnownX402 {
|
|
|
5141
5142
|
resources: string[];
|
|
5142
5143
|
ownershipProofs?: string[];
|
|
5143
5144
|
}
|
|
5145
|
+
/**
|
|
5146
|
+
* Describes a resource's INPUT for discovery. The open indexes that REQUIRE an
|
|
5147
|
+
* input schema (x402scan rejects a listing without one) read this from a
|
|
5148
|
+
* `extensions.bazaar` block. Pass it to a gate's `discovery` option (emits the
|
|
5149
|
+
* block in the 402 challenge) or build it directly with {@link buildBazaarExtension}.
|
|
5150
|
+
*/
|
|
5151
|
+
interface DiscoveryDescriptor {
|
|
5152
|
+
/** HTTP method the resource answers. Default `'GET'`. */
|
|
5153
|
+
method?: string;
|
|
5154
|
+
/** Query params the resource reads, as a JSON-Schema `properties` object
|
|
5155
|
+
* (name → schema). Default `{}` — a no-input GET. */
|
|
5156
|
+
queryParams?: Record<string, unknown>;
|
|
5157
|
+
/** Optional output hint (shape/example) for a richer listing. */
|
|
5158
|
+
output?: {
|
|
5159
|
+
type?: string;
|
|
5160
|
+
example?: unknown;
|
|
5161
|
+
};
|
|
5162
|
+
}
|
|
5163
|
+
/** The `extensions.bazaar` discovery block (the x402 "bazaar" convention the open
|
|
5164
|
+
* indexes parse: `info.input` describes the request, `schema` is its JSON Schema). */
|
|
5165
|
+
interface BazaarExtension {
|
|
5166
|
+
info: {
|
|
5167
|
+
input: {
|
|
5168
|
+
type: 'http';
|
|
5169
|
+
method: string;
|
|
5170
|
+
queryParams: Record<string, unknown>;
|
|
5171
|
+
};
|
|
5172
|
+
output?: {
|
|
5173
|
+
type?: string;
|
|
5174
|
+
example?: unknown;
|
|
5175
|
+
};
|
|
5176
|
+
};
|
|
5177
|
+
schema: Record<string, unknown>;
|
|
5178
|
+
}
|
|
5179
|
+
/**
|
|
5180
|
+
* Build the `extensions.bazaar` block that satisfies x402scan's mandatory input-schema
|
|
5181
|
+
* check, from a {@link DiscoveryDescriptor}. Pure. Defaults to a no-input GET — the
|
|
5182
|
+
* minimal shape a live x402scan listing accepts.
|
|
5183
|
+
*/
|
|
5184
|
+
declare function buildBazaarExtension(descriptor?: DiscoveryDescriptor): BazaarExtension;
|
|
5144
5185
|
/** The `_x402` DNS TXT pointer record (experimental draft). */
|
|
5145
5186
|
interface X402DnsRecord {
|
|
5146
5187
|
name: string;
|
|
@@ -5292,6 +5333,14 @@ interface RequirePaymentOptions {
|
|
|
5292
5333
|
* Omit to keep the gate exactly as today (`onchain-proof` only).
|
|
5293
5334
|
*/
|
|
5294
5335
|
exact?: ExactRailOption;
|
|
5336
|
+
/**
|
|
5337
|
+
* Make this gate's 402 self-describing for the open indexes — **x402scan REQUIRES
|
|
5338
|
+
* an input schema or it won't list the resource.** Set `true` for a no-input GET,
|
|
5339
|
+
* or pass a {@link DiscoveryDescriptor} to describe the request. Emits an
|
|
5340
|
+
* `extensions.bazaar` block in the 402 challenge. Opt-in; omitting it leaves the
|
|
5341
|
+
* challenge byte-identical to before.
|
|
5342
|
+
*/
|
|
5343
|
+
discovery?: boolean | DiscoveryDescriptor;
|
|
5295
5344
|
}
|
|
5296
5345
|
type VerifyPaymentResult = {
|
|
5297
5346
|
kind: 'paid';
|
|
@@ -5898,4 +5947,4 @@ declare function readExactDomain(publicClient: PublicClient, asset: string): Pro
|
|
|
5898
5947
|
version: string;
|
|
5899
5948
|
} | null>;
|
|
5900
5949
|
|
|
5901
|
-
export { type AcceptOption, type AddressId, type AgentTool, type AlgorandToken, type AptosToken, type AssetId, type BuildExactParams, CHAINS, type Caip2, type ChainFamily, type ChainInput, type ChainName, type ChainPreset, type ChainSelector, type ConfirmInfo, ConfirmationTimeoutError, type CostEstimate, DIRECTORY_INFO, type DirectoryInfo, type DiscoverOptions, type DiscoveredRail, type DiscoveredResource, type DiscoverySigner, type DiscoverySource, type DomainClaim, type DomainVerification, EIP3009_TYPES, EXACT_NETWORK_SLUGS, type EvmToken, type ExactAccept, type ExactAuthorization, type ExactAuthorizationWire, type ExactPaymentPayload, 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, type ParsedExactPayment, type PayBlocker, type PayOption, type PayWarning, PaymentDeclinedError, type PaymentDriver, type PaymentGate, type PaymentIntent, type PaymentPlan, type PaymentPolicy, type PaymentRail, PaymentTimeoutError, PipRailClient, type PipRailClientOptions, type PipRailCostQuote, PipRailError, type PipRailEvent, type PipRailQuote, type PolicyDecision, RecipientNotReadyError, type RecipientReason, type RegisterInput, type RegisterOptions, type RegisterOutcome, type RequirePaymentOptions, type ResolveOptions, type ResolvedChain, type ResolvedNetwork, type ResolvedToken, type ResourceDescription, type SearchOpenIndexesOptions, type SettleViaFacilitatorInput, SettlementError, type SolanaToken, type SpendAssetTotal, type SpendRecord, type SpendSummary, type StellarToken, type SuiToken, type TokenInfo, type TokenInput, type TonToken, type ToolAnnotations, type TronToken, UnknownTokenError, UnsupportedNetworkError, 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, type XrplToken, buildChallengeHeader, buildExactAuthorization, buildOpenApi, buildReceiptHeader, buildSignatureHeader, buildWellKnownX402, buildX402DnsTxt, chainIdForExactNetwork, claim402IndexDomain, createPaymentGate, decorateOutcome, eip3009Abi, encodeXPaymentHeader, evaluatePolicy, getDirectoryInfo, normalizeNetwork, parseChallenge, parseExactPaymentHeader, parseExactRequirements, parseReceipt, parseSignatureHeader, paymentTools, pickAccept, planAcross, readExactDomain, register402Index, registerDriver, registerX402Scan, requirePayment, resolveChain, searchOpenIndexes, settleViaFacilitator, toInsufficientFundsError, toInvalidBody, verify402IndexDomain };
|
|
5950
|
+
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 ConfirmInfo, ConfirmationTimeoutError, type CostEstimate, DIRECTORY_INFO, 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 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, type ParsedExactPayment, type PayBlocker, type PayOption, type PayWarning, PaymentDeclinedError, type PaymentDriver, type PaymentGate, type PaymentIntent, type PaymentPlan, type PaymentPolicy, type PaymentRail, PaymentTimeoutError, PipRailClient, type PipRailClientOptions, type PipRailCostQuote, PipRailError, type PipRailEvent, type PipRailQuote, type PolicyDecision, RecipientNotReadyError, type RecipientReason, type RegisterInput, type RegisterOptions, type RegisterOutcome, type RequirePaymentOptions, type ResolveOptions, type ResolvedChain, type ResolvedNetwork, type ResolvedToken, type ResourceDescription, type SearchOpenIndexesOptions, type SettleViaFacilitatorInput, SettlementError, type SolanaToken, type SpendAssetTotal, type SpendRecord, type SpendSummary, type StellarToken, type SuiToken, type TokenInfo, type TokenInput, type TonToken, type ToolAnnotations, type TronToken, UnknownTokenError, UnsupportedNetworkError, 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, type XrplToken, buildBazaarExtension, buildChallengeHeader, buildExactAuthorization, buildOpenApi, buildReceiptHeader, buildSignatureHeader, buildWellKnownX402, buildX402DnsTxt, chainIdForExactNetwork, claim402IndexDomain, createPaymentGate, decorateOutcome, eip3009Abi, encodeXPaymentHeader, evaluatePolicy, getDirectoryInfo, normalizeNetwork, parseChallenge, parseExactPaymentHeader, parseExactRequirements, parseReceipt, parseSignatureHeader, paymentTools, pickAccept, planAcross, readExactDomain, register402Index, registerDriver, registerX402Scan, requirePayment, resolveChain, searchOpenIndexes, settleViaFacilitator, toInsufficientFundsError, toInvalidBody, verify402IndexDomain };
|
package/dist/index.d.ts
CHANGED
|
@@ -4370,9 +4370,14 @@ declare function registerX402Scan(input: {
|
|
|
4370
4370
|
interface DomainClaim {
|
|
4371
4371
|
ok: boolean;
|
|
4372
4372
|
domain: string;
|
|
4373
|
-
/**
|
|
4373
|
+
/** The exact text to serve as the ENTIRE body of `verificationUrl` — this is what
|
|
4374
|
+
* 402 Index fetches and checks (the SHA-256 of the token). Always populated on
|
|
4375
|
+
* success: read from the response, or computed as `sha256(verificationToken)` if
|
|
4376
|
+
* the API returns only the token. Serve THIS. */
|
|
4374
4377
|
verificationHash?: string;
|
|
4375
|
-
/**
|
|
4378
|
+
/** The raw 64-hex token 402 Index issued (the preimage of `verificationHash`). */
|
|
4379
|
+
verificationToken?: string;
|
|
4380
|
+
/** Where to serve `verificationHash` — your `https://<domain>/.well-known/402index-verify.txt`. */
|
|
4376
4381
|
verificationUrl?: string;
|
|
4377
4382
|
/** 402 Index's own human instructions. */
|
|
4378
4383
|
instructions?: string;
|
|
@@ -5129,10 +5134,6 @@ interface OpenApiOperation {
|
|
|
5129
5134
|
'x-payment-info': {
|
|
5130
5135
|
x402Version: 2;
|
|
5131
5136
|
accepts: PaymentRail[];
|
|
5132
|
-
/** Bazaar-style input schema marker so a strict index doesn't "skip" the op. */
|
|
5133
|
-
bazaar: {
|
|
5134
|
-
discoverable: true;
|
|
5135
|
-
};
|
|
5136
5137
|
};
|
|
5137
5138
|
}
|
|
5138
5139
|
/** x402scan's legacy origin file (`/.well-known/x402`). */
|
|
@@ -5141,6 +5142,46 @@ interface WellKnownX402 {
|
|
|
5141
5142
|
resources: string[];
|
|
5142
5143
|
ownershipProofs?: string[];
|
|
5143
5144
|
}
|
|
5145
|
+
/**
|
|
5146
|
+
* Describes a resource's INPUT for discovery. The open indexes that REQUIRE an
|
|
5147
|
+
* input schema (x402scan rejects a listing without one) read this from a
|
|
5148
|
+
* `extensions.bazaar` block. Pass it to a gate's `discovery` option (emits the
|
|
5149
|
+
* block in the 402 challenge) or build it directly with {@link buildBazaarExtension}.
|
|
5150
|
+
*/
|
|
5151
|
+
interface DiscoveryDescriptor {
|
|
5152
|
+
/** HTTP method the resource answers. Default `'GET'`. */
|
|
5153
|
+
method?: string;
|
|
5154
|
+
/** Query params the resource reads, as a JSON-Schema `properties` object
|
|
5155
|
+
* (name → schema). Default `{}` — a no-input GET. */
|
|
5156
|
+
queryParams?: Record<string, unknown>;
|
|
5157
|
+
/** Optional output hint (shape/example) for a richer listing. */
|
|
5158
|
+
output?: {
|
|
5159
|
+
type?: string;
|
|
5160
|
+
example?: unknown;
|
|
5161
|
+
};
|
|
5162
|
+
}
|
|
5163
|
+
/** The `extensions.bazaar` discovery block (the x402 "bazaar" convention the open
|
|
5164
|
+
* indexes parse: `info.input` describes the request, `schema` is its JSON Schema). */
|
|
5165
|
+
interface BazaarExtension {
|
|
5166
|
+
info: {
|
|
5167
|
+
input: {
|
|
5168
|
+
type: 'http';
|
|
5169
|
+
method: string;
|
|
5170
|
+
queryParams: Record<string, unknown>;
|
|
5171
|
+
};
|
|
5172
|
+
output?: {
|
|
5173
|
+
type?: string;
|
|
5174
|
+
example?: unknown;
|
|
5175
|
+
};
|
|
5176
|
+
};
|
|
5177
|
+
schema: Record<string, unknown>;
|
|
5178
|
+
}
|
|
5179
|
+
/**
|
|
5180
|
+
* Build the `extensions.bazaar` block that satisfies x402scan's mandatory input-schema
|
|
5181
|
+
* check, from a {@link DiscoveryDescriptor}. Pure. Defaults to a no-input GET — the
|
|
5182
|
+
* minimal shape a live x402scan listing accepts.
|
|
5183
|
+
*/
|
|
5184
|
+
declare function buildBazaarExtension(descriptor?: DiscoveryDescriptor): BazaarExtension;
|
|
5144
5185
|
/** The `_x402` DNS TXT pointer record (experimental draft). */
|
|
5145
5186
|
interface X402DnsRecord {
|
|
5146
5187
|
name: string;
|
|
@@ -5292,6 +5333,14 @@ interface RequirePaymentOptions {
|
|
|
5292
5333
|
* Omit to keep the gate exactly as today (`onchain-proof` only).
|
|
5293
5334
|
*/
|
|
5294
5335
|
exact?: ExactRailOption;
|
|
5336
|
+
/**
|
|
5337
|
+
* Make this gate's 402 self-describing for the open indexes — **x402scan REQUIRES
|
|
5338
|
+
* an input schema or it won't list the resource.** Set `true` for a no-input GET,
|
|
5339
|
+
* or pass a {@link DiscoveryDescriptor} to describe the request. Emits an
|
|
5340
|
+
* `extensions.bazaar` block in the 402 challenge. Opt-in; omitting it leaves the
|
|
5341
|
+
* challenge byte-identical to before.
|
|
5342
|
+
*/
|
|
5343
|
+
discovery?: boolean | DiscoveryDescriptor;
|
|
5295
5344
|
}
|
|
5296
5345
|
type VerifyPaymentResult = {
|
|
5297
5346
|
kind: 'paid';
|
|
@@ -5898,4 +5947,4 @@ declare function readExactDomain(publicClient: PublicClient, asset: string): Pro
|
|
|
5898
5947
|
version: string;
|
|
5899
5948
|
} | null>;
|
|
5900
5949
|
|
|
5901
|
-
export { type AcceptOption, type AddressId, type AgentTool, type AlgorandToken, type AptosToken, type AssetId, type BuildExactParams, CHAINS, type Caip2, type ChainFamily, type ChainInput, type ChainName, type ChainPreset, type ChainSelector, type ConfirmInfo, ConfirmationTimeoutError, type CostEstimate, DIRECTORY_INFO, type DirectoryInfo, type DiscoverOptions, type DiscoveredRail, type DiscoveredResource, type DiscoverySigner, type DiscoverySource, type DomainClaim, type DomainVerification, EIP3009_TYPES, EXACT_NETWORK_SLUGS, type EvmToken, type ExactAccept, type ExactAuthorization, type ExactAuthorizationWire, type ExactPaymentPayload, 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, type ParsedExactPayment, type PayBlocker, type PayOption, type PayWarning, PaymentDeclinedError, type PaymentDriver, type PaymentGate, type PaymentIntent, type PaymentPlan, type PaymentPolicy, type PaymentRail, PaymentTimeoutError, PipRailClient, type PipRailClientOptions, type PipRailCostQuote, PipRailError, type PipRailEvent, type PipRailQuote, type PolicyDecision, RecipientNotReadyError, type RecipientReason, type RegisterInput, type RegisterOptions, type RegisterOutcome, type RequirePaymentOptions, type ResolveOptions, type ResolvedChain, type ResolvedNetwork, type ResolvedToken, type ResourceDescription, type SearchOpenIndexesOptions, type SettleViaFacilitatorInput, SettlementError, type SolanaToken, type SpendAssetTotal, type SpendRecord, type SpendSummary, type StellarToken, type SuiToken, type TokenInfo, type TokenInput, type TonToken, type ToolAnnotations, type TronToken, UnknownTokenError, UnsupportedNetworkError, 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, type XrplToken, buildChallengeHeader, buildExactAuthorization, buildOpenApi, buildReceiptHeader, buildSignatureHeader, buildWellKnownX402, buildX402DnsTxt, chainIdForExactNetwork, claim402IndexDomain, createPaymentGate, decorateOutcome, eip3009Abi, encodeXPaymentHeader, evaluatePolicy, getDirectoryInfo, normalizeNetwork, parseChallenge, parseExactPaymentHeader, parseExactRequirements, parseReceipt, parseSignatureHeader, paymentTools, pickAccept, planAcross, readExactDomain, register402Index, registerDriver, registerX402Scan, requirePayment, resolveChain, searchOpenIndexes, settleViaFacilitator, toInsufficientFundsError, toInvalidBody, verify402IndexDomain };
|
|
5950
|
+
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 ConfirmInfo, ConfirmationTimeoutError, type CostEstimate, DIRECTORY_INFO, 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 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, type ParsedExactPayment, type PayBlocker, type PayOption, type PayWarning, PaymentDeclinedError, type PaymentDriver, type PaymentGate, type PaymentIntent, type PaymentPlan, type PaymentPolicy, type PaymentRail, PaymentTimeoutError, PipRailClient, type PipRailClientOptions, type PipRailCostQuote, PipRailError, type PipRailEvent, type PipRailQuote, type PolicyDecision, RecipientNotReadyError, type RecipientReason, type RegisterInput, type RegisterOptions, type RegisterOutcome, type RequirePaymentOptions, type ResolveOptions, type ResolvedChain, type ResolvedNetwork, type ResolvedToken, type ResourceDescription, type SearchOpenIndexesOptions, type SettleViaFacilitatorInput, SettlementError, type SolanaToken, type SpendAssetTotal, type SpendRecord, type SpendSummary, type StellarToken, type SuiToken, type TokenInfo, type TokenInput, type TonToken, type ToolAnnotations, type TronToken, UnknownTokenError, UnsupportedNetworkError, 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, type XrplToken, buildBazaarExtension, buildChallengeHeader, buildExactAuthorization, buildOpenApi, buildReceiptHeader, buildSignatureHeader, buildWellKnownX402, buildX402DnsTxt, chainIdForExactNetwork, claim402IndexDomain, createPaymentGate, decorateOutcome, eip3009Abi, encodeXPaymentHeader, evaluatePolicy, getDirectoryInfo, normalizeNetwork, parseChallenge, parseExactPaymentHeader, parseExactRequirements, parseReceipt, parseSignatureHeader, paymentTools, pickAccept, planAcross, readExactDomain, register402Index, registerDriver, registerX402Scan, requirePayment, resolveChain, searchOpenIndexes, settleViaFacilitator, toInsufficientFundsError, toInvalidBody, verify402IndexDomain };
|
package/dist/index.js
CHANGED
|
@@ -1339,7 +1339,7 @@ function getDirectoryInfo(source) {
|
|
|
1339
1339
|
}
|
|
1340
1340
|
function decorateOutcome(o) {
|
|
1341
1341
|
const info = DIRECTORY_INFO[o.source];
|
|
1342
|
-
return { ...o, visibility: o.ok ? info.onSuccess : "not-listable", note: info.caveat };
|
|
1342
|
+
return { ...o, visibility: o.visibility ?? (o.ok ? info.onSuccess : "not-listable"), note: info.caveat };
|
|
1343
1343
|
}
|
|
1344
1344
|
var BAZAAR_URL = "https://api.cdp.coinbase.com/platform/v2/x402/discovery/resources";
|
|
1345
1345
|
var INDEX402_SEARCH = "https://402index.io/api/v1/services";
|
|
@@ -1495,12 +1495,15 @@ async function register402Index(input) {
|
|
|
1495
1495
|
body: JSON.stringify(payload)
|
|
1496
1496
|
});
|
|
1497
1497
|
if (res.ok) {
|
|
1498
|
-
const
|
|
1498
|
+
const body = await res.json().catch(() => ({}));
|
|
1499
|
+
const msg = typeof body.message === "string" && body.message.length > 0 ? body.message : void 0;
|
|
1500
|
+
const live = body.service?.status === "active";
|
|
1499
1501
|
return {
|
|
1500
1502
|
source: "402index",
|
|
1501
1503
|
ok: true,
|
|
1502
1504
|
status: res.status,
|
|
1503
|
-
|
|
1505
|
+
...live ? { visibility: "live" } : {},
|
|
1506
|
+
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).")
|
|
1504
1507
|
};
|
|
1505
1508
|
}
|
|
1506
1509
|
const why = await readIndexError(res);
|
|
@@ -1514,14 +1517,6 @@ async function register402Index(input) {
|
|
|
1514
1517
|
return { source: "402index", ok: false, detail: errMsg(err) };
|
|
1515
1518
|
}
|
|
1516
1519
|
}
|
|
1517
|
-
async function readIndexMessage(res) {
|
|
1518
|
-
try {
|
|
1519
|
-
const body = await res.json();
|
|
1520
|
-
return typeof body.message === "string" && body.message.length > 0 ? body.message : void 0;
|
|
1521
|
-
} catch {
|
|
1522
|
-
return void 0;
|
|
1523
|
-
}
|
|
1524
|
-
}
|
|
1525
1520
|
async function readIndexError(res) {
|
|
1526
1521
|
try {
|
|
1527
1522
|
const body = await res.json();
|
|
@@ -1593,11 +1588,14 @@ async function claim402IndexDomain(domainOrUrl, opts = {}) {
|
|
|
1593
1588
|
if (!res.ok) {
|
|
1594
1589
|
return { ok: false, domain, httpStatus: res.status, detail: pickString(body, "error", "detail", "message") ?? `402 Index claim returned HTTP ${res.status}.` };
|
|
1595
1590
|
}
|
|
1591
|
+
const verificationToken = pickString(body, "verification_token");
|
|
1592
|
+
const verificationHash = pickString(body, "verification_hash") ?? (verificationToken ? await sha256Hex(verificationToken) : void 0);
|
|
1596
1593
|
return {
|
|
1597
1594
|
ok: true,
|
|
1598
1595
|
domain,
|
|
1599
1596
|
httpStatus: res.status,
|
|
1600
|
-
...optionalString("verificationHash",
|
|
1597
|
+
...optionalString("verificationHash", verificationHash),
|
|
1598
|
+
...optionalString("verificationToken", verificationToken),
|
|
1601
1599
|
...optionalString("verificationUrl", pickString(body, "verification_url")),
|
|
1602
1600
|
...optionalString("instructions", pickString(body, "instructions"))
|
|
1603
1601
|
};
|
|
@@ -1605,6 +1603,10 @@ async function claim402IndexDomain(domainOrUrl, opts = {}) {
|
|
|
1605
1603
|
return { ok: false, domain, detail: errMsg(err) };
|
|
1606
1604
|
}
|
|
1607
1605
|
}
|
|
1606
|
+
async function sha256Hex(input) {
|
|
1607
|
+
const digest = await globalThis.crypto.subtle.digest("SHA-256", new TextEncoder().encode(input));
|
|
1608
|
+
return Array.from(new Uint8Array(digest)).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
1609
|
+
}
|
|
1608
1610
|
async function verify402IndexDomain(domainOrUrl) {
|
|
1609
1611
|
const domain = hostOf(domainOrUrl);
|
|
1610
1612
|
try {
|
|
@@ -1634,6 +1636,12 @@ async function readSiwxInfo(res) {
|
|
|
1634
1636
|
const ext = body.extensions;
|
|
1635
1637
|
const siwx = ext?.["sign-in-with-x"];
|
|
1636
1638
|
const info = siwx?.info ?? siwx;
|
|
1639
|
+
if (info && info.chainId == null && Array.isArray(siwx?.supportedChains)) {
|
|
1640
|
+
const evm = siwx.supportedChains.find(
|
|
1641
|
+
(c) => typeof c?.chainId === "string" && c.chainId.startsWith("eip155:")
|
|
1642
|
+
);
|
|
1643
|
+
if (evm && typeof evm.chainId === "string") info.chainId = evm.chainId;
|
|
1644
|
+
}
|
|
1637
1645
|
if (info && typeof info.domain === "string" && info.domain.length > 0 && typeof info.nonce === "string" && info.nonce.length > 0 && typeof info.uri === "string" && info.uri.length > 0) {
|
|
1638
1646
|
return info;
|
|
1639
1647
|
}
|
|
@@ -1717,7 +1725,8 @@ function firstArray(o, ...keys) {
|
|
|
1717
1725
|
}
|
|
1718
1726
|
function hostOf(url) {
|
|
1719
1727
|
try {
|
|
1720
|
-
|
|
1728
|
+
const withScheme = /^[a-z][a-z0-9+.-]*:\/\//i.test(url) ? url : `https://${url}`;
|
|
1729
|
+
return new URL(withScheme).hostname || url;
|
|
1721
1730
|
} catch {
|
|
1722
1731
|
return url;
|
|
1723
1732
|
}
|
|
@@ -1726,8 +1735,13 @@ function errMsg(err) {
|
|
|
1726
1735
|
return err instanceof Error ? err.message : String(err);
|
|
1727
1736
|
}
|
|
1728
1737
|
function encodeBase642(str) {
|
|
1729
|
-
if (typeof btoa === "function") return btoa(str);
|
|
1730
1738
|
if (typeof Buffer !== "undefined") return Buffer.from(str, "utf8").toString("base64");
|
|
1739
|
+
if (typeof btoa === "function" && typeof TextEncoder !== "undefined") {
|
|
1740
|
+
const bytes = new TextEncoder().encode(str);
|
|
1741
|
+
let binary = "";
|
|
1742
|
+
for (let i = 0; i < bytes.length; i++) binary += String.fromCharCode(bytes[i]);
|
|
1743
|
+
return btoa(binary);
|
|
1744
|
+
}
|
|
1731
1745
|
throw new Error("No base64 encoder available in this runtime.");
|
|
1732
1746
|
}
|
|
1733
1747
|
|
|
@@ -2773,7 +2787,7 @@ function paymentTools(client) {
|
|
|
2773
2787
|
},
|
|
2774
2788
|
{
|
|
2775
2789
|
name: "piprail_register",
|
|
2776
|
-
description: "List an x402 payment-gated resource YOU run on the open indexes so other agents can discover it. Default target is 402 Index \u2014 no auth, no signature, no payment; a self-registered listing is pending review (verify your domain on 402index.io for instant approval). Returns one outcome per index ({ source, ok, detail, visibility, note }); a step the chain can't satisfy comes back ok:false with the reason. Moves no funds; nothing is PipRail-hosted.",
|
|
2790
|
+
description: "List an x402 payment-gated resource YOU run on the open indexes so other agents can discover it. Default target is 402 Index \u2014 no auth, no signature, no payment; a self-registered listing is pending review (verify your domain on 402index.io for instant approval). Returns one outcome per index ({ source, ok, detail, visibility, note }); a step the chain can't satisfy comes back ok:false with the reason. Moves no funds; nothing is PipRail-hosted. NOTE: index/agent payers are overwhelmingly standard `exact` clients \u2014 a default onchain-proof-only gate gets listed but they cannot pay it, so add an `exact` rail (and set the gate's `discovery` option, required for x402scan) to be usefully discoverable AND payable.",
|
|
2777
2791
|
annotations: {
|
|
2778
2792
|
title: "Register an x402 endpoint",
|
|
2779
2793
|
readOnlyHint: false,
|
|
@@ -2807,6 +2821,87 @@ function paymentTools(client) {
|
|
|
2807
2821
|
];
|
|
2808
2822
|
}
|
|
2809
2823
|
|
|
2824
|
+
// src/discovery.ts
|
|
2825
|
+
var GENERATOR = "@piprail/sdk \xB7 https://piprail.com";
|
|
2826
|
+
function buildBazaarExtension(descriptor = {}) {
|
|
2827
|
+
const method = (descriptor.method ?? "GET").toUpperCase();
|
|
2828
|
+
const queryParams = descriptor.queryParams ?? {};
|
|
2829
|
+
return {
|
|
2830
|
+
info: {
|
|
2831
|
+
input: { type: "http", method, queryParams },
|
|
2832
|
+
output: descriptor.output ?? { type: "json" }
|
|
2833
|
+
},
|
|
2834
|
+
schema: {
|
|
2835
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
2836
|
+
type: "object",
|
|
2837
|
+
properties: {
|
|
2838
|
+
input: {
|
|
2839
|
+
type: "object",
|
|
2840
|
+
properties: {
|
|
2841
|
+
type: { type: "string", const: "http" },
|
|
2842
|
+
method: { type: "string", enum: ["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD"] },
|
|
2843
|
+
queryParams: { type: "object", properties: queryParams, additionalProperties: false }
|
|
2844
|
+
},
|
|
2845
|
+
required: ["type", "method"],
|
|
2846
|
+
additionalProperties: false
|
|
2847
|
+
}
|
|
2848
|
+
},
|
|
2849
|
+
required: ["input"]
|
|
2850
|
+
}
|
|
2851
|
+
};
|
|
2852
|
+
}
|
|
2853
|
+
function pathOf(url) {
|
|
2854
|
+
try {
|
|
2855
|
+
return new URL(url).pathname || "/";
|
|
2856
|
+
} catch {
|
|
2857
|
+
return url.startsWith("/") ? url : `/${url}`;
|
|
2858
|
+
}
|
|
2859
|
+
}
|
|
2860
|
+
function buildOpenApi(input) {
|
|
2861
|
+
const paths = {};
|
|
2862
|
+
for (const r of input.resources) {
|
|
2863
|
+
const path = pathOf(r.url);
|
|
2864
|
+
const method = (r.method ?? "GET").toLowerCase();
|
|
2865
|
+
const op = {
|
|
2866
|
+
...r.description ? { summary: r.description } : {},
|
|
2867
|
+
responses: {
|
|
2868
|
+
"200": { description: "Paid \u2014 the resource." },
|
|
2869
|
+
"402": { description: "Payment required (x402)." }
|
|
2870
|
+
},
|
|
2871
|
+
"x-payment-info": {
|
|
2872
|
+
x402Version: 2,
|
|
2873
|
+
accepts: r.accepts
|
|
2874
|
+
}
|
|
2875
|
+
};
|
|
2876
|
+
paths[path] = { ...paths[path] ?? {}, [method]: op };
|
|
2877
|
+
}
|
|
2878
|
+
return {
|
|
2879
|
+
openapi: "3.1.0",
|
|
2880
|
+
info: { title: input.title ?? "PipRail x402 resources", version: input.version ?? "1.0.0" },
|
|
2881
|
+
servers: [{ url: input.origin }],
|
|
2882
|
+
paths,
|
|
2883
|
+
// "Built with @piprail/sdk" — default on (opt out with attribution:false). At the
|
|
2884
|
+
// document ROOT so `info` stays exactly { title, version }.
|
|
2885
|
+
...input.attribution === false ? {} : { "x-generator": GENERATOR },
|
|
2886
|
+
...input.ownershipProofs && input.ownershipProofs.length > 0 ? { "x-agentcash-provenance": { ownershipProofs: input.ownershipProofs } } : {}
|
|
2887
|
+
};
|
|
2888
|
+
}
|
|
2889
|
+
function buildWellKnownX402(input) {
|
|
2890
|
+
return {
|
|
2891
|
+
version: 1,
|
|
2892
|
+
resources: input.resources.map((r) => r.url),
|
|
2893
|
+
...input.ownershipProofs && input.ownershipProofs.length > 0 ? { ownershipProofs: input.ownershipProofs } : {}
|
|
2894
|
+
};
|
|
2895
|
+
}
|
|
2896
|
+
function buildX402DnsTxt(input) {
|
|
2897
|
+
const descriptor = input.descriptor ? `descriptor=${input.descriptor};` : "";
|
|
2898
|
+
return {
|
|
2899
|
+
name: `_x402.${input.host}`,
|
|
2900
|
+
type: "TXT",
|
|
2901
|
+
value: `v=x4021;${descriptor}url=${input.discoveryUrl}`
|
|
2902
|
+
};
|
|
2903
|
+
}
|
|
2904
|
+
|
|
2810
2905
|
// src/facilitator.ts
|
|
2811
2906
|
function safeStringify(value) {
|
|
2812
2907
|
return JSON.stringify(value, (_k, v) => typeof v === "bigint" ? v.toString() : v);
|
|
@@ -3055,6 +3150,8 @@ function createPaymentGate(options) {
|
|
|
3055
3150
|
async function makeChallenge(resourceUrl, opts) {
|
|
3056
3151
|
const specs = await ready();
|
|
3057
3152
|
const nonce = genNonce();
|
|
3153
|
+
const bazaar = options.discovery ? { bazaar: buildBazaarExtension(options.discovery === true ? {} : options.discovery) } : void 0;
|
|
3154
|
+
const extensions = { ...bazaar, ...opts?.extensions };
|
|
3058
3155
|
const challenge2 = {
|
|
3059
3156
|
x402Version: 2,
|
|
3060
3157
|
resource: {
|
|
@@ -3063,7 +3160,7 @@ function createPaymentGate(options) {
|
|
|
3063
3160
|
},
|
|
3064
3161
|
accepts: buildAccepts(specs, nonce),
|
|
3065
3162
|
...opts?.error ? { error: opts.error } : {},
|
|
3066
|
-
...
|
|
3163
|
+
...Object.keys(extensions).length > 0 ? { extensions } : {}
|
|
3067
3164
|
};
|
|
3068
3165
|
return { challenge: challenge2, requiredHeader: buildChallengeHeader(challenge2) };
|
|
3069
3166
|
}
|
|
@@ -3249,61 +3346,6 @@ function normaliseHeader(value) {
|
|
|
3249
3346
|
if (Array.isArray(value)) return value[0];
|
|
3250
3347
|
return value;
|
|
3251
3348
|
}
|
|
3252
|
-
|
|
3253
|
-
// src/discovery.ts
|
|
3254
|
-
var GENERATOR = "@piprail/sdk \xB7 https://piprail.com";
|
|
3255
|
-
function pathOf(url) {
|
|
3256
|
-
try {
|
|
3257
|
-
return new URL(url).pathname || "/";
|
|
3258
|
-
} catch {
|
|
3259
|
-
return url.startsWith("/") ? url : `/${url}`;
|
|
3260
|
-
}
|
|
3261
|
-
}
|
|
3262
|
-
function buildOpenApi(input) {
|
|
3263
|
-
const paths = {};
|
|
3264
|
-
for (const r of input.resources) {
|
|
3265
|
-
const path = pathOf(r.url);
|
|
3266
|
-
const method = (r.method ?? "GET").toLowerCase();
|
|
3267
|
-
const op = {
|
|
3268
|
-
...r.description ? { summary: r.description } : {},
|
|
3269
|
-
responses: {
|
|
3270
|
-
"200": { description: "Paid \u2014 the resource." },
|
|
3271
|
-
"402": { description: "Payment required (x402)." }
|
|
3272
|
-
},
|
|
3273
|
-
"x-payment-info": {
|
|
3274
|
-
x402Version: 2,
|
|
3275
|
-
accepts: r.accepts,
|
|
3276
|
-
bazaar: { discoverable: true }
|
|
3277
|
-
}
|
|
3278
|
-
};
|
|
3279
|
-
paths[path] = { ...paths[path] ?? {}, [method]: op };
|
|
3280
|
-
}
|
|
3281
|
-
return {
|
|
3282
|
-
openapi: "3.1.0",
|
|
3283
|
-
info: { title: input.title ?? "PipRail x402 resources", version: input.version ?? "1.0.0" },
|
|
3284
|
-
servers: [{ url: input.origin }],
|
|
3285
|
-
paths,
|
|
3286
|
-
// "Built with @piprail/sdk" — default on (opt out with attribution:false). At the
|
|
3287
|
-
// document ROOT so `info` stays exactly { title, version }.
|
|
3288
|
-
...input.attribution === false ? {} : { "x-generator": GENERATOR },
|
|
3289
|
-
...input.ownershipProofs && input.ownershipProofs.length > 0 ? { "x-agentcash-provenance": { ownershipProofs: input.ownershipProofs } } : {}
|
|
3290
|
-
};
|
|
3291
|
-
}
|
|
3292
|
-
function buildWellKnownX402(input) {
|
|
3293
|
-
return {
|
|
3294
|
-
version: 1,
|
|
3295
|
-
resources: input.resources.map((r) => r.url),
|
|
3296
|
-
...input.ownershipProofs && input.ownershipProofs.length > 0 ? { ownershipProofs: input.ownershipProofs } : {}
|
|
3297
|
-
};
|
|
3298
|
-
}
|
|
3299
|
-
function buildX402DnsTxt(input) {
|
|
3300
|
-
const descriptor = input.descriptor ? `descriptor=${input.descriptor};` : "";
|
|
3301
|
-
return {
|
|
3302
|
-
name: `_x402.${input.host}`,
|
|
3303
|
-
type: "TXT",
|
|
3304
|
-
value: `v=x4021;${descriptor}url=${input.discoveryUrl}`
|
|
3305
|
-
};
|
|
3306
|
-
}
|
|
3307
3349
|
export {
|
|
3308
3350
|
CHAINS,
|
|
3309
3351
|
ConfirmationTimeoutError,
|
|
@@ -3332,6 +3374,7 @@ export {
|
|
|
3332
3374
|
UnsupportedNetworkError,
|
|
3333
3375
|
WrongChainError,
|
|
3334
3376
|
WrongFamilyError,
|
|
3377
|
+
buildBazaarExtension,
|
|
3335
3378
|
buildChallengeHeader,
|
|
3336
3379
|
buildExactAuthorization,
|
|
3337
3380
|
buildOpenApi,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@piprail/sdk",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.13.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",
|