@seedhape/x402-merchant-sdk 0.1.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 ADDED
@@ -0,0 +1,115 @@
1
+ # @seedhape/x402-merchant-sdk
2
+
3
+ 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
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install @seedhape/x402-merchant-sdk
9
+ ```
10
+
11
+ ## Express
12
+
13
+ ```ts
14
+ import express from "express";
15
+ import { BASE_MAINNET, expressPaywall } from "@seedhape/x402-merchant-sdk";
16
+
17
+ const app = express();
18
+
19
+ app.use(expressPaywall({
20
+ ...BASE_MAINNET,
21
+ payTo: "0xYourBaseMerchantWallet",
22
+ paymentMethods: ["eip3009", "erc7710"],
23
+ price: ({ path }) => path === "/weather"
24
+ ? { amount: 50_000n, ...BASE_MAINNET }
25
+ : null,
26
+ free: ["/health", "/docs/*"],
27
+ facilitator: { url: process.env.FACILITATOR_URL! },
28
+ description: "Current weather data",
29
+ receipts: { record: async (receipt) => db.receipts.insert(receipt) },
30
+ }));
31
+
32
+ app.get("/weather", (req, res) => {
33
+ res.json({ temperature: 24, conditions: "clear", receipt: req.x402Receipt?.id });
34
+ });
35
+ ```
36
+
37
+ `price` may be a fixed `Money` object or a resolver based on the request path, method, and query. Return `null` for a free route. USDC amounts are integer base units: `50_000n` is `0.05 USDC`.
38
+
39
+ ## Network presets and payment methods
40
+
41
+ Use `BASE_MAINNET` or `BASE_SEPOLIA` to preconfigure the CAIP-2 network, USDC contract, decimals, and default facilitator:
42
+
43
+ ```ts
44
+ import { BASE_SEPOLIA, expressPaywall } from "@seedhape/x402-merchant-sdk";
45
+
46
+ app.use(expressPaywall({
47
+ ...BASE_SEPOLIA,
48
+ payTo: "0xYourStagingWallet",
49
+ paymentMethods: ["eip3009"],
50
+ price: ({ path }) => path === "/weather"
51
+ ? { amount: 10_000n, ...BASE_SEPOLIA }
52
+ : null,
53
+ }));
54
+ ```
55
+
56
+ `paymentMethods` is optional and defaults to `['eip3009']` for backward compatibility. Set `['erc7710']` to advertise only delegated payments, or `['eip3009', 'erc7710']` to let the buyer/client choose. Override `facilitator` when using a compatible provider of your choice.
57
+
58
+ ## Hono and node:http
59
+
60
+ Use `honoPaywall(config)` with Hono or `nodePaywall(config)` for a raw Node server. All adapters use the same `PaywallConfig` and facilitator contract.
61
+
62
+ ## Payment flow
63
+
64
+ 1. An unpaid request receives a `402` challenge containing the merchant wallet, USDC asset, Base network, amount, and resource URL.
65
+ 2. The buyer creates an x402 payment using EIP-3009 or another supported payment method.
66
+ 3. The facilitator verifies and settles the payment.
67
+ 4. USDC settles directly to `payTo`; Seedhape never holds merchant funds.
68
+ 5. The request continues and `req.x402Receipt` contains the settlement record.
69
+
70
+ The SDK currently emits the exact x402 challenge shape. ERC-7710 selection is handled by a compatible client/facilitator path; the merchant's responsibility is to declare an accurate recipient, asset, network, amount, and resource.
71
+
72
+ ## Bazaar discovery
73
+
74
+ Bazaar is an optional discovery layer. Add Bazaar discovery metadata to your x402 route when using an x402 resource server/facilitator that supports the Bazaar extension. Describe the input schema, route, method, and response so agents can find the service without a hardcoded URL. Bazaar does not change settlement or custody.
75
+
76
+ ## Sonar discovery
77
+
78
+ [Sonar](https://sonar.seedhape.com/) is Seedhape's service discovery surface for merchants and agents. After deploying your x402 endpoint, list it in Sonar with its public URL, HTTP method, service description, input schema, price, token, network, receiving wallet, and supported payment methods. Sonar helps agents discover and evaluate the service; it does not custody funds or settle payments. The x402 paywall and facilitator still perform verification and settlement.
79
+
80
+ Sonar listing does not replace Bazaar metadata. A merchant can publish Bazaar discovery metadata for the open x402 ecosystem and list the same endpoint in Sonar for Seedhape discovery.
81
+
82
+ ## Production checklist
83
+
84
+ - Use a self-custodial merchant receiving address.
85
+ - Use `eip155:8453` and Base USDC in production; use Base Sepolia only for testing.
86
+ - Configure a production facilitator URL and keep it server-side.
87
+ - Keep health, documentation, and discovery metadata routes free.
88
+ - Record the receipt ID, resource, payer, amount, network, and transaction hash.
89
+ - Treat `payTo`, asset, network, and resource as server-controlled values; never accept them from the buyer.
90
+
91
+ ## Publishing and full integration guide
92
+
93
+ Authenticate and verify the package:
94
+
95
+ ```bash
96
+ npm login
97
+ npm whoami
98
+ npm run typecheck
99
+ npm run build:packages
100
+ npm pack --dry-run --workspace=@seedhape/x402-merchant-sdk
101
+ ```
102
+
103
+ Publish the public scoped package:
104
+
105
+ ```bash
106
+ npm publish --workspace=@seedhape/x402-merchant-sdk --access public
107
+ ```
108
+
109
+ For local tarball testing, versioning, Bazaar metadata, and the complete release checklist, see the repository guide:
110
+
111
+ [`docs/SDK-PUBLISHING-GUIDE.md`](https://github.com/seedhape/seedhape/blob/main/docs/SDK-PUBLISHING-GUIDE.md)
112
+
113
+ ## License
114
+
115
+ MIT
@@ -0,0 +1,2 @@
1
+ export * from "./middleware.js";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export * from "./middleware.js";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC"}
@@ -0,0 +1,154 @@
1
+ /**
2
+ * Merchant SDK — the paywall.
3
+ *
4
+ * Be clear-eyed about what this part is worth: wrapping an endpoint in a 402 is
5
+ * commoditised. CloudFront does it as a config change, Stripe and Cloudflare
6
+ * both ship it. If all you need is "charge agents per call", use one of those.
7
+ *
8
+ * What this SDK adds is the merchant-side boundary after a payment lands:
9
+ * settlement receipts keyed to your own order IDs and a transport-neutral API
10
+ * for Express, Hono, and node:http services.
11
+ */
12
+ import type { IncomingMessage, ServerResponse } from "node:http";
13
+ export interface Money {
14
+ /** Base units of the asset. USDC has 6 decimals. */
15
+ amount: bigint;
16
+ asset: string;
17
+ network: string;
18
+ decimals: number;
19
+ }
20
+ export interface PriceResolver {
21
+ (req: {
22
+ path: string;
23
+ method: string;
24
+ query: URLSearchParams;
25
+ }): Money | null;
26
+ }
27
+ export interface Receipt {
28
+ id: string;
29
+ resource: string;
30
+ payer?: string;
31
+ payTo: string;
32
+ amount: bigint;
33
+ asset: string;
34
+ network: string;
35
+ txHash?: string;
36
+ /** INR paise at settlement time. */
37
+ inrPaise?: bigint;
38
+ fxRateScaled?: bigint;
39
+ settledAt: number;
40
+ /** Your own order/customer reference, if the caller supplied one. */
41
+ merchantRef?: string;
42
+ }
43
+ export interface ReceiptSink {
44
+ record(r: Receipt): Promise<void>;
45
+ }
46
+ export interface FacilitatorConfig {
47
+ /** e.g. https://x402.org/facilitator or your own. */
48
+ url: string;
49
+ apiKey?: string;
50
+ }
51
+ export type PaymentMethod = "eip3009" | "erc7710";
52
+ export interface MerchantNetworkConfig {
53
+ network: string;
54
+ asset: string;
55
+ decimals: number;
56
+ facilitator: FacilitatorConfig;
57
+ }
58
+ /** Base mainnet + USDC defaults. Override any field for a custom facilitator. */
59
+ export declare const BASE_MAINNET: MerchantNetworkConfig;
60
+ /** Base Sepolia + USDC defaults for development and staging. */
61
+ export declare const BASE_SEPOLIA: MerchantNetworkConfig;
62
+ export interface PaywallConfig {
63
+ payTo: string;
64
+ network: string;
65
+ asset: string;
66
+ decimals?: number;
67
+ /** Payment authorization methods advertised in the 402 response. */
68
+ paymentMethods?: PaymentMethod[];
69
+ /** Fixed price, or a function of the request. Return null to leave a route free. */
70
+ price: Money | PriceResolver;
71
+ facilitator: FacilitatorConfig;
72
+ receipts?: ReceiptSink;
73
+ /** INR per USDC scaled 1e8, for receipt valuation. */
74
+ fxRateScaled?: () => Promise<bigint>;
75
+ description?: string;
76
+ maxTimeoutSeconds?: number;
77
+ /** Routes that never require payment, e.g. ["/health", "/.well-known/*"]. */
78
+ free?: string[];
79
+ /**
80
+ * Settle before serving (safer, slower) or after (faster, risks serving an
81
+ * unsettled request). Default "before". Only choose "after" for idempotent
82
+ * reads where a rare free response is cheaper than the added latency.
83
+ */
84
+ settlement?: "before" | "after";
85
+ }
86
+ export interface VerifyResult {
87
+ isValid: boolean;
88
+ invalidReason?: string;
89
+ payer?: string;
90
+ }
91
+ export interface SettleResult {
92
+ success: boolean;
93
+ transaction?: string;
94
+ network?: string;
95
+ payer?: string;
96
+ errorReason?: string;
97
+ }
98
+ export declare class Facilitator {
99
+ private readonly cfg;
100
+ private readonly fetchImpl;
101
+ constructor(cfg: FacilitatorConfig, fetchImpl?: typeof fetch);
102
+ verify(payload: unknown, requirements: unknown): Promise<VerifyResult>;
103
+ settle(payload: unknown, requirements: unknown): Promise<SettleResult>;
104
+ private call;
105
+ }
106
+ export interface PaywallOutcome {
107
+ /** "free" | "challenge" | "paid" | "rejected" */
108
+ kind: "free" | "challenge" | "paid" | "rejected";
109
+ status?: number;
110
+ challenge?: unknown;
111
+ settlementHeader?: string;
112
+ receipt?: Receipt;
113
+ reason?: string;
114
+ }
115
+ export declare class Paywall {
116
+ private readonly cfg;
117
+ private readonly facilitator;
118
+ private readonly decimals;
119
+ constructor(cfg: PaywallConfig);
120
+ priceFor(path: string, method: string, query: URLSearchParams): Money | null;
121
+ buildChallenge(price: Money, resource: string): {
122
+ x402Version: number;
123
+ accepts: {
124
+ scheme: string;
125
+ network: string;
126
+ maxAmountRequired: string;
127
+ resource: string;
128
+ description: string;
129
+ mimeType: string;
130
+ payTo: string;
131
+ maxTimeoutSeconds: number;
132
+ asset: string;
133
+ extra: {
134
+ name: string;
135
+ version: string;
136
+ decimals: number;
137
+ assetTransferMethod: PaymentMethod;
138
+ };
139
+ }[];
140
+ };
141
+ handle(args: {
142
+ path: string;
143
+ method: string;
144
+ query: URLSearchParams;
145
+ resource: string;
146
+ paymentHeader: string | null;
147
+ merchantRef?: string;
148
+ }): Promise<PaywallOutcome>;
149
+ private writeReceipt;
150
+ }
151
+ export declare function expressPaywall(cfg: PaywallConfig): (req: any, res: any, next: any) => Promise<any>;
152
+ export declare function honoPaywall(cfg: PaywallConfig): (c: any, next: any) => Promise<any>;
153
+ export declare function nodePaywall(cfg: PaywallConfig): (req: IncomingMessage, res: ServerResponse) => Promise<Receipt | "free" | null>;
154
+ //# sourceMappingURL=middleware.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,286 @@
1
+ /**
2
+ * Merchant SDK — the paywall.
3
+ *
4
+ * Be clear-eyed about what this part is worth: wrapping an endpoint in a 402 is
5
+ * commoditised. CloudFront does it as a config change, Stripe and Cloudflare
6
+ * both ship it. If all you need is "charge agents per call", use one of those.
7
+ *
8
+ * What this SDK adds is the merchant-side boundary after a payment lands:
9
+ * settlement receipts keyed to your own order IDs and a transport-neutral API
10
+ * for Express, Hono, and node:http services.
11
+ */
12
+ import { randomUUID } from "node:crypto";
13
+ /** Base mainnet + USDC defaults. Override any field for a custom facilitator. */
14
+ export const BASE_MAINNET = {
15
+ network: "eip155:8453",
16
+ asset: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
17
+ decimals: 6,
18
+ facilitator: { url: "https://api.cdp.coinbase.com/platform/v2/x402" },
19
+ };
20
+ /** Base Sepolia + USDC defaults for development and staging. */
21
+ export const BASE_SEPOLIA = {
22
+ network: "eip155:84532",
23
+ asset: "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
24
+ decimals: 6,
25
+ facilitator: { url: "https://api.cdp.coinbase.com/platform/v2/x402" },
26
+ };
27
+ // ---------------------------------------------------------------------------
28
+ // Facilitator
29
+ // ---------------------------------------------------------------------------
30
+ export class Facilitator {
31
+ cfg;
32
+ fetchImpl;
33
+ constructor(cfg, fetchImpl = fetch) {
34
+ this.cfg = cfg;
35
+ this.fetchImpl = fetchImpl;
36
+ }
37
+ async verify(payload, requirements) {
38
+ return this.call("/verify", { paymentPayload: payload, paymentRequirements: requirements });
39
+ }
40
+ async settle(payload, requirements) {
41
+ return this.call("/settle", { paymentPayload: payload, paymentRequirements: requirements });
42
+ }
43
+ async call(path, body) {
44
+ const res = await this.fetchImpl(`${this.cfg.url}${path}`, {
45
+ method: "POST",
46
+ headers: {
47
+ "content-type": "application/json",
48
+ ...(this.cfg.apiKey ? { authorization: `Bearer ${this.cfg.apiKey}` } : {}),
49
+ },
50
+ body: JSON.stringify(body),
51
+ });
52
+ if (!res.ok) {
53
+ const t = await res.text();
54
+ throw new Error(`Facilitator ${path} returned ${res.status}: ${t}`);
55
+ }
56
+ return (await res.json());
57
+ }
58
+ }
59
+ export class Paywall {
60
+ cfg;
61
+ facilitator;
62
+ decimals;
63
+ constructor(cfg) {
64
+ this.cfg = cfg;
65
+ this.facilitator = new Facilitator(cfg.facilitator);
66
+ this.decimals = cfg.decimals ?? 6;
67
+ }
68
+ priceFor(path, method, query) {
69
+ if (this.cfg.free?.some((p) => matchRoute(path, p)))
70
+ return null;
71
+ const p = this.cfg.price;
72
+ return typeof p === "function" ? p({ path, method, query }) : p;
73
+ }
74
+ buildChallenge(price, resource) {
75
+ const paymentMethods = this.cfg.paymentMethods?.length
76
+ ? this.cfg.paymentMethods
77
+ : ["eip3009"];
78
+ return {
79
+ x402Version: 1,
80
+ accepts: paymentMethods.map((paymentMethod) => ({
81
+ scheme: "exact",
82
+ network: this.cfg.network,
83
+ maxAmountRequired: price.amount.toString(),
84
+ resource,
85
+ description: this.cfg.description ?? "",
86
+ mimeType: "application/json",
87
+ payTo: this.cfg.payTo,
88
+ maxTimeoutSeconds: this.cfg.maxTimeoutSeconds ?? 300,
89
+ asset: this.cfg.asset,
90
+ extra: { name: "USDC", version: "2", decimals: this.decimals, assetTransferMethod: paymentMethod },
91
+ })),
92
+ };
93
+ }
94
+ async handle(args) {
95
+ const price = this.priceFor(args.path, args.method, args.query);
96
+ if (!price || price.amount === 0n)
97
+ return { kind: "free" };
98
+ if (!args.paymentHeader) {
99
+ return {
100
+ kind: "challenge",
101
+ status: 402,
102
+ challenge: this.buildChallenge(price, args.resource),
103
+ };
104
+ }
105
+ let payload;
106
+ try {
107
+ payload = JSON.parse(Buffer.from(args.paymentHeader, "base64").toString("utf8"));
108
+ }
109
+ catch {
110
+ return { kind: "rejected", status: 400, reason: "X-PAYMENT header is not valid base64 JSON." };
111
+ }
112
+ const requirements = this.buildChallenge(price, args.resource).accepts[0];
113
+ const verified = await this.facilitator.verify(payload, requirements);
114
+ if (!verified.isValid) {
115
+ return {
116
+ kind: "rejected",
117
+ status: 402,
118
+ reason: verified.invalidReason ?? "Payment verification failed.",
119
+ challenge: this.buildChallenge(price, args.resource),
120
+ };
121
+ }
122
+ if (this.cfg.settlement === "after") {
123
+ // Caller serves first, then invokes settleLater(). Kept explicit rather
124
+ // than fire-and-forget so a failed settlement is not silently swallowed.
125
+ return { kind: "paid", receipt: undefined };
126
+ }
127
+ const settled = await this.facilitator.settle(payload, requirements);
128
+ if (!settled.success) {
129
+ return {
130
+ kind: "rejected",
131
+ status: 402,
132
+ reason: settled.errorReason ?? "Settlement failed.",
133
+ };
134
+ }
135
+ const receipt = await this.writeReceipt({
136
+ resource: args.resource,
137
+ price,
138
+ settled,
139
+ payer: verified.payer ?? settled.payer,
140
+ merchantRef: args.merchantRef,
141
+ });
142
+ return {
143
+ kind: "paid",
144
+ receipt,
145
+ settlementHeader: Buffer.from(JSON.stringify(settled), "utf8").toString("base64"),
146
+ };
147
+ }
148
+ async writeReceipt(args) {
149
+ let inrPaise;
150
+ let fxRateScaled;
151
+ if (this.cfg.fxRateScaled) {
152
+ try {
153
+ fxRateScaled = await this.cfg.fxRateScaled();
154
+ inrPaise =
155
+ (args.price.amount * fxRateScaled * 100n) /
156
+ (10n ** BigInt(this.decimals) * 100000000n);
157
+ }
158
+ catch {
159
+ // A missing FX rate must not fail a settled payment. Backfill later.
160
+ }
161
+ }
162
+ const receipt = {
163
+ id: randomUUID(),
164
+ resource: args.resource,
165
+ payer: args.payer,
166
+ payTo: this.cfg.payTo,
167
+ amount: args.price.amount,
168
+ asset: this.cfg.asset,
169
+ network: this.cfg.network,
170
+ txHash: args.settled.transaction,
171
+ inrPaise,
172
+ fxRateScaled,
173
+ settledAt: Math.floor(Date.now() / 1000),
174
+ merchantRef: args.merchantRef,
175
+ };
176
+ await this.cfg.receipts?.record(receipt);
177
+ return receipt;
178
+ }
179
+ }
180
+ // ---------------------------------------------------------------------------
181
+ // Express adapter
182
+ // ---------------------------------------------------------------------------
183
+ /* eslint-disable @typescript-eslint/no-explicit-any */
184
+ export function expressPaywall(cfg) {
185
+ const paywall = new Paywall(cfg);
186
+ return async function middleware(req, res, next) {
187
+ try {
188
+ const url = new URL(req.originalUrl ?? req.url, `http://${req.headers.host ?? "localhost"}`);
189
+ const outcome = await paywall.handle({
190
+ path: url.pathname,
191
+ method: req.method,
192
+ query: url.searchParams,
193
+ resource: url.toString(),
194
+ paymentHeader: req.headers["x-payment"] ?? null,
195
+ merchantRef: req.headers["x-merchant-ref"],
196
+ });
197
+ switch (outcome.kind) {
198
+ case "free":
199
+ return next();
200
+ case "challenge":
201
+ res.status(402).json(outcome.challenge);
202
+ return;
203
+ case "rejected":
204
+ res.status(outcome.status ?? 402).json({
205
+ error: outcome.reason,
206
+ ...(outcome.challenge ?? {}),
207
+ });
208
+ return;
209
+ case "paid":
210
+ if (outcome.settlementHeader) {
211
+ res.setHeader("X-PAYMENT-RESPONSE", outcome.settlementHeader);
212
+ res.setHeader("Access-Control-Expose-Headers", "X-PAYMENT-RESPONSE");
213
+ }
214
+ req.x402Receipt = outcome.receipt;
215
+ return next();
216
+ }
217
+ }
218
+ catch (e) {
219
+ next(e);
220
+ }
221
+ };
222
+ }
223
+ // ---------------------------------------------------------------------------
224
+ // Hono / Fetch-API adapter
225
+ // ---------------------------------------------------------------------------
226
+ export function honoPaywall(cfg) {
227
+ const paywall = new Paywall(cfg);
228
+ return async function middleware(c, next) {
229
+ const url = new URL(c.req.url);
230
+ const outcome = await paywall.handle({
231
+ path: url.pathname,
232
+ method: c.req.method,
233
+ query: url.searchParams,
234
+ resource: url.toString(),
235
+ paymentHeader: c.req.header("x-payment") ?? null,
236
+ merchantRef: c.req.header("x-merchant-ref"),
237
+ });
238
+ if (outcome.kind === "free")
239
+ return next();
240
+ if (outcome.kind === "challenge")
241
+ return c.json(outcome.challenge, 402);
242
+ if (outcome.kind === "rejected") {
243
+ return c.json({ error: outcome.reason, ...(outcome.challenge ?? {}) }, (outcome.status ?? 402));
244
+ }
245
+ c.set("x402Receipt", outcome.receipt);
246
+ await next();
247
+ if (outcome.settlementHeader) {
248
+ c.res.headers.set("X-PAYMENT-RESPONSE", outcome.settlementHeader);
249
+ c.res.headers.set("Access-Control-Expose-Headers", "X-PAYMENT-RESPONSE");
250
+ }
251
+ };
252
+ }
253
+ // ---------------------------------------------------------------------------
254
+ // Raw node:http adapter, for anything else
255
+ // ---------------------------------------------------------------------------
256
+ export function nodePaywall(cfg) {
257
+ const paywall = new Paywall(cfg);
258
+ return async function guard(req, res) {
259
+ const url = new URL(req.url ?? "/", `http://${req.headers.host ?? "localhost"}`);
260
+ const outcome = await paywall.handle({
261
+ path: url.pathname,
262
+ method: req.method ?? "GET",
263
+ query: url.searchParams,
264
+ resource: url.toString(),
265
+ paymentHeader: req.headers["x-payment"] ?? null,
266
+ });
267
+ if (outcome.kind === "free")
268
+ return "free";
269
+ if (outcome.kind === "paid") {
270
+ if (outcome.settlementHeader) {
271
+ res.setHeader("X-PAYMENT-RESPONSE", outcome.settlementHeader);
272
+ }
273
+ return outcome.receipt ?? null;
274
+ }
275
+ res.statusCode = outcome.status ?? 402;
276
+ res.setHeader("content-type", "application/json");
277
+ res.end(JSON.stringify(outcome.challenge ?? { error: outcome.reason }));
278
+ return null;
279
+ };
280
+ }
281
+ function matchRoute(path, pattern) {
282
+ if (pattern.endsWith("/*"))
283
+ return path.startsWith(pattern.slice(0, -1));
284
+ return path === pattern;
285
+ }
286
+ //# sourceMappingURL=middleware.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"middleware.js","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,16 @@
1
+ {
2
+ "name": "@seedhape/x402-merchant-sdk",
3
+ "version": "0.1.0",
4
+ "description": "Add x402 payment-gated routes, settlement receipts, and merchant accounting to Node.js services.",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": { ".": { "types": "./dist/index.d.ts", "import": "./dist/index.js" } },
9
+ "files": ["dist", "README.md"],
10
+ "keywords": ["x402", "payments", "usdc", "base", "merchant", "paywall", "api", "agents"],
11
+ "license": "MIT",
12
+ "repository": { "type": "git", "url": "https://github.com/seedhape/seedhape.git", "directory": "packages/merchant-sdk" },
13
+ "bugs": { "url": "https://github.com/seedhape/seedhape/issues" },
14
+ "publishConfig": { "access": "public" },
15
+ "dependencies": {}
16
+ }