@apitoll/seller-sdk 0.1.0-beta.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/README.md ADDED
@@ -0,0 +1,131 @@
1
+ # @apitoll/seller-sdk
2
+
3
+ Monetize any API with x402 micropayments. Add per-request USDC payments in 3 lines of code.
4
+
5
+ Built on the [x402 HTTP Payment Protocol](https://www.x402.org/) — settled instantly on Base.
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ npm install @apitoll/seller-sdk
11
+ ```
12
+
13
+ ## Quick Start (Express)
14
+
15
+ ```ts
16
+ import express from "express";
17
+ import { paymentMiddleware } from "@apitoll/seller-sdk";
18
+
19
+ const app = express();
20
+
21
+ app.use(paymentMiddleware({
22
+ walletAddress: "0xYourWallet...",
23
+ endpoints: {
24
+ "GET /api/data": {
25
+ price: "0.001",
26
+ chains: ["base"],
27
+ description: "Premium data feed",
28
+ },
29
+ },
30
+ }));
31
+
32
+ app.get("/api/data", (req, res) => {
33
+ res.json({ data: "You paid for this!" });
34
+ });
35
+
36
+ app.listen(3000);
37
+ ```
38
+
39
+ ## Quick Start (Hono)
40
+
41
+ ```ts
42
+ import { Hono } from "hono";
43
+ import { honoPaymentMiddleware } from "@apitoll/seller-sdk";
44
+
45
+ const app = new Hono();
46
+
47
+ app.use("*", honoPaymentMiddleware({
48
+ walletAddress: "0xYourWallet...",
49
+ endpoints: {
50
+ "GET /api/joke": {
51
+ price: "0.001",
52
+ chains: ["base"],
53
+ },
54
+ },
55
+ }));
56
+ ```
57
+
58
+ ## How It Works
59
+
60
+ 1. Agent requests your API endpoint
61
+ 2. Middleware returns `402 Payment Required` with USDC price and chain info
62
+ 3. Agent pays via the x402 facilitator
63
+ 4. Agent retries with `X-PAYMENT` header containing the signed payment
64
+ 5. Middleware verifies payment and lets the request through
65
+ 6. You get paid instantly in USDC on Base
66
+
67
+ ## Features
68
+
69
+ - **Express & Hono** middleware out of the box
70
+ - **Per-endpoint pricing** — different prices for different routes
71
+ - **Multi-chain** — Base and Solana support
72
+ - **Platform fees** — automatic fee splitting (3% default)
73
+ - **Analytics** — built-in transaction reporting to the API Toll dashboard
74
+ - **Rate limiting** — optional Redis-backed rate limiting
75
+ - **Circuit breaker** — automatic protection against payment verification failures
76
+
77
+ ## Platform Fee Splitting
78
+
79
+ ```ts
80
+ app.use(paymentMiddleware({
81
+ walletAddress: "0xYourWallet...",
82
+ endpoints: { ... },
83
+ platformFee: {
84
+ feeBps: 300, // 3%
85
+ feeCollector: "0xPlatformWallet...",
86
+ },
87
+ }));
88
+ ```
89
+
90
+ ## Analytics Reporting
91
+
92
+ ```ts
93
+ import { AnalyticsReporter } from "@apitoll/seller-sdk";
94
+
95
+ const reporter = new AnalyticsReporter({
96
+ apiKey: "your-seller-api-key",
97
+ dashboardUrl: "https://cheery-parrot-104.convex.cloud",
98
+ });
99
+
100
+ // Transactions are automatically batched and reported
101
+ ```
102
+
103
+ ## API Reference
104
+
105
+ ### `paymentMiddleware(config)`
106
+ Express middleware. Intercepts requests, returns 402 for unpaid endpoints, verifies payments.
107
+
108
+ ### `honoPaymentMiddleware(config)`
109
+ Same as above, but for Hono framework.
110
+
111
+ ### `buildPaymentRequirements(endpoint, config)`
112
+ Build x402-compliant payment requirement objects.
113
+
114
+ ### `verifyPayment(header, requirements)`
115
+ Verify a signed payment header against requirements.
116
+
117
+ ### `AnalyticsReporter`
118
+ Batch transaction reporter for the API Toll dashboard.
119
+
120
+ ## Part of API Toll
121
+
122
+ API Toll is the payment infrastructure for autonomous AI agents. Learn more:
123
+
124
+ - [apitoll.com](https://apitoll.com) — Dashboard & marketplace
125
+ - [`@apitoll/buyer-sdk`](https://www.npmjs.com/package/@apitoll/buyer-sdk) — For AI agent builders
126
+ - [x402 Protocol](https://www.x402.org/) — The HTTP payment standard
127
+ - [GitHub](https://github.com/TasnidChain/APITOLL)
128
+
129
+ ## License
130
+
131
+ MIT
@@ -0,0 +1,62 @@
1
+ import { type PaymentReceipt, type FeeBreakdown } from "@apitoll/shared";
2
+ export interface ReporterConfig {
3
+ /** Platform API key for authentication */
4
+ apiKey?: string;
5
+ /** Seller ID on the platform */
6
+ sellerId?: string;
7
+ /** Custom platform API URL */
8
+ platformUrl?: string;
9
+ /** Webhook URL for real-time notifications */
10
+ webhookUrl?: string;
11
+ /** Webhook signing secret for HMAC-SHA256 verification */
12
+ webhookSecret?: string;
13
+ /** Enable local logging */
14
+ verbose?: boolean;
15
+ }
16
+ export interface TransactionReport {
17
+ /** The endpoint that was called */
18
+ endpoint: string;
19
+ /** HTTP method */
20
+ method: string;
21
+ /** Payment receipt from verification */
22
+ receipt: PaymentReceipt;
23
+ /** Response HTTP status */
24
+ responseStatus: number;
25
+ /** Request-to-response latency in ms */
26
+ latencyMs: number;
27
+ /** Fee breakdown (if platform fee enabled) */
28
+ feeBreakdown?: FeeBreakdown;
29
+ }
30
+ /**
31
+ * Analytics reporter that sends transaction data to the Apitoll platform.
32
+ * Now includes platform fee tracking for revenue reporting.
33
+ * Falls back to local logging if no API key is configured.
34
+ */
35
+ export declare class AnalyticsReporter {
36
+ private config;
37
+ private queue;
38
+ private flushTimer;
39
+ constructor(config?: ReporterConfig);
40
+ /**
41
+ * Report a completed transaction (with optional fee breakdown).
42
+ */
43
+ report(report: TransactionReport): Promise<void>;
44
+ /**
45
+ * Report a failed/rejected payment (no receipt).
46
+ */
47
+ reportRejection(endpoint: string, method: string, reason: string): Promise<void>;
48
+ /**
49
+ * Flush queued transactions to the platform.
50
+ */
51
+ private flush;
52
+ /**
53
+ * Send a real-time webhook notification to the Apitoll platform (Convex).
54
+ * Formats the transaction in the Convex /webhook/transactions format.
55
+ */
56
+ private sendWebhook;
57
+ /**
58
+ * Cleanup: flush remaining transactions and clear timer.
59
+ */
60
+ destroy(): Promise<void>;
61
+ }
62
+ //# sourceMappingURL=analytics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analytics.d.ts","sourceRoot":"","sources":["../src/analytics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,KAAK,cAAc,EAAE,KAAK,YAAY,EAAoC,MAAM,iBAAiB,CAAC;AAI7H,MAAM,WAAW,cAAc;IAC7B,0CAA0C;IAC1C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gCAAgC;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,8BAA8B;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8CAA8C;IAC9C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0DAA0D;IAC1D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,2BAA2B;IAC3B,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,mCAAmC;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,kBAAkB;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,wCAAwC;IACxC,OAAO,EAAE,cAAc,CAAC;IACxB,2BAA2B;IAC3B,cAAc,EAAE,MAAM,CAAC;IACvB,wCAAwC;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,8CAA8C;IAC9C,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B;AASD;;;;GAIG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,KAAK,CAA4B;IACzC,OAAO,CAAC,UAAU,CAA+C;gBAErD,MAAM,GAAE,cAAmB;IAavC;;OAEG;IACG,MAAM,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAgDtD;;OAEG;IACG,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMtF;;OAEG;YACW,KAAK;IA6BnB;;;OAGG;YACW,WAAW;IAyCzB;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAO/B"}
@@ -0,0 +1,157 @@
1
+ import { generateId, computeHmacSignature } from "@apitoll/shared";
2
+ const PLATFORM_API_URL = "https://api.apitoll.com";
3
+ /**
4
+ * Analytics reporter that sends transaction data to the Apitoll platform.
5
+ * Now includes platform fee tracking for revenue reporting.
6
+ * Falls back to local logging if no API key is configured.
7
+ */
8
+ export class AnalyticsReporter {
9
+ config;
10
+ queue = [];
11
+ flushTimer = null;
12
+ constructor(config = {}) {
13
+ this.config = {
14
+ platformUrl: PLATFORM_API_URL,
15
+ verbose: false,
16
+ ...config,
17
+ };
18
+ // Batch flush every 5 seconds
19
+ if (this.config.apiKey) {
20
+ this.flushTimer = setInterval(() => this.flush(), 5000);
21
+ }
22
+ }
23
+ /**
24
+ * Report a completed transaction (with optional fee breakdown).
25
+ */
26
+ async report(report) {
27
+ const transaction = {
28
+ id: generateId("tx"),
29
+ txHash: report.receipt.txHash,
30
+ agentAddress: report.receipt.from,
31
+ sellerId: this.config.sellerId || "unknown",
32
+ endpoint: report.endpoint,
33
+ method: report.method,
34
+ amount: report.receipt.amount,
35
+ chain: report.receipt.chain,
36
+ status: report.responseStatus < 400 ? "settled" : "failed",
37
+ requestedAt: report.receipt.timestamp,
38
+ settledAt: report.receipt.timestamp,
39
+ responseStatus: report.responseStatus,
40
+ latencyMs: report.latencyMs,
41
+ // Fee tracking
42
+ platformFee: report.feeBreakdown?.platformFee,
43
+ sellerAmount: report.feeBreakdown?.sellerAmount,
44
+ feeBps: report.feeBreakdown?.feeBps,
45
+ };
46
+ if (this.config.verbose) {
47
+ const feeInfo = report.feeBreakdown
48
+ ? ` fee=$${report.feeBreakdown.platformFee} seller=$${report.feeBreakdown.sellerAmount}`
49
+ : "";
50
+ console.log(`[apitoll] tx=${transaction.id} endpoint=${transaction.endpoint} amount=$${transaction.amount}${feeInfo} chain=${transaction.chain} status=${transaction.status}`);
51
+ }
52
+ // Queue for batch send
53
+ this.queue.push(transaction);
54
+ // Send webhook immediately if configured
55
+ if (this.config.webhookUrl) {
56
+ this.sendWebhook(transaction).catch((err) => {
57
+ if (this.config.verbose) {
58
+ console.error(`[apitoll] webhook error:`, err);
59
+ }
60
+ });
61
+ }
62
+ // Flush immediately if queue is large
63
+ if (this.queue.length >= 50) {
64
+ await this.flush();
65
+ }
66
+ }
67
+ /**
68
+ * Report a failed/rejected payment (no receipt).
69
+ */
70
+ async reportRejection(endpoint, method, reason) {
71
+ if (this.config.verbose) {
72
+ console.log(`[apitoll] rejected endpoint=${endpoint} reason=${reason}`);
73
+ }
74
+ }
75
+ /**
76
+ * Flush queued transactions to the platform.
77
+ */
78
+ async flush() {
79
+ if (this.queue.length === 0)
80
+ return;
81
+ if (!this.config.apiKey) {
82
+ this.queue = [];
83
+ return;
84
+ }
85
+ const batch = this.queue.splice(0, this.queue.length);
86
+ try {
87
+ await fetch(`${this.config.platformUrl}/v1/transactions/batch`, {
88
+ method: "POST",
89
+ headers: {
90
+ "Content-Type": "application/json",
91
+ Authorization: `Bearer ${this.config.apiKey}`,
92
+ },
93
+ body: JSON.stringify({ transactions: batch }),
94
+ });
95
+ }
96
+ catch (err) {
97
+ // Re-queue on failure (with limit to prevent memory leaks)
98
+ if (this.queue.length < 500) {
99
+ this.queue.unshift(...batch);
100
+ }
101
+ if (this.config.verbose) {
102
+ console.error(`[apitoll] flush error:`, err);
103
+ }
104
+ }
105
+ }
106
+ /**
107
+ * Send a real-time webhook notification to the Apitoll platform (Convex).
108
+ * Formats the transaction in the Convex /webhook/transactions format.
109
+ */
110
+ async sendWebhook(transaction) {
111
+ if (!this.config.webhookUrl)
112
+ return;
113
+ const body = JSON.stringify({
114
+ transactions: [
115
+ {
116
+ txHash: transaction.txHash,
117
+ agentAddress: transaction.agentAddress,
118
+ endpointPath: transaction.endpoint,
119
+ method: transaction.method,
120
+ amount: parseFloat(transaction.amount),
121
+ chain: transaction.chain,
122
+ status: transaction.status,
123
+ latencyMs: transaction.latencyMs,
124
+ requestedAt: transaction.requestedAt,
125
+ },
126
+ ],
127
+ });
128
+ const headers = {
129
+ "Content-Type": "application/json",
130
+ };
131
+ // Include seller API key for Convex authentication
132
+ if (this.config.apiKey) {
133
+ headers["X-Seller-Key"] = this.config.apiKey;
134
+ }
135
+ // Sign webhook payload if secret is configured
136
+ if (this.config.webhookSecret) {
137
+ const signature = await computeHmacSignature(body, this.config.webhookSecret);
138
+ headers["X-Webhook-Signature"] = signature;
139
+ }
140
+ await fetch(this.config.webhookUrl, {
141
+ method: "POST",
142
+ headers,
143
+ body,
144
+ });
145
+ }
146
+ /**
147
+ * Cleanup: flush remaining transactions and clear timer.
148
+ */
149
+ async destroy() {
150
+ if (this.flushTimer) {
151
+ clearInterval(this.flushTimer);
152
+ this.flushTimer = null;
153
+ }
154
+ await this.flush();
155
+ }
156
+ }
157
+ //# sourceMappingURL=analytics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analytics.js","sourceRoot":"","sources":["../src/analytics.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=analytics.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analytics.test.d.ts","sourceRoot":"","sources":["../src/analytics.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,222 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
2
+ import { AnalyticsReporter } from "./analytics";
3
+ import { verifyHmacSignature } from "@apitoll/shared";
4
+ const TEST_RECEIPT = {
5
+ txHash: "0xabc123",
6
+ chain: "base",
7
+ amount: "0.005000",
8
+ from: "0xPayer",
9
+ to: "0xSeller",
10
+ timestamp: new Date().toISOString(),
11
+ };
12
+ function makeReport(overrides = {}) {
13
+ return {
14
+ endpoint: "GET /api/data",
15
+ method: "GET",
16
+ receipt: TEST_RECEIPT,
17
+ responseStatus: 200,
18
+ latencyMs: 50,
19
+ ...overrides,
20
+ };
21
+ }
22
+ // ─── Tests using fake timers (batch/flush/retry) ────────────────
23
+ describe("AnalyticsReporter (batching)", () => {
24
+ const mockFetch = vi.fn();
25
+ beforeEach(() => {
26
+ vi.stubGlobal("fetch", mockFetch);
27
+ mockFetch.mockResolvedValue({ ok: true });
28
+ vi.useFakeTimers({ shouldAdvanceTime: true });
29
+ });
30
+ afterEach(() => {
31
+ vi.restoreAllMocks();
32
+ vi.useRealTimers();
33
+ });
34
+ it("queues transactions and flushes on interval", async () => {
35
+ const reporter = new AnalyticsReporter({
36
+ apiKey: "test-key",
37
+ platformUrl: "https://test-api.com",
38
+ });
39
+ await reporter.report(makeReport());
40
+ await vi.advanceTimersByTimeAsync(5000);
41
+ const batchCall = mockFetch.mock.calls.find((c) => c[0].includes("/v1/transactions/batch"));
42
+ expect(batchCall).toBeDefined();
43
+ expect(batchCall[1].headers.Authorization).toBe("Bearer test-key");
44
+ await reporter.destroy();
45
+ });
46
+ it("flushes immediately when queue hits 50", async () => {
47
+ const reporter = new AnalyticsReporter({
48
+ apiKey: "test-key",
49
+ platformUrl: "https://test-api.com",
50
+ });
51
+ for (let i = 0; i < 50; i++) {
52
+ await reporter.report(makeReport());
53
+ }
54
+ const batchCall = mockFetch.mock.calls.find((c) => c[0].includes("/v1/transactions/batch"));
55
+ expect(batchCall).toBeDefined();
56
+ await reporter.destroy();
57
+ });
58
+ it("discards queue when no API key is configured", async () => {
59
+ const reporter = new AnalyticsReporter({
60
+ platformUrl: "https://test-api.com",
61
+ });
62
+ await reporter.report(makeReport());
63
+ const batchCalls = mockFetch.mock.calls.filter((c) => c[0]?.includes?.("/v1/transactions/batch"));
64
+ expect(batchCalls).toHaveLength(0);
65
+ await reporter.destroy();
66
+ });
67
+ it("marks 2xx responses as settled", async () => {
68
+ const reporter = new AnalyticsReporter({
69
+ apiKey: "key",
70
+ platformUrl: "https://test-api.com",
71
+ });
72
+ await reporter.report(makeReport({ responseStatus: 200 }));
73
+ await vi.advanceTimersByTimeAsync(5000);
74
+ const body = JSON.parse(mockFetch.mock.calls.find((c) => c[0].includes("/v1/transactions/batch"))[1].body);
75
+ expect(body.transactions[0].status).toBe("settled");
76
+ await reporter.destroy();
77
+ });
78
+ it("marks 4xx/5xx responses as failed", async () => {
79
+ const reporter = new AnalyticsReporter({
80
+ apiKey: "key",
81
+ platformUrl: "https://test-api.com",
82
+ });
83
+ await reporter.report(makeReport({ responseStatus: 500 }));
84
+ await vi.advanceTimersByTimeAsync(5000);
85
+ const body = JSON.parse(mockFetch.mock.calls.find((c) => c[0].includes("/v1/transactions/batch"))[1].body);
86
+ expect(body.transactions[0].status).toBe("failed");
87
+ await reporter.destroy();
88
+ });
89
+ it("includes fee breakdown in transaction data", async () => {
90
+ const reporter = new AnalyticsReporter({
91
+ apiKey: "key",
92
+ platformUrl: "https://test-api.com",
93
+ });
94
+ await reporter.report(makeReport({
95
+ feeBreakdown: {
96
+ totalAmount: "0.005000",
97
+ sellerAmount: "0.004850",
98
+ platformFee: "0.000150",
99
+ feeBps: 300,
100
+ },
101
+ }));
102
+ await vi.advanceTimersByTimeAsync(5000);
103
+ const body = JSON.parse(mockFetch.mock.calls.find((c) => c[0].includes("/v1/transactions/batch"))[1].body);
104
+ expect(body.transactions[0].platformFee).toBe("0.000150");
105
+ expect(body.transactions[0].sellerAmount).toBe("0.004850");
106
+ expect(body.transactions[0].feeBps).toBe(300);
107
+ await reporter.destroy();
108
+ });
109
+ it("re-queues transactions on flush failure", async () => {
110
+ mockFetch.mockRejectedValueOnce(new Error("Server down"));
111
+ mockFetch.mockResolvedValueOnce({ ok: true });
112
+ const reporter = new AnalyticsReporter({
113
+ apiKey: "key",
114
+ platformUrl: "https://test-api.com",
115
+ });
116
+ await reporter.report(makeReport());
117
+ await vi.advanceTimersByTimeAsync(5000);
118
+ await vi.advanceTimersByTimeAsync(5000);
119
+ const batchCalls = mockFetch.mock.calls.filter((c) => c[0].includes("/v1/transactions/batch"));
120
+ expect(batchCalls.length).toBeGreaterThanOrEqual(2);
121
+ await reporter.destroy();
122
+ });
123
+ it("flushes remaining queue on destroy", async () => {
124
+ const reporter = new AnalyticsReporter({
125
+ apiKey: "key",
126
+ platformUrl: "https://test-api.com",
127
+ });
128
+ await reporter.report(makeReport());
129
+ await reporter.destroy();
130
+ const batchCall = mockFetch.mock.calls.find((c) => c[0].includes("/v1/transactions/batch"));
131
+ expect(batchCall).toBeDefined();
132
+ });
133
+ it("clears flush timer on destroy", async () => {
134
+ const reporter = new AnalyticsReporter({ apiKey: "key" });
135
+ await reporter.destroy();
136
+ await vi.advanceTimersByTimeAsync(10000);
137
+ // No errors — timer was cleaned up
138
+ });
139
+ });
140
+ // ─── Tests using real timers (webhook / HMAC) ───────────────────
141
+ describe("AnalyticsReporter (webhooks)", () => {
142
+ const mockFetch = vi.fn();
143
+ beforeEach(() => {
144
+ vi.stubGlobal("fetch", mockFetch);
145
+ mockFetch.mockResolvedValue({ ok: true });
146
+ });
147
+ afterEach(() => {
148
+ vi.restoreAllMocks();
149
+ });
150
+ it("sends webhook immediately when configured", async () => {
151
+ const reporter = new AnalyticsReporter({
152
+ webhookUrl: "https://hooks.example.com/tx",
153
+ });
154
+ await reporter.report(makeReport());
155
+ // Webhook is fire-and-forget but without HMAC it's synchronous fetch call
156
+ // Give the microtask queue a tick
157
+ await new Promise((r) => setTimeout(r, 20));
158
+ const webhookCall = mockFetch.mock.calls.find((c) => c[0] === "https://hooks.example.com/tx");
159
+ expect(webhookCall).toBeDefined();
160
+ const body = JSON.parse(webhookCall[1].body);
161
+ expect(body.type).toBe("transaction.settled");
162
+ expect(body.data.txHash).toBe("0xabc123");
163
+ await reporter.destroy();
164
+ });
165
+ it("does not send webhook when not configured", async () => {
166
+ const reporter = new AnalyticsReporter({});
167
+ await reporter.report(makeReport());
168
+ expect(mockFetch).not.toHaveBeenCalled();
169
+ await reporter.destroy();
170
+ });
171
+ it("includes HMAC signature when webhookSecret is set", async () => {
172
+ // Capture the webhook call via a deferred promise
173
+ let capturedArgs = null;
174
+ let resolveCapture;
175
+ const captured = new Promise((resolve) => { resolveCapture = resolve; });
176
+ mockFetch.mockImplementation((...args) => {
177
+ capturedArgs = args;
178
+ resolveCapture();
179
+ return Promise.resolve({ ok: true });
180
+ });
181
+ const secret = "my-webhook-secret";
182
+ const reporter = new AnalyticsReporter({
183
+ webhookUrl: "https://hooks.example.com/tx",
184
+ webhookSecret: secret,
185
+ });
186
+ // Don't await report — it fires webhook as fire-and-forget
187
+ reporter.report(makeReport());
188
+ // Wait for the async webhook (HMAC computation + fetch) to complete
189
+ await captured;
190
+ expect(capturedArgs).not.toBeNull();
191
+ expect(capturedArgs[0]).toBe("https://hooks.example.com/tx");
192
+ const headers = capturedArgs[1].headers;
193
+ const signature = headers["X-Webhook-Signature"];
194
+ expect(signature).toBeDefined();
195
+ expect(signature).toMatch(/^[a-f0-9]{64}$/);
196
+ // Verify the signature matches the payload
197
+ const body = capturedArgs[1].body;
198
+ const isValid = await verifyHmacSignature(body, secret, signature);
199
+ expect(isValid).toBe(true);
200
+ await reporter.destroy();
201
+ });
202
+ it("does not include signature header when no secret", async () => {
203
+ const reporter = new AnalyticsReporter({
204
+ webhookUrl: "https://hooks.example.com/tx",
205
+ });
206
+ await reporter.report(makeReport());
207
+ await new Promise((r) => setTimeout(r, 20));
208
+ const webhookCall = mockFetch.mock.calls.find((c) => c[0] === "https://hooks.example.com/tx");
209
+ expect(webhookCall[1].headers["X-Webhook-Signature"]).toBeUndefined();
210
+ await reporter.destroy();
211
+ });
212
+ it("swallows webhook errors without crashing", async () => {
213
+ mockFetch.mockRejectedValueOnce(new Error("Network error"));
214
+ const reporter = new AnalyticsReporter({
215
+ webhookUrl: "https://hooks.example.com/tx",
216
+ verbose: false,
217
+ });
218
+ await expect(reporter.report(makeReport())).resolves.not.toThrow();
219
+ await reporter.destroy();
220
+ });
221
+ });
222
+ //# sourceMappingURL=analytics.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analytics.test.js","sourceRoot":"","sources":["../src/analytics.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export { paymentMiddleware, getPaymentReceipt, getX402Context } from "./middleware-express";
2
+ export { paymentMiddleware as honoPaymentMiddleware } from "./middleware-hono";
3
+ export { buildPaymentRequirements, encodePaymentRequired, verifyPayment, findEndpointConfig, getEndpointFeeBreakdown, type VerifyPaymentOptions, type VerificationResult, } from "./payment";
4
+ export { AnalyticsReporter, type ReporterConfig, type TransactionReport } from "./analytics";
5
+ export type { SellerConfig, EndpointConfig, EndpointRegistry, PaymentRequirement, PaymentReceipt, SupportedChain, ChainConfig, PlatformFeeConfig, FeeBreakdown, PlanTier, PlanLimits, } from "@apitoll/shared";
6
+ export { calculateFeeBreakdown, getPlatformWallet, getPlanLimits, checkPlanLimit, PLAN_LIMITS, } from "@apitoll/shared";
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC5F,OAAO,EAAE,iBAAiB,IAAI,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAG/E,OAAO,EACL,wBAAwB,EACxB,qBAAqB,EACrB,aAAa,EACb,kBAAkB,EAClB,uBAAuB,EACvB,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,GACxB,MAAM,WAAW,CAAC;AAGnB,OAAO,EAAE,iBAAiB,EAAE,KAAK,cAAc,EAAE,KAAK,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAG7F,YAAY,EACV,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,kBAAkB,EAClB,cAAc,EACd,cAAc,EACd,WAAW,EACX,iBAAiB,EACjB,YAAY,EACZ,QAAQ,EACR,UAAU,GACX,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EACL,qBAAqB,EACrB,iBAAiB,EACjB,aAAa,EACb,cAAc,EACd,WAAW,GACZ,MAAM,iBAAiB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,10 @@
1
+ // Core exports
2
+ export { paymentMiddleware, getPaymentReceipt, getX402Context } from "./middleware-express";
3
+ export { paymentMiddleware as honoPaymentMiddleware } from "./middleware-hono";
4
+ // Payment utilities
5
+ export { buildPaymentRequirements, encodePaymentRequired, verifyPayment, findEndpointConfig, getEndpointFeeBreakdown, } from "./payment";
6
+ // Analytics
7
+ export { AnalyticsReporter } from "./analytics";
8
+ // Re-export shared utilities
9
+ export { calculateFeeBreakdown, getPlatformWallet, getPlanLimits, checkPlanLimit, PLAN_LIMITS, } from "@apitoll/shared";
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,eAAe;AACf,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC5F,OAAO,EAAE,iBAAiB,IAAI,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAE/E,oBAAoB;AACpB,OAAO,EACL,wBAAwB,EACxB,qBAAqB,EACrB,aAAa,EACb,kBAAkB,EAClB,uBAAuB,GAGxB,MAAM,WAAW,CAAC;AAEnB,YAAY;AACZ,OAAO,EAAE,iBAAiB,EAA+C,MAAM,aAAa,CAAC;AAiB7F,6BAA6B;AAC7B,OAAO,EACL,qBAAqB,EACrB,iBAAiB,EACjB,aAAa,EACb,cAAc,EACd,WAAW,GACZ,MAAM,iBAAiB,CAAC"}