@seedhape/x402-merchant-sdk 0.3.5 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +181 -6
- package/dist/browser-paywall.d.ts +50 -0
- package/dist/browser-paywall.d.ts.map +1 -0
- package/dist/browser-paywall.js +35 -0
- package/dist/browser-paywall.js.map +1 -0
- package/dist/commerce.d.ts +38 -0
- package/dist/commerce.d.ts.map +1 -0
- package/dist/commerce.js +35 -0
- package/dist/commerce.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/mcp.d.ts.map +1 -1
- package/dist/mcp.js +23 -16
- package/dist/mcp.js.map +1 -1
- package/dist/middleware.d.ts +31 -4
- package/dist/middleware.d.ts.map +1 -1
- package/dist/middleware.js +157 -36
- package/dist/middleware.js.map +1 -1
- package/dist/mpp.d.ts +22 -0
- package/dist/mpp.d.ts.map +1 -0
- package/dist/mpp.js +23 -0
- package/dist/mpp.js.map +1 -0
- package/dist/seller.d.ts +93 -0
- package/dist/seller.d.ts.map +1 -0
- package/dist/seller.js +249 -0
- package/dist/seller.js.map +1 -0
- package/dist/stripe-mpp.d.ts +59 -0
- package/dist/stripe-mpp.d.ts.map +1 -0
- package/dist/stripe-mpp.js +79 -0
- package/dist/stripe-mpp.js.map +1 -0
- package/package.json +23 -2
package/README.md
CHANGED
|
@@ -1,5 +1,72 @@
|
|
|
1
1
|
# @seedhape/x402-merchant-sdk
|
|
2
2
|
|
|
3
|
+
## One catalog for agent commerce
|
|
4
|
+
|
|
5
|
+
Use `createMerchantCommerce` to define products once. The same product
|
|
6
|
+
definitions can feed the SDK's current x402 paywall and future ACP/UCP/MPP
|
|
7
|
+
adapters; merchants do not maintain protocol-specific catalogs.
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
const commerce = createMerchantCommerce({
|
|
11
|
+
paywall: { payTo, ...base, facilitator: base.facilitator },
|
|
12
|
+
products: [{
|
|
13
|
+
id: "weather", name: "Weather API", description: "Current weather",
|
|
14
|
+
endpoint: "/weather",
|
|
15
|
+
price: { amount: 50_000n, ...base },
|
|
16
|
+
}],
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
commerce.catalog(); // publish to your agent-facing catalog
|
|
20
|
+
commerce.paywallFor("weather"); // pass to existing paywall middleware
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
The helper normalizes discovery metadata and product lookup. Fulfillment and
|
|
24
|
+
refunds remain merchant-owned and should use the purchase ID as their durable
|
|
25
|
+
idempotency key.
|
|
26
|
+
|
|
27
|
+
## Unified seller facade (preview)
|
|
28
|
+
|
|
29
|
+
`createSeedhapeSeller` is the single-drop-in entry point for a server-side
|
|
30
|
+
Express route. Define each product once and keep provider credentials in the
|
|
31
|
+
server environment:
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
import { base, createSeedhapeSeller } from "@seedhape/x402-merchant-sdk";
|
|
35
|
+
|
|
36
|
+
const seller = createSeedhapeSeller({
|
|
37
|
+
products: [{
|
|
38
|
+
id: "weather",
|
|
39
|
+
name: "Weather API",
|
|
40
|
+
description: "Current weather data",
|
|
41
|
+
endpoint: "/weather",
|
|
42
|
+
price: "0.50",
|
|
43
|
+
fulfill: async () => ({ temperature: 24 }),
|
|
44
|
+
}],
|
|
45
|
+
payments: {
|
|
46
|
+
x402: {
|
|
47
|
+
payTo: process.env.MERCHANT_WALLET!,
|
|
48
|
+
network: base.network,
|
|
49
|
+
asset: base.asset,
|
|
50
|
+
decimals: base.decimals,
|
|
51
|
+
facilitator: base.facilitator,
|
|
52
|
+
},
|
|
53
|
+
stripeMpp: {
|
|
54
|
+
stripeSecretKey: process.env.STRIPE_SECRET_KEY!,
|
|
55
|
+
profileId: process.env.STRIPE_PROFILE_ID!,
|
|
56
|
+
mppSecretKey: process.env.MPP_SECRET_KEY!,
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
app.all("/weather", seller.route("weather"));
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
The facade preserves the existing x402 Bazaar discovery challenge. It selects
|
|
65
|
+
Stripe MPP when a client advertises the MPP payment scheme and selects x402
|
|
66
|
+
otherwise. ACP/UCP checkout remains a separate integration gate; it will
|
|
67
|
+
consume the same catalog rather than requiring another merchant catalog or
|
|
68
|
+
middleware stack.
|
|
69
|
+
|
|
3
70
|
Add an x402 payment gate to an existing Express, Hono, or `node:http` service. The SDK returns a standard `402 Payment Required` challenge, verifies the buyer's payment through an x402 facilitator, settles USDC directly to the merchant wallet, and exposes a receipt for your application ledger.
|
|
4
71
|
|
|
5
72
|
## Install
|
|
@@ -8,6 +75,44 @@ Add an x402 payment gate to an existing Express, Hono, or `node:http` service. T
|
|
|
8
75
|
npm install @seedhape/x402-merchant-sdk
|
|
9
76
|
```
|
|
10
77
|
|
|
78
|
+
## Stripe machine payments (MPP)
|
|
79
|
+
|
|
80
|
+
Install the optional MPP runtime when you want agents to pay with Stripe cards
|
|
81
|
+
or Shared Payment Tokens:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
npm install mppx
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Create one Stripe MPP paywall per seller endpoint. The seller keeps the Stripe
|
|
88
|
+
secret key and `profile_test_...` profile ID on the server; the SDK returns the
|
|
89
|
+
payment challenge and settles the credential without exposing either value:
|
|
90
|
+
|
|
91
|
+
```ts
|
|
92
|
+
import { createStripeMppPaywall } from "@seedhape/x402-merchant-sdk";
|
|
93
|
+
|
|
94
|
+
const mpp = await createStripeMppPaywall({
|
|
95
|
+
stripeSecretKey: process.env.STRIPE_SECRET_KEY!,
|
|
96
|
+
profileId: process.env.STRIPE_PROFILE_ID!,
|
|
97
|
+
mppSecretKey: process.env.MPP_SECRET_KEY!,
|
|
98
|
+
amount: "0.50",
|
|
99
|
+
currency: "usd",
|
|
100
|
+
description: "Weather API request",
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
export async function weather(request: Request) {
|
|
104
|
+
return mpp.handle(request, async () =>
|
|
105
|
+
Response.json({ temperature: 24, conditions: "clear" }),
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
An unpaid agent receives HTTP `402`; a valid credential is verified and
|
|
111
|
+
settled before the fulfillment callback runs. For a Stripe Connect direct
|
|
112
|
+
charge, pass `connect: { stripeAccount: "acct_..." }`. To enable Stripe's
|
|
113
|
+
stablecoin MPP rail as well, supply a Stripe SDK client and a test Tempo deposit
|
|
114
|
+
address. Use `profile_test_...` and `sk_test_...` in a Stripe Sandbox.
|
|
115
|
+
|
|
11
116
|
## Express
|
|
12
117
|
|
|
13
118
|
```ts
|
|
@@ -43,7 +148,7 @@ app.get("/weather", (req, res) => {
|
|
|
43
148
|
|
|
44
149
|
## Network presets and payment methods
|
|
45
150
|
|
|
46
|
-
Use `base` or `
|
|
151
|
+
Use `base`, `baseSepolia`, `solana`, or `solanaDevnet` to preconfigure the CAIP-2 network, USDC mint/contract, decimals, and default facilitator:
|
|
47
152
|
|
|
48
153
|
```ts
|
|
49
154
|
import { baseSepolia, expressPaywall, merchantConfig } from "@seedhape/x402-merchant-sdk";
|
|
@@ -59,6 +164,76 @@ app.use(expressPaywall(merchantConfig(baseSepolia, {
|
|
|
59
164
|
|
|
60
165
|
`paymentMethods` defaults to `['eip3009']`, the broadly supported payment method. Set `['eip3009', 'erc7710']` to let the buyer/client choose both methods. Only advertise ERC-7710 when the configured facilitator supports it. If the methods use different facilitators, configure `facilitators: { eip3009: {...}, erc7710: {...} }`; the SDK selects the facilitator matching the buyer's selected method.
|
|
61
166
|
|
|
167
|
+
### Base and Solana on one route
|
|
168
|
+
|
|
169
|
+
Use `accepts` to expose both chains from the same resource. Bazaar and downstream catalogs such as Agentic Market treat these as payment choices on one service listing:
|
|
170
|
+
|
|
171
|
+
```ts
|
|
172
|
+
import { base, solana, expressPaywall, merchantConfig } from "@seedhape/x402-merchant-sdk";
|
|
173
|
+
|
|
174
|
+
// Create cdpFacilitator with createCdpFacilitatorClient as shown below.
|
|
175
|
+
|
|
176
|
+
app.use(expressPaywall(merchantConfig(base, {
|
|
177
|
+
accepts: [{
|
|
178
|
+
...base,
|
|
179
|
+
payTo: process.env.BASE_MERCHANT_WALLET!,
|
|
180
|
+
paymentMethods: ["eip3009"],
|
|
181
|
+
}, {
|
|
182
|
+
...solana,
|
|
183
|
+
payTo: process.env.SOLANA_MERCHANT_WALLET!,
|
|
184
|
+
feePayer: process.env.SOLANA_FEE_PAYER!,
|
|
185
|
+
}],
|
|
186
|
+
price: { amount: 10_000n, ...base },
|
|
187
|
+
facilitator: {
|
|
188
|
+
url: "https://api.cdp.coinbase.com/platform/v2/x402",
|
|
189
|
+
client: cdpFacilitator,
|
|
190
|
+
},
|
|
191
|
+
route: {
|
|
192
|
+
name: "Market Data",
|
|
193
|
+
description: "Paid market data on Base or Solana",
|
|
194
|
+
inputSchema: { type: "object", properties: { symbol: { type: "string" } } },
|
|
195
|
+
outputSchema: { type: "object" },
|
|
196
|
+
},
|
|
197
|
+
})));
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
`feePayer` is the Solana facilitator signer advertised by its `/supported` response; it is not the merchant wallet. Use a facilitator that supports every advertised network, or set a per-option `facilitator`. Solana payments use the official x402 `exact` SVM scheme and a base64-encoded, partially signed versioned transaction in `PAYMENT-SIGNATURE`.
|
|
201
|
+
|
|
202
|
+
The built-in Solana mainnet preset uses `solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp` and native USDC mint `EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v`. Solana addresses are case-sensitive.
|
|
203
|
+
Its default facilitator is `https://facilitator.payai.network`; the devnet preset uses the test-only `https://x402.org/facilitator`.
|
|
204
|
+
|
|
205
|
+
### Browser wallet paywall
|
|
206
|
+
|
|
207
|
+
Install the optional official UI when people should be able to open the paid route directly and pay with an EVM or Solana browser wallet:
|
|
208
|
+
|
|
209
|
+
```bash
|
|
210
|
+
npm install @seedhape/x402-merchant-sdk @x402/paywall react react-dom
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
Then enable it on the same configuration:
|
|
214
|
+
|
|
215
|
+
```ts
|
|
216
|
+
const config = merchantConfig(base, {
|
|
217
|
+
accepts: [
|
|
218
|
+
{ ...base, payTo: process.env.BASE_MERCHANT_WALLET! },
|
|
219
|
+
{
|
|
220
|
+
...solana,
|
|
221
|
+
payTo: process.env.SOLANA_MERCHANT_WALLET!,
|
|
222
|
+
feePayer: process.env.SOLANA_FEE_PAYER!,
|
|
223
|
+
},
|
|
224
|
+
],
|
|
225
|
+
price: { amount: 10_000n, ...base },
|
|
226
|
+
browserPaywall: {
|
|
227
|
+
appName: "Market Data",
|
|
228
|
+
appLogo: "https://api.example.com/icon-512.png",
|
|
229
|
+
testnet: false,
|
|
230
|
+
},
|
|
231
|
+
facilitator: { url: "https://facilitator.payai.network" },
|
|
232
|
+
});
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
Express, Hono, and `node:http` adapters now return the official `@x402/paywall` HTML when the request accepts `text/html`. Programmatic callers continue receiving the normal JSON challenge and `PAYMENT-REQUIRED` header. The UI registers both official `evmPaywall` and `svmPaywall` handlers. Because `@x402/paywall` is an optional peer dependency, API-only installations do not pull its browser-wallet and React dependency tree.
|
|
236
|
+
|
|
62
237
|
### Coinbase CDP Facilitator and Bazaar
|
|
63
238
|
|
|
64
239
|
For Coinbase Bazaar indexing, use Coinbase's authenticated facilitator client rather than passing the CDP API secret as a bearer token:
|
|
@@ -169,7 +344,7 @@ The HTTP route and MCP tool produce separate x402 resources, so each can have it
|
|
|
169
344
|
|
|
170
345
|
Enable AP2 on an HTTP paywall to issue a signed merchant Checkout JWT with every unpaid or rejected `402` response. The SDK returns it in the `AP2-CHECKOUT-JWT` header; this does not change x402 verification or settlement.
|
|
171
346
|
|
|
172
|
-
AP2 is optional. A route without the `ap2` option behaves exactly like a normal x402 route. AP2 adds signed checkout context for AP2-aware buyers and agents; the facilitator still verifies and settles the EIP-3009 or ERC-7710 payment.
|
|
347
|
+
AP2 is optional. A route without the `ap2` option behaves exactly like a normal x402 route. AP2 adds signed checkout context for AP2-aware buyers and agents; the facilitator still verifies and settles the EIP-3009 or ERC-7710 payment. The current Checkout JWT binds one network, so SDK routes using `ap2` must configure a single payment option; multi-network Solana AP2 mandates are a separate follow-up.
|
|
173
348
|
|
|
174
349
|
```ts
|
|
175
350
|
app.use(expressPaywall(merchantConfig(base, {
|
|
@@ -217,8 +392,8 @@ PAYMENT-REQUIRED: eyJ...
|
|
|
217
392
|
|
|
218
393
|
## Payment flow
|
|
219
394
|
|
|
220
|
-
1. An unpaid request receives a v2 `402` challenge with a `PAYMENT-REQUIRED` header containing
|
|
221
|
-
2. The buyer
|
|
395
|
+
1. An unpaid request receives a v2 `402` challenge with a `PAYMENT-REQUIRED` header containing one or more accepted networks, recipient wallets, USDC assets, the amount, and resource URL.
|
|
396
|
+
2. The buyer selects an accepted option, creates an EVM authorization or Solana transaction, and sends it in `PAYMENT-SIGNATURE`.
|
|
222
397
|
3. The facilitator verifies and settles the payment.
|
|
223
398
|
4. USDC settles directly to `payTo`; Seedhape never holds merchant funds.
|
|
224
399
|
5. The request continues and the settlement is returned in `PAYMENT-RESPONSE`.
|
|
@@ -227,7 +402,7 @@ The SDK emits the current x402 v2 challenge shape. For migration, it also accept
|
|
|
227
402
|
|
|
228
403
|
## Official x402 integrations
|
|
229
404
|
|
|
230
|
-
The SDK is built on the official `@x402/core
|
|
405
|
+
The SDK is built on the official `@x402/core`, `@x402/evm`, and `@x402/svm` packages. EIP-3009 and exact-SVM verification and settlement use `x402ResourceServer`, `HTTPFacilitatorClient`, and the official chain scheme. Bazaar declarations use `@x402/extensions/bazaar` and are registered with the resource server.
|
|
231
406
|
|
|
232
407
|
ERC-7710 remains an opt-in Seedhape facilitator method because the official EVM exact server currently covers EIP-3009 and Permit2, not ERC-7710. When `erc7710` is selected, the SDK routes it to the configured facilitator override; it never silently sends an ERC-7710 payload through the EIP-3009 verifier.
|
|
233
408
|
|
|
@@ -250,7 +425,7 @@ Sonar listing does not replace Bazaar metadata. A merchant can publish Bazaar di
|
|
|
250
425
|
## Production checklist
|
|
251
426
|
|
|
252
427
|
- Use a self-custodial merchant receiving address.
|
|
253
|
-
- Use
|
|
428
|
+
- Use Base mainnet or Solana mainnet presets in production and their testnet/devnet presets only for testing.
|
|
254
429
|
- Configure a production facilitator URL and keep it server-side.
|
|
255
430
|
- Keep health, documentation, and discovery metadata routes free.
|
|
256
431
|
- Record the receipt ID, resource, payer, amount, network, and transaction hash.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/** Structural subset of the official renderer, kept local so server-only users do not need its types. */
|
|
2
|
+
export interface BrowserPaywallProvider {
|
|
3
|
+
generateHtml(paymentRequired: BrowserPaymentRequired, config?: BrowserPaywallRuntimeConfig): string;
|
|
4
|
+
}
|
|
5
|
+
export interface BrowserPaywallRuntimeConfig {
|
|
6
|
+
appName?: string;
|
|
7
|
+
appLogo?: string;
|
|
8
|
+
currentUrl?: string;
|
|
9
|
+
testnet?: boolean;
|
|
10
|
+
faucetUrls?: Record<string, string>;
|
|
11
|
+
}
|
|
12
|
+
export interface BrowserPaymentRequired {
|
|
13
|
+
x402Version: number;
|
|
14
|
+
error?: string;
|
|
15
|
+
resource?: {
|
|
16
|
+
url: string;
|
|
17
|
+
description?: string;
|
|
18
|
+
mimeType?: string;
|
|
19
|
+
};
|
|
20
|
+
accepts: Array<{
|
|
21
|
+
scheme: string;
|
|
22
|
+
network: string;
|
|
23
|
+
asset: string;
|
|
24
|
+
payTo: string;
|
|
25
|
+
maxTimeoutSeconds: number;
|
|
26
|
+
extra?: Record<string, unknown>;
|
|
27
|
+
amount?: string;
|
|
28
|
+
maxAmountRequired?: string;
|
|
29
|
+
description?: string;
|
|
30
|
+
resource?: string;
|
|
31
|
+
mimeType?: string;
|
|
32
|
+
}>;
|
|
33
|
+
extensions?: Record<string, unknown>;
|
|
34
|
+
}
|
|
35
|
+
/** Runtime options passed to the official browser paywall renderer. */
|
|
36
|
+
export interface BrowserPaywallConfig extends BrowserPaywallRuntimeConfig {
|
|
37
|
+
/** Inject a custom provider, primarily for custom themes or tests. */
|
|
38
|
+
provider?: BrowserPaywallProvider;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Build the official x402 browser paywall with handlers for both EVM and Solana.
|
|
42
|
+
* `@x402/paywall` is an optional peer so server-only SDK installs stay lean.
|
|
43
|
+
*/
|
|
44
|
+
export declare function createBrowserPaywallProvider(config?: BrowserPaywallRuntimeConfig): Promise<BrowserPaywallProvider>;
|
|
45
|
+
export declare function renderBrowserPaywall(args: {
|
|
46
|
+
paymentRequired: unknown;
|
|
47
|
+
accept?: string | string[];
|
|
48
|
+
config: true | BrowserPaywallConfig;
|
|
49
|
+
}): Promise<string | undefined>;
|
|
50
|
+
//# sourceMappingURL=browser-paywall.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-paywall.d.ts","sourceRoot":"","sources":["../src/browser-paywall.ts"],"names":[],"mappings":"AAAA,yGAAyG;AACzG,MAAM,WAAW,sBAAsB;IACrC,YAAY,CAAC,eAAe,EAAE,sBAAsB,EAAE,MAAM,CAAC,EAAE,2BAA2B,GAAG,MAAM,CAAC;CACrG;AAED,MAAM,WAAW,2BAA2B;IAC1C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACrC;AAED,MAAM,WAAW,sBAAsB;IACrC,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACpE,OAAO,EAAE,KAAK,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,MAAM,CAAC;QACd,iBAAiB,EAAE,MAAM,CAAC;QAC1B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAChC,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,iBAAiB,CAAC,EAAE,MAAM,CAAC;QAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC,CAAC;IACH,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED,uEAAuE;AACvE,MAAM,WAAW,oBAAqB,SAAQ,2BAA2B;IACvE,sEAAsE;IACtE,QAAQ,CAAC,EAAE,sBAAsB,CAAC;CACnC;AAED;;;GAGG;AACH,wBAAsB,4BAA4B,CAChD,MAAM,GAAE,2BAAgC,GACvC,OAAO,CAAC,sBAAsB,CAAC,CAkBjC;AAED,wBAAsB,oBAAoB,CAAC,IAAI,EAAE;IAC/C,eAAe,EAAE,OAAO,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC3B,MAAM,EAAE,IAAI,GAAG,oBAAoB,CAAC;CACrC,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAY9B"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build the official x402 browser paywall with handlers for both EVM and Solana.
|
|
3
|
+
* `@x402/paywall` is an optional peer so server-only SDK installs stay lean.
|
|
4
|
+
*/
|
|
5
|
+
export async function createBrowserPaywallProvider(config = {}) {
|
|
6
|
+
try {
|
|
7
|
+
const [{ createPaywall }, { evmPaywall }, { svmPaywall }] = await Promise.all([
|
|
8
|
+
import("@x402/paywall"),
|
|
9
|
+
import("@x402/paywall/evm"),
|
|
10
|
+
import("@x402/paywall/svm"),
|
|
11
|
+
]);
|
|
12
|
+
return createPaywall()
|
|
13
|
+
.withNetwork(evmPaywall)
|
|
14
|
+
.withNetwork(svmPaywall)
|
|
15
|
+
.withConfig(config)
|
|
16
|
+
.build();
|
|
17
|
+
}
|
|
18
|
+
catch (cause) {
|
|
19
|
+
throw new Error("Browser paywall support requires the optional @x402/paywall peer dependency (version 2.23.0 or newer).", { cause });
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
export async function renderBrowserPaywall(args) {
|
|
23
|
+
const accept = Array.isArray(args.accept) ? args.accept.join(",") : args.accept ?? "";
|
|
24
|
+
if (!accept.toLowerCase().includes("text/html"))
|
|
25
|
+
return undefined;
|
|
26
|
+
const configured = args.config === true ? {} : args.config;
|
|
27
|
+
const { provider, ...runtimeConfig } = configured;
|
|
28
|
+
const resolvedProvider = provider ?? await createBrowserPaywallProvider(runtimeConfig);
|
|
29
|
+
const paymentRequired = args.paymentRequired;
|
|
30
|
+
return resolvedProvider.generateHtml(paymentRequired, {
|
|
31
|
+
...runtimeConfig,
|
|
32
|
+
currentUrl: runtimeConfig.currentUrl ?? paymentRequired.resource?.url,
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=browser-paywall.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-paywall.js","sourceRoot":"","sources":["../src/browser-paywall.ts"],"names":[],"mappings":"AAuCA;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,4BAA4B,CAChD,SAAsC,EAAE;IAExC,IAAI,CAAC;QACH,MAAM,CAAC,EAAE,aAAa,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,UAAU,EAAE,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YAC5E,MAAM,CAAC,eAAe,CAAC;YACvB,MAAM,CAAC,mBAAmB,CAAC;YAC3B,MAAM,CAAC,mBAAmB,CAAC;SAC5B,CAAC,CAAC;QACH,OAAO,aAAa,EAAE;aACnB,WAAW,CAAC,UAAU,CAAC;aACvB,WAAW,CAAC,UAAU,CAAC;aACvB,UAAU,CAAC,MAAM,CAAC;aAClB,KAAK,EAAE,CAAC;IACb,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CACb,wGAAwG,EACxG,EAAE,KAAK,EAAE,CACV,CAAC;IACJ,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,IAI1C;IACC,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC;IACtF,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC;QAAE,OAAO,SAAS,CAAC;IAElE,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC;IAC3D,MAAM,EAAE,QAAQ,EAAE,GAAG,aAAa,EAAE,GAAG,UAAU,CAAC;IAClD,MAAM,gBAAgB,GAAG,QAAQ,IAAI,MAAM,4BAA4B,CAAC,aAAa,CAAC,CAAC;IACvF,MAAM,eAAe,GAAG,IAAI,CAAC,eAAyC,CAAC;IACvE,OAAO,gBAAgB,CAAC,YAAY,CAAC,eAAe,EAAE;QACpD,GAAG,aAAa;QAChB,UAAU,EAAE,aAAa,CAAC,UAAU,IAAI,eAAe,CAAC,QAAQ,EAAE,GAAG;KACtE,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { Money, PaywallConfig, RouteMetadata } from "./middleware.js";
|
|
2
|
+
/** A merchant's protocol-neutral, agent-readable product definition. */
|
|
3
|
+
export interface MerchantProduct {
|
|
4
|
+
id: string;
|
|
5
|
+
name: string;
|
|
6
|
+
description: string;
|
|
7
|
+
price: Money;
|
|
8
|
+
endpoint: string;
|
|
9
|
+
/** A human-readable policy; fulfillment/refund behavior stays merchant-owned. */
|
|
10
|
+
refundPolicy?: string;
|
|
11
|
+
metadata?: RouteMetadata;
|
|
12
|
+
}
|
|
13
|
+
export interface MerchantCommerceConfig {
|
|
14
|
+
/** Base paywall/provider configuration shared by every product. */
|
|
15
|
+
paywall: Omit<PaywallConfig, "price">;
|
|
16
|
+
products: readonly MerchantProduct[];
|
|
17
|
+
}
|
|
18
|
+
export interface MerchantCatalogProduct extends Omit<MerchantProduct, "price"> {
|
|
19
|
+
price: {
|
|
20
|
+
amount: string;
|
|
21
|
+
asset: string;
|
|
22
|
+
network: string;
|
|
23
|
+
decimals: number;
|
|
24
|
+
};
|
|
25
|
+
capabilities: readonly ["quote", "purchase", "receipt"];
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* One merchant integration surface for catalogs and paid routes. Protocol
|
|
29
|
+
* adapters consume the same product definitions, so a merchant does not keep
|
|
30
|
+
* separate ACP/UCP/x402/MPP catalogs. The returned PaywallConfig remains
|
|
31
|
+
* compatible with the existing Express/Hono/node:http middleware.
|
|
32
|
+
*/
|
|
33
|
+
export declare function createMerchantCommerce(config: MerchantCommerceConfig): {
|
|
34
|
+
catalog(): MerchantCatalogProduct[];
|
|
35
|
+
product(id: string): MerchantProduct | null;
|
|
36
|
+
paywallFor(id: string): PaywallConfig;
|
|
37
|
+
};
|
|
38
|
+
//# sourceMappingURL=commerce.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commerce.d.ts","sourceRoot":"","sources":["../src/commerce.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAE3E,wEAAwE;AACxE,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,iFAAiF;IACjF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,aAAa,CAAC;CAC1B;AAED,MAAM,WAAW,sBAAsB;IACrC,mEAAmE;IACnE,OAAO,EAAE,IAAI,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;IACtC,QAAQ,EAAE,SAAS,eAAe,EAAE,CAAC;CACtC;AAED,MAAM,WAAW,sBAAuB,SAAQ,IAAI,CAAC,eAAe,EAAE,OAAO,CAAC;IAC5E,KAAK,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5E,YAAY,EAAE,SAAS,CAAC,OAAO,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;CACzD;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,sBAAsB;eAKtD,sBAAsB,EAAE;gBAOvB,MAAM,GAAG,eAAe,GAAG,IAAI;mBAG5B,MAAM,GAAG,aAAa;EAWxC"}
|
package/dist/commerce.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One merchant integration surface for catalogs and paid routes. Protocol
|
|
3
|
+
* adapters consume the same product definitions, so a merchant does not keep
|
|
4
|
+
* separate ACP/UCP/x402/MPP catalogs. The returned PaywallConfig remains
|
|
5
|
+
* compatible with the existing Express/Hono/node:http middleware.
|
|
6
|
+
*/
|
|
7
|
+
export function createMerchantCommerce(config) {
|
|
8
|
+
const byId = new Map(config.products.map((product) => [product.id, product]));
|
|
9
|
+
if (byId.size !== config.products.length)
|
|
10
|
+
throw new Error("Merchant product IDs must be unique.");
|
|
11
|
+
return {
|
|
12
|
+
catalog() {
|
|
13
|
+
return config.products.map((product) => ({
|
|
14
|
+
...product,
|
|
15
|
+
price: { ...product.price, amount: product.price.amount.toString() },
|
|
16
|
+
capabilities: ["quote", "purchase", "receipt"],
|
|
17
|
+
}));
|
|
18
|
+
},
|
|
19
|
+
product(id) {
|
|
20
|
+
return byId.get(id) ?? null;
|
|
21
|
+
},
|
|
22
|
+
paywallFor(id) {
|
|
23
|
+
const product = byId.get(id);
|
|
24
|
+
if (!product)
|
|
25
|
+
throw new Error(`Unknown merchant product: ${id}`);
|
|
26
|
+
return {
|
|
27
|
+
...config.paywall,
|
|
28
|
+
price: product.price,
|
|
29
|
+
description: product.description,
|
|
30
|
+
route: { ...product.metadata, name: product.metadata?.name ?? product.name, description: product.description },
|
|
31
|
+
};
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=commerce.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commerce.js","sourceRoot":"","sources":["../src/commerce.ts"],"names":[],"mappings":"AAyBA;;;;;GAKG;AACH,MAAM,UAAU,sBAAsB,CAAC,MAA8B;IACnE,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IAC9E,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,CAAC,QAAQ,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;IAElG,OAAO;QACL,OAAO;YACL,OAAO,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;gBACvC,GAAG,OAAO;gBACV,KAAK,EAAE,EAAE,GAAG,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE;gBACpE,YAAY,EAAE,CAAC,OAAO,EAAE,UAAU,EAAE,SAAS,CAAU;aACxD,CAAC,CAAC,CAAC;QACN,CAAC;QACD,OAAO,CAAC,EAAU;YAChB,OAAO,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC;QAC9B,CAAC;QACD,UAAU,CAAC,EAAU;YACnB,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC7B,IAAI,CAAC,OAAO;gBAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,EAAE,EAAE,CAAC,CAAC;YACjE,OAAO;gBACL,GAAG,MAAM,CAAC,OAAO;gBACjB,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,WAAW,EAAE,OAAO,CAAC,WAAW;gBAChC,KAAK,EAAE,EAAE,GAAG,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC,QAAQ,EAAE,IAAI,IAAI,OAAO,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE;aAC/G,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
export * from "./middleware.js";
|
|
2
2
|
export * from "./mcp.js";
|
|
3
3
|
export * from "./ap2.js";
|
|
4
|
+
export * from "./browser-paywall.js";
|
|
5
|
+
export * from "./commerce.js";
|
|
6
|
+
export * from "./mpp.js";
|
|
7
|
+
export * from "./stripe-mpp.js";
|
|
8
|
+
export * from "./seller.js";
|
|
4
9
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,sBAAsB,CAAC;AACrC,cAAc,eAAe,CAAC;AAC9B,cAAc,UAAU,CAAC;AACzB,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
export * from "./middleware.js";
|
|
2
2
|
export * from "./mcp.js";
|
|
3
3
|
export * from "./ap2.js";
|
|
4
|
+
export * from "./browser-paywall.js";
|
|
5
|
+
export * from "./commerce.js";
|
|
6
|
+
export * from "./mpp.js";
|
|
7
|
+
export * from "./stripe-mpp.js";
|
|
8
|
+
export * from "./seller.js";
|
|
4
9
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,sBAAsB,CAAC;AACrC,cAAc,eAAe,CAAC;AAC9B,cAAc,UAAU,CAAC;AACzB,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC"}
|
package/dist/mcp.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAIpE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,KAAK,CAAC;AACvC,OAAO,EAEL,KAAK,iBAAiB,EACtB,KAAK,UAAU,EACf,KAAK,aAAa,
|
|
1
|
+
{"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAIpE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,KAAK,CAAC;AACvC,OAAO,EAEL,KAAK,iBAAiB,EACtB,KAAK,UAAU,EACf,KAAK,aAAa,EAEnB,MAAM,iBAAiB,CAAC;AAEzB,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,yDAAyD;IACzD,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,4CAA4C;IAC5C,eAAe,CAAC,EAAE,UAAU,CAAC;IAC7B,gBAAgB,CAAC,EAAE,UAAU,CAAC;IAC9B,iEAAiE;IACjE,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,gEAAgE;IAChE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,yEAAyE;IACzE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yDAAyD;IACzD,WAAW,CAAC,EAAE,iBAAiB,CAAC;CACjC;AAED,MAAM,MAAM,cAAc,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IACxF,CAAC,IAAI,EAAE,KAAK,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;AAE9C;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACrG,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,aAAa,EACtB,IAAI,EAAE,aAAa,EACnB,OAAO,EAAE,cAAc,CAAC,KAAK,CAAC,GAC7B,OAAO,CAAC,IAAI,CAAC,CA4Ef"}
|
package/dist/mcp.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
2
|
import { createPaymentWrapper } from "@x402/mcp";
|
|
3
3
|
import { declareDiscoveryExtension } from "@x402/extensions/bazaar";
|
|
4
|
-
import { createOfficialResourceServer, } from "./middleware.js";
|
|
4
|
+
import { createOfficialResourceServer, resolvePaymentOptions, } from "./middleware.js";
|
|
5
5
|
/**
|
|
6
6
|
* Register a paid MCP tool using the same merchant configuration as HTTP routes.
|
|
7
7
|
* The official @x402/mcp wrapper handles the MCP payment challenge, verification,
|
|
@@ -13,22 +13,29 @@ export async function createPaidMcpTool(server, paywall, tool, handler) {
|
|
|
13
13
|
const price = typeof paywall.price === "function"
|
|
14
14
|
? (() => { throw new Error("MCP tools require a fixed price; configure per-call pricing in the MCP handler layer."); })()
|
|
15
15
|
: paywall.price;
|
|
16
|
-
const
|
|
16
|
+
const paymentOptions = resolvePaymentOptions(paywall);
|
|
17
|
+
if (paymentOptions.some((option) => option.facilitator)) {
|
|
18
|
+
throw new Error("MCP multi-network tools currently require one shared facilitator.");
|
|
19
|
+
}
|
|
20
|
+
const accepts = (await Promise.all(paymentOptions.map((option) => resourceServer.buildPaymentRequirements({
|
|
17
21
|
scheme: "exact",
|
|
18
|
-
network:
|
|
19
|
-
payTo:
|
|
22
|
+
network: option.network,
|
|
23
|
+
payTo: option.payTo,
|
|
20
24
|
price: {
|
|
21
|
-
asset:
|
|
25
|
+
asset: option.asset,
|
|
22
26
|
amount: price.amount.toString(),
|
|
23
|
-
extra:
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
extra: option.network.startsWith("solana:")
|
|
28
|
+
? { ...(option.extra ?? {}), feePayer: option.feePayer ?? option.extra?.feePayer }
|
|
29
|
+
: {
|
|
30
|
+
name: "USD Coin",
|
|
31
|
+
version: "2",
|
|
32
|
+
decimals: option.decimals ?? 6,
|
|
33
|
+
assetTransferMethod: option.paymentMethods?.[0] ?? paywall.paymentMethods?.[0] ?? "eip3009",
|
|
34
|
+
...(option.extra ?? {}),
|
|
35
|
+
},
|
|
29
36
|
},
|
|
30
37
|
maxTimeoutSeconds: paywall.maxTimeoutSeconds,
|
|
31
|
-
});
|
|
38
|
+
})))).flat();
|
|
32
39
|
const wrapped = createPaymentWrapper(resourceServer, {
|
|
33
40
|
accepts,
|
|
34
41
|
resource: {
|
|
@@ -51,18 +58,18 @@ export async function createPaidMcpTool(server, paywall, tool, handler) {
|
|
|
51
58
|
onAfterSettlement: async ({ settlement, paymentPayload }) => {
|
|
52
59
|
if (!settlement.success)
|
|
53
60
|
return;
|
|
61
|
+
const accepted = paymentPayload.accepted;
|
|
54
62
|
await paywall.receipts?.record({
|
|
55
63
|
id: randomUUID(),
|
|
56
64
|
resource: tool.resourceUrl ?? `mcp://tool/${tool.name}`,
|
|
57
65
|
payer: settlement.payer,
|
|
58
|
-
payTo:
|
|
66
|
+
payTo: accepted.payTo,
|
|
59
67
|
amount: price.amount,
|
|
60
|
-
asset:
|
|
61
|
-
network:
|
|
68
|
+
asset: accepted.asset,
|
|
69
|
+
network: accepted.network,
|
|
62
70
|
txHash: settlement.transaction,
|
|
63
71
|
settledAt: Math.floor(Date.now() / 1000),
|
|
64
72
|
});
|
|
65
|
-
void paymentPayload;
|
|
66
73
|
},
|
|
67
74
|
} : undefined,
|
|
68
75
|
})(async (args) => ({
|
package/dist/mcp.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp.js","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AAEpE,OAAO,EACL,4BAA4B,
|
|
1
|
+
{"version":3,"file":"mcp.js","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":"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"}
|
package/dist/middleware.d.ts
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
import type { IncomingMessage, ServerResponse } from "node:http";
|
|
13
13
|
import { x402ResourceServer, type FacilitatorClient } from "@x402/core/server";
|
|
14
14
|
import type { Ap2MerchantConfig } from "./ap2.js";
|
|
15
|
+
import { type BrowserPaywallConfig } from "./browser-paywall.js";
|
|
15
16
|
export interface Money {
|
|
16
17
|
/** Base units of the asset. USDC has 6 decimals. */
|
|
17
18
|
amount: bigint;
|
|
@@ -53,6 +54,21 @@ export interface FacilitatorConfig {
|
|
|
53
54
|
client?: FacilitatorClient;
|
|
54
55
|
}
|
|
55
56
|
export type PaymentMethod = "eip3009" | "erc7710";
|
|
57
|
+
/** One chain-specific way a buyer may pay for the same resource. */
|
|
58
|
+
export interface MerchantPaymentOption {
|
|
59
|
+
network: string;
|
|
60
|
+
asset: string;
|
|
61
|
+
payTo: string;
|
|
62
|
+
decimals?: number;
|
|
63
|
+
/** EVM transfer methods. Solana always uses the x402 `exact` SVM scheme. */
|
|
64
|
+
paymentMethods?: PaymentMethod[];
|
|
65
|
+
/** Override the route-level facilitator for this network. */
|
|
66
|
+
facilitator?: FacilitatorConfig;
|
|
67
|
+
/** Required for Solana HTTP challenges unless supplied in `extra.feePayer`. */
|
|
68
|
+
feePayer?: string;
|
|
69
|
+
/** Additional scheme-specific payment requirement fields. */
|
|
70
|
+
extra?: Record<string, unknown>;
|
|
71
|
+
}
|
|
56
72
|
export interface JsonSchema {
|
|
57
73
|
[key: string]: unknown;
|
|
58
74
|
}
|
|
@@ -83,6 +99,8 @@ export interface MerchantNetworkConfig {
|
|
|
83
99
|
decimals: number;
|
|
84
100
|
facilitator: FacilitatorConfig;
|
|
85
101
|
}
|
|
102
|
+
export declare const SOLANA_MAINNET: MerchantNetworkConfig;
|
|
103
|
+
export declare const SOLANA_DEVNET: MerchantNetworkConfig;
|
|
86
104
|
/** Base mainnet + USDC defaults. Override any field for a custom facilitator. */
|
|
87
105
|
export declare const BASE_MAINNET: MerchantNetworkConfig;
|
|
88
106
|
/** Base Sepolia + USDC defaults for development and staging. */
|
|
@@ -90,16 +108,21 @@ export declare const BASE_SEPOLIA: MerchantNetworkConfig;
|
|
|
90
108
|
/** Lowercase aliases make preset usage read naturally in route definitions. */
|
|
91
109
|
export declare const base: MerchantNetworkConfig;
|
|
92
110
|
export declare const baseSepolia: MerchantNetworkConfig;
|
|
111
|
+
export declare const solana: MerchantNetworkConfig;
|
|
112
|
+
export declare const solanaDevnet: MerchantNetworkConfig;
|
|
93
113
|
export interface MerchantPresetConfig extends MerchantNetworkConfig {
|
|
94
114
|
paymentMethods?: PaymentMethod[];
|
|
95
115
|
}
|
|
96
116
|
/** Compose a route configuration from a network preset without mutation. */
|
|
97
117
|
export declare function merchantConfig(preset: MerchantPresetConfig, config: Omit<PaywallConfig, "network" | "asset" | "decimals" | "facilitator"> & Partial<Pick<PaywallConfig, "network" | "asset" | "decimals" | "facilitator">>): PaywallConfig;
|
|
98
118
|
export interface PaywallConfig {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
119
|
+
/** Legacy single-network fields. Omit these when `accepts` is provided. */
|
|
120
|
+
payTo?: string;
|
|
121
|
+
network?: string;
|
|
122
|
+
asset?: string;
|
|
102
123
|
decimals?: number;
|
|
124
|
+
/** Multiple chain-specific payment choices shown in one Bazaar/Agentic Market listing. */
|
|
125
|
+
accepts?: MerchantPaymentOption[];
|
|
103
126
|
/** Payment authorization methods advertised in the 402 response. */
|
|
104
127
|
paymentMethods?: PaymentMethod[];
|
|
105
128
|
/** Optional facilitator overrides for individual transfer methods. */
|
|
@@ -122,6 +145,8 @@ export interface PaywallConfig {
|
|
|
122
145
|
bazaar?: boolean;
|
|
123
146
|
/** Optional merchant AP2 issuer. Adds AP2-CHECKOUT-JWT to 402 responses. */
|
|
124
147
|
ap2?: Ap2MerchantConfig;
|
|
148
|
+
/** Render the official EVM + Solana browser UI for requests accepting text/html. */
|
|
149
|
+
browserPaywall?: true | BrowserPaywallConfig;
|
|
125
150
|
maxTimeoutSeconds?: number;
|
|
126
151
|
/** Routes that never require payment, e.g. ["/health", "/.well-known/*"]. */
|
|
127
152
|
free?: string[];
|
|
@@ -168,9 +193,10 @@ export interface PaywallOutcome {
|
|
|
168
193
|
export declare class Paywall {
|
|
169
194
|
private readonly cfg;
|
|
170
195
|
private readonly facilitator;
|
|
171
|
-
private readonly
|
|
196
|
+
private readonly paymentOptions;
|
|
172
197
|
constructor(cfg: PaywallConfig);
|
|
173
198
|
priceFor(path: string, method: string, query: URLSearchParams): Money | null;
|
|
199
|
+
renderBrowserChallenge(challenge: unknown, accept?: string | string[]): Promise<string | undefined>;
|
|
174
200
|
buildChallenge(price: Money, resource: string, method?: string): {
|
|
175
201
|
x402Version: number;
|
|
176
202
|
error: string;
|
|
@@ -195,6 +221,7 @@ export declare class Paywall {
|
|
|
195
221
|
private facilitatorFor;
|
|
196
222
|
private writeReceipt;
|
|
197
223
|
}
|
|
224
|
+
export declare function resolvePaymentOptions(cfg: PaywallConfig): MerchantPaymentOption[];
|
|
198
225
|
export declare function expressPaywall(cfg: PaywallConfig): (req: any, res: any, next: any) => Promise<any>;
|
|
199
226
|
export declare function honoPaywall(cfg: PaywallConfig): (c: any, next: any) => Promise<any>;
|
|
200
227
|
export declare function nodePaywall(cfg: PaywallConfig): (req: IncomingMessage, res: ServerResponse) => Promise<Receipt | "free" | null>;
|