@analytix402/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,158 @@
1
+ # @analytix402/sdk
2
+
3
+ Monitor, secure, and optimize your x402 APIs. Drop-in Express middleware that captures requests, payments, and performance data — viewable on [analytix402.com](https://analytix402.com).
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @analytix402/sdk
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ```typescript
14
+ import express from 'express';
15
+ import { Analytix402 } from '@analytix402/sdk';
16
+
17
+ const app = express();
18
+
19
+ // Add Analytix402 middleware (before your routes)
20
+ app.use(Analytix402({
21
+ apiKey: 'ax_live_your_key_here',
22
+ }));
23
+
24
+ // Your x402 routes
25
+ app.get('/api/data', (req, res) => {
26
+ res.json({ data: 'Hello World' });
27
+ });
28
+
29
+ app.listen(3000);
30
+ ```
31
+
32
+ That's it! Revenue, requests, and security data will appear in your [Analytix402 dashboard](https://analytix402.com/dashboard.html).
33
+
34
+ ## What Gets Tracked
35
+
36
+ The SDK automatically captures:
37
+
38
+ - **Request data**: Method, path, status code, response time
39
+ - **Payment data**: Amount, currency, payer wallet (from x402 headers)
40
+ - **Metadata**: IP address, user agent, timestamp
41
+
42
+ All data is batched and sent asynchronously — your API response times are not affected.
43
+
44
+ ## Configuration
45
+
46
+ ```typescript
47
+ app.use(Analytix402({
48
+ // Required: Your API key from the Analytix402 dashboard
49
+ apiKey: 'ax_live_xxxxx',
50
+
51
+ // Optional: Custom API endpoint (for self-hosted)
52
+ baseUrl: 'https://api.analytix402.com',
53
+
54
+ // Optional: Enable debug logging
55
+ debug: false,
56
+
57
+ // Optional: Batch size before sending (default: 100)
58
+ batchSize: 100,
59
+
60
+ // Optional: Flush interval in ms (default: 5000)
61
+ flushInterval: 5000,
62
+
63
+ // Optional: Max retries for failed requests (default: 3)
64
+ maxRetries: 3,
65
+
66
+ // Optional: Max events to queue offline (default: 1000)
67
+ maxQueueSize: 1000,
68
+
69
+ // Optional: Request timeout in ms (default: 10000)
70
+ timeout: 10000,
71
+
72
+ // Optional: Paths to exclude from tracking
73
+ excludePaths: ['/health', '/internal/*'],
74
+
75
+ // Optional: Custom endpoint naming
76
+ getEndpointName: (req) => {
77
+ // Group by route pattern instead of full path
78
+ return req.path.replace(/\/[0-9a-f-]+/g, '/:id');
79
+ },
80
+
81
+ // Optional: Custom filtering
82
+ shouldTrack: (req) => {
83
+ // Only track API routes
84
+ return req.path.startsWith('/api/');
85
+ },
86
+ }));
87
+ ```
88
+
89
+ ## x402 Payment Headers
90
+
91
+ The SDK automatically reads these headers set by x402 facilitators:
92
+
93
+ | Header | Description |
94
+ |--------|-------------|
95
+ | `x-payment` | Payment receipt/proof |
96
+ | `x-payment-token` | Payment JWT |
97
+ | `x-payer` | Payer wallet address |
98
+ | `x-payment-amount` | Payment amount |
99
+ | `x-payment-currency` | Currency (e.g., USDC) |
100
+ | `x-payment-tx` | Transaction hash |
101
+ | `x-facilitator` | Facilitator URL |
102
+
103
+ ## Default Excluded Paths
104
+
105
+ These paths are excluded from tracking by default:
106
+
107
+ `/health`, `/healthz`, `/ready`, `/readyz`, `/live`, `/livez`, `/metrics`, `/favicon.ico`, `/.well-known`
108
+
109
+ ## Manual Tracking
110
+
111
+ For non-Express frameworks or custom tracking:
112
+
113
+ ```typescript
114
+ import { createAnalytix402Client } from '@analytix402/sdk';
115
+
116
+ const client = createAnalytix402Client({
117
+ apiKey: 'ax_live_xxxxx',
118
+ });
119
+
120
+ // Track a custom event
121
+ client.track({
122
+ type: 'request',
123
+ method: 'GET',
124
+ path: '/api/data',
125
+ statusCode: 200,
126
+ responseTimeMs: 45,
127
+ timestamp: new Date().toISOString(),
128
+ payment: {
129
+ amount: '0.01',
130
+ currency: 'USDC',
131
+ wallet: '0x8f2a...',
132
+ status: 'success',
133
+ },
134
+ });
135
+
136
+ // Flush events before shutdown
137
+ await client.flush();
138
+
139
+ // Graceful shutdown
140
+ await client.shutdown();
141
+ ```
142
+
143
+ ## Performance
144
+
145
+ - **< 50ms overhead** per request
146
+ - Events are batched and sent asynchronously
147
+ - Automatic retry with exponential backoff
148
+ - Offline queue (up to 1000 events)
149
+ - Non-blocking — your API never waits for Analytix402
150
+
151
+ ## Requirements
152
+
153
+ - Node.js 18+
154
+ - Express 4.x or 5.x (for middleware, optional)
155
+
156
+ ## License
157
+
158
+ MIT
@@ -0,0 +1,236 @@
1
+ /**
2
+ * Analytix402 SDK Types
3
+ */
4
+ interface Analytix402Config {
5
+ /**
6
+ * Your Analytix402 API key (starts with ax_live_ or ax_test_)
7
+ */
8
+ apiKey: string;
9
+ /**
10
+ * Base URL for the Analytix402 API
11
+ * @default "https://api.analytix402.com"
12
+ */
13
+ baseUrl?: string;
14
+ /**
15
+ * Enable debug logging
16
+ * @default false
17
+ */
18
+ debug?: boolean;
19
+ /**
20
+ * Maximum number of events to batch before sending
21
+ * @default 100
22
+ */
23
+ batchSize?: number;
24
+ /**
25
+ * Maximum time (ms) to wait before flushing events
26
+ * @default 5000
27
+ */
28
+ flushInterval?: number;
29
+ /**
30
+ * Maximum number of retry attempts for failed requests
31
+ * @default 3
32
+ */
33
+ maxRetries?: number;
34
+ /**
35
+ * Maximum events to queue when offline
36
+ * @default 1000
37
+ */
38
+ maxQueueSize?: number;
39
+ /**
40
+ * Request timeout in milliseconds
41
+ * @default 10000
42
+ */
43
+ timeout?: number;
44
+ /**
45
+ * Paths to exclude from tracking (supports wildcards)
46
+ * @default ["/health", "/healthz", "/ready", "/metrics"]
47
+ */
48
+ excludePaths?: string[];
49
+ /**
50
+ * Custom function to extract endpoint name from request
51
+ */
52
+ getEndpointName?: (req: RequestInfo) => string;
53
+ /**
54
+ * Custom function to determine if request should be tracked
55
+ */
56
+ shouldTrack?: (req: RequestInfo) => boolean;
57
+ /**
58
+ * Agent identifier for multi-agent tracking
59
+ */
60
+ agentId?: string;
61
+ /**
62
+ * Agent friendly name
63
+ */
64
+ agentName?: string;
65
+ }
66
+ interface RequestEvent {
67
+ type: 'request';
68
+ method: string;
69
+ path: string;
70
+ endpoint?: string;
71
+ statusCode: number;
72
+ responseTimeMs: number;
73
+ payment?: PaymentInfo;
74
+ /** Agent identifier */
75
+ agentId?: string;
76
+ /** Task identifier for grouping actions */
77
+ taskId?: string;
78
+ /** Custom metadata */
79
+ metadata?: Record<string, unknown>;
80
+ timestamp: string;
81
+ ip?: string;
82
+ userAgent?: string;
83
+ }
84
+ interface PaymentInfo {
85
+ /** Payment amount */
86
+ amount: string;
87
+ /** Currency (e.g., "USDC") */
88
+ currency: string;
89
+ /** Payer wallet address */
90
+ wallet: string;
91
+ /** Payment status */
92
+ status: 'success' | 'failed' | 'pending';
93
+ /** Transaction hash if available */
94
+ txHash?: string;
95
+ /** Facilitator URL */
96
+ facilitator?: string;
97
+ }
98
+ interface HeartbeatEvent {
99
+ type: 'heartbeat';
100
+ agentId: string;
101
+ status: 'healthy' | 'degraded' | 'error';
102
+ metadata?: Record<string, unknown>;
103
+ timestamp: string;
104
+ }
105
+ interface TaskOutcome {
106
+ type: 'task_outcome';
107
+ agentId?: string;
108
+ taskId: string;
109
+ success: boolean;
110
+ durationMs?: number;
111
+ cost?: number;
112
+ metadata?: Record<string, unknown>;
113
+ timestamp: string;
114
+ }
115
+ interface LLMUsageEvent {
116
+ type: 'llm_usage';
117
+ agentId?: string;
118
+ taskId?: string;
119
+ model: string;
120
+ provider: string;
121
+ inputTokens: number;
122
+ outputTokens: number;
123
+ totalTokens: number;
124
+ costUsd?: number;
125
+ durationMs?: number;
126
+ metadata?: Record<string, unknown>;
127
+ timestamp: string;
128
+ }
129
+ interface BatchPayload {
130
+ events: (RequestEvent | HeartbeatEvent | TaskOutcome | LLMUsageEvent)[];
131
+ sdk: {
132
+ name: string;
133
+ version: string;
134
+ };
135
+ sentAt: string;
136
+ }
137
+ interface RequestInfo {
138
+ method: string;
139
+ path: string;
140
+ url: string;
141
+ headers: Record<string, string | string[] | undefined>;
142
+ ip?: string;
143
+ }
144
+ interface ResponseInfo {
145
+ statusCode: number;
146
+ headers: Record<string, string | string[] | undefined>;
147
+ }
148
+ interface Analytix402Client {
149
+ /**
150
+ * Track a request event
151
+ */
152
+ track(event: RequestEvent): void;
153
+ /**
154
+ * Flush all queued events immediately
155
+ */
156
+ flush(): Promise<void>;
157
+ /**
158
+ * Shutdown the client gracefully
159
+ */
160
+ shutdown(): Promise<void>;
161
+ /**
162
+ * Send a heartbeat signal
163
+ */
164
+ heartbeat(status?: 'healthy' | 'degraded' | 'error', metadata?: Record<string, unknown>): void;
165
+ /**
166
+ * Report a task outcome
167
+ */
168
+ reportOutcome(taskId: string, success: boolean, options?: {
169
+ durationMs?: number;
170
+ cost?: number;
171
+ metadata?: Record<string, unknown>;
172
+ }): void;
173
+ /**
174
+ * Start a task and return a task tracker
175
+ */
176
+ startTask(taskId?: string): TaskTracker;
177
+ /** Track LLM token usage */
178
+ trackLLM(usage: {
179
+ model: string;
180
+ provider: string;
181
+ inputTokens: number;
182
+ outputTokens: number;
183
+ costUsd?: number;
184
+ durationMs?: number;
185
+ taskId?: string;
186
+ metadata?: Record<string, unknown>;
187
+ }): void;
188
+ }
189
+ interface TaskTracker {
190
+ taskId: string;
191
+ /** End the task and report outcome */
192
+ end(success: boolean, metadata?: Record<string, unknown>): void;
193
+ }
194
+ interface ExpressRequest {
195
+ method: string;
196
+ path: string;
197
+ originalUrl: string;
198
+ url: string;
199
+ headers: Record<string, string | string[] | undefined>;
200
+ ip?: string;
201
+ get(name: string): string | undefined;
202
+ }
203
+ interface ExpressResponse {
204
+ statusCode: number;
205
+ getHeader(name: string): string | number | string[] | undefined;
206
+ on(event: string, callback: () => void): void;
207
+ }
208
+ type ExpressNextFunction = (err?: unknown) => void;
209
+ type ExpressMiddleware = (req: ExpressRequest, res: ExpressResponse, next: ExpressNextFunction) => void;
210
+
211
+ /**
212
+ * Analytix402 Express Middleware
213
+ * Captures requests and x402 payment data
214
+ */
215
+
216
+ /**
217
+ * Create Express middleware for Analytix402
218
+ */
219
+ declare function analytix402(config: Analytix402Config): ExpressMiddleware;
220
+ /**
221
+ * Create Express middleware (alias for analytix402)
222
+ */
223
+ declare const Analytix402: typeof analytix402;
224
+ /**
225
+ * Get the underlying client for manual tracking
226
+ */
227
+ declare function createAnalytix402Client(config: Analytix402Config): Analytix402Client;
228
+
229
+ /**
230
+ * Analytix402 Client
231
+ * Handles event batching, queuing, and transmission
232
+ */
233
+
234
+ declare function createClient(config: Analytix402Config): Analytix402Client;
235
+
236
+ export { Analytix402, type Analytix402Client, type Analytix402Config, type BatchPayload, type ExpressMiddleware, type ExpressNextFunction, type ExpressRequest, type ExpressResponse, type HeartbeatEvent, type LLMUsageEvent, type PaymentInfo, type RequestEvent, type RequestInfo, type ResponseInfo, type TaskOutcome, type TaskTracker, analytix402, createAnalytix402Client, createClient };
@@ -0,0 +1,236 @@
1
+ /**
2
+ * Analytix402 SDK Types
3
+ */
4
+ interface Analytix402Config {
5
+ /**
6
+ * Your Analytix402 API key (starts with ax_live_ or ax_test_)
7
+ */
8
+ apiKey: string;
9
+ /**
10
+ * Base URL for the Analytix402 API
11
+ * @default "https://api.analytix402.com"
12
+ */
13
+ baseUrl?: string;
14
+ /**
15
+ * Enable debug logging
16
+ * @default false
17
+ */
18
+ debug?: boolean;
19
+ /**
20
+ * Maximum number of events to batch before sending
21
+ * @default 100
22
+ */
23
+ batchSize?: number;
24
+ /**
25
+ * Maximum time (ms) to wait before flushing events
26
+ * @default 5000
27
+ */
28
+ flushInterval?: number;
29
+ /**
30
+ * Maximum number of retry attempts for failed requests
31
+ * @default 3
32
+ */
33
+ maxRetries?: number;
34
+ /**
35
+ * Maximum events to queue when offline
36
+ * @default 1000
37
+ */
38
+ maxQueueSize?: number;
39
+ /**
40
+ * Request timeout in milliseconds
41
+ * @default 10000
42
+ */
43
+ timeout?: number;
44
+ /**
45
+ * Paths to exclude from tracking (supports wildcards)
46
+ * @default ["/health", "/healthz", "/ready", "/metrics"]
47
+ */
48
+ excludePaths?: string[];
49
+ /**
50
+ * Custom function to extract endpoint name from request
51
+ */
52
+ getEndpointName?: (req: RequestInfo) => string;
53
+ /**
54
+ * Custom function to determine if request should be tracked
55
+ */
56
+ shouldTrack?: (req: RequestInfo) => boolean;
57
+ /**
58
+ * Agent identifier for multi-agent tracking
59
+ */
60
+ agentId?: string;
61
+ /**
62
+ * Agent friendly name
63
+ */
64
+ agentName?: string;
65
+ }
66
+ interface RequestEvent {
67
+ type: 'request';
68
+ method: string;
69
+ path: string;
70
+ endpoint?: string;
71
+ statusCode: number;
72
+ responseTimeMs: number;
73
+ payment?: PaymentInfo;
74
+ /** Agent identifier */
75
+ agentId?: string;
76
+ /** Task identifier for grouping actions */
77
+ taskId?: string;
78
+ /** Custom metadata */
79
+ metadata?: Record<string, unknown>;
80
+ timestamp: string;
81
+ ip?: string;
82
+ userAgent?: string;
83
+ }
84
+ interface PaymentInfo {
85
+ /** Payment amount */
86
+ amount: string;
87
+ /** Currency (e.g., "USDC") */
88
+ currency: string;
89
+ /** Payer wallet address */
90
+ wallet: string;
91
+ /** Payment status */
92
+ status: 'success' | 'failed' | 'pending';
93
+ /** Transaction hash if available */
94
+ txHash?: string;
95
+ /** Facilitator URL */
96
+ facilitator?: string;
97
+ }
98
+ interface HeartbeatEvent {
99
+ type: 'heartbeat';
100
+ agentId: string;
101
+ status: 'healthy' | 'degraded' | 'error';
102
+ metadata?: Record<string, unknown>;
103
+ timestamp: string;
104
+ }
105
+ interface TaskOutcome {
106
+ type: 'task_outcome';
107
+ agentId?: string;
108
+ taskId: string;
109
+ success: boolean;
110
+ durationMs?: number;
111
+ cost?: number;
112
+ metadata?: Record<string, unknown>;
113
+ timestamp: string;
114
+ }
115
+ interface LLMUsageEvent {
116
+ type: 'llm_usage';
117
+ agentId?: string;
118
+ taskId?: string;
119
+ model: string;
120
+ provider: string;
121
+ inputTokens: number;
122
+ outputTokens: number;
123
+ totalTokens: number;
124
+ costUsd?: number;
125
+ durationMs?: number;
126
+ metadata?: Record<string, unknown>;
127
+ timestamp: string;
128
+ }
129
+ interface BatchPayload {
130
+ events: (RequestEvent | HeartbeatEvent | TaskOutcome | LLMUsageEvent)[];
131
+ sdk: {
132
+ name: string;
133
+ version: string;
134
+ };
135
+ sentAt: string;
136
+ }
137
+ interface RequestInfo {
138
+ method: string;
139
+ path: string;
140
+ url: string;
141
+ headers: Record<string, string | string[] | undefined>;
142
+ ip?: string;
143
+ }
144
+ interface ResponseInfo {
145
+ statusCode: number;
146
+ headers: Record<string, string | string[] | undefined>;
147
+ }
148
+ interface Analytix402Client {
149
+ /**
150
+ * Track a request event
151
+ */
152
+ track(event: RequestEvent): void;
153
+ /**
154
+ * Flush all queued events immediately
155
+ */
156
+ flush(): Promise<void>;
157
+ /**
158
+ * Shutdown the client gracefully
159
+ */
160
+ shutdown(): Promise<void>;
161
+ /**
162
+ * Send a heartbeat signal
163
+ */
164
+ heartbeat(status?: 'healthy' | 'degraded' | 'error', metadata?: Record<string, unknown>): void;
165
+ /**
166
+ * Report a task outcome
167
+ */
168
+ reportOutcome(taskId: string, success: boolean, options?: {
169
+ durationMs?: number;
170
+ cost?: number;
171
+ metadata?: Record<string, unknown>;
172
+ }): void;
173
+ /**
174
+ * Start a task and return a task tracker
175
+ */
176
+ startTask(taskId?: string): TaskTracker;
177
+ /** Track LLM token usage */
178
+ trackLLM(usage: {
179
+ model: string;
180
+ provider: string;
181
+ inputTokens: number;
182
+ outputTokens: number;
183
+ costUsd?: number;
184
+ durationMs?: number;
185
+ taskId?: string;
186
+ metadata?: Record<string, unknown>;
187
+ }): void;
188
+ }
189
+ interface TaskTracker {
190
+ taskId: string;
191
+ /** End the task and report outcome */
192
+ end(success: boolean, metadata?: Record<string, unknown>): void;
193
+ }
194
+ interface ExpressRequest {
195
+ method: string;
196
+ path: string;
197
+ originalUrl: string;
198
+ url: string;
199
+ headers: Record<string, string | string[] | undefined>;
200
+ ip?: string;
201
+ get(name: string): string | undefined;
202
+ }
203
+ interface ExpressResponse {
204
+ statusCode: number;
205
+ getHeader(name: string): string | number | string[] | undefined;
206
+ on(event: string, callback: () => void): void;
207
+ }
208
+ type ExpressNextFunction = (err?: unknown) => void;
209
+ type ExpressMiddleware = (req: ExpressRequest, res: ExpressResponse, next: ExpressNextFunction) => void;
210
+
211
+ /**
212
+ * Analytix402 Express Middleware
213
+ * Captures requests and x402 payment data
214
+ */
215
+
216
+ /**
217
+ * Create Express middleware for Analytix402
218
+ */
219
+ declare function analytix402(config: Analytix402Config): ExpressMiddleware;
220
+ /**
221
+ * Create Express middleware (alias for analytix402)
222
+ */
223
+ declare const Analytix402: typeof analytix402;
224
+ /**
225
+ * Get the underlying client for manual tracking
226
+ */
227
+ declare function createAnalytix402Client(config: Analytix402Config): Analytix402Client;
228
+
229
+ /**
230
+ * Analytix402 Client
231
+ * Handles event batching, queuing, and transmission
232
+ */
233
+
234
+ declare function createClient(config: Analytix402Config): Analytix402Client;
235
+
236
+ export { Analytix402, type Analytix402Client, type Analytix402Config, type BatchPayload, type ExpressMiddleware, type ExpressNextFunction, type ExpressRequest, type ExpressResponse, type HeartbeatEvent, type LLMUsageEvent, type PaymentInfo, type RequestEvent, type RequestInfo, type ResponseInfo, type TaskOutcome, type TaskTracker, analytix402, createAnalytix402Client, createClient };