@mixrpay/agent-sdk 0.3.2 β†’ 0.3.4

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 CHANGED
@@ -1,495 +1,71 @@
1
- # MixrPay Agent SDK for JavaScript/TypeScript
1
+ # @mixrpay/agent-sdk
2
2
 
3
- Enable AI agents to make autonomous payments. Supports both session-based payments (for MixrPay merchants) and x402 protocol (for external APIs).
3
+ Enable AI agents to make payments.
4
4
 
5
- [![npm version](https://img.shields.io/npm/v/@mixrpay/agent-sdk)](https://www.npmjs.com/package/@mixrpay/agent-sdk)
6
- [![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue)](https://www.typescriptlang.org/)
7
-
8
- ## πŸš€ Quick Start
9
-
10
- ```typescript
11
- import { AgentWallet } from '@mixrpay/agent-sdk';
12
-
13
- const wallet = new AgentWallet({
14
- sessionKey: 'sk_live_...' // Get from wallet owner
15
- });
16
-
17
- // For MixrPay merchants (recommended):
18
- const response = await wallet.callMerchantApi({
19
- url: 'https://api.merchant.com/generate',
20
- merchantPublicKey: 'pk_live_abc123',
21
- priceUsd: 0.05,
22
- body: { prompt: 'Hello world' }
23
- });
24
-
25
- // For external x402 APIs:
26
- const response = await wallet.fetch('https://external-api.com/query');
27
- ```
28
-
29
- ## πŸ“¦ Installation
5
+ ## Installation
30
6
 
31
7
  ```bash
32
8
  npm install @mixrpay/agent-sdk
33
- # or
34
- yarn add @mixrpay/agent-sdk
35
- # or
36
- pnpm add @mixrpay/agent-sdk
37
9
  ```
38
10
 
39
- ## Two Payment Methods
40
-
41
- The Agent SDK supports **two payment patterns** depending on what API you're calling:
11
+ ## Setup
42
12
 
43
- ### 1. Session-Based Payments (For MixrPay Merchants) ⭐ Recommended
44
-
45
- Use `callMerchantApi()` when the API uses MixrPay:
46
-
47
- ```typescript
48
- const response = await wallet.callMerchantApi({
49
- url: 'https://api.merchant.com/generate',
50
- merchantPublicKey: 'pk_live_abc123', // Merchant's MixrPay public key
51
- priceUsd: 0.05,
52
- method: 'POST',
53
- body: { prompt: 'Hello world' },
54
- });
13
+ ```bash
14
+ # .env
15
+ MIXRPAY_SESSION_KEY=sk_live_...
55
16
  ```
56
17
 
57
- **How it works:**
58
- 1. SDK creates/reuses a session authorization with the merchant
59
- 2. SDK charges against the session
60
- 3. Request is sent with `X-Mixr-Session` header
61
- 4. No 402 round-trip neededβ€”faster and cheaper
62
-
63
- **When to use:** APIs built with MixrPay, or any API that accepts `X-Mixr-Session` headers.
18
+ Get session keys from [mixrpay.com/wallet/sessions](https://www.mixrpay.com/wallet/sessions).
64
19
 
65
- ### 2. x402 Protocol (For External APIs)
66
-
67
- Use `fetch()` when calling APIs that implement x402 but aren't MixrPay merchants:
20
+ ## Usage
68
21
 
69
22
  ```typescript
70
- const response = await wallet.fetch('https://external-api.com/query', {
71
- method: 'POST',
72
- body: JSON.stringify({ prompt: 'Hello' })
73
- });
74
- ```
75
-
76
- **How it works:**
77
- 1. SDK makes initial request
78
- 2. API returns `402 Payment Required`
79
- 3. SDK signs payment authorization
80
- 4. SDK retries with `X-PAYMENT` header
81
-
82
- **When to use:** External APIs that use standard x402 protocol.
83
-
84
- ## πŸ”‘ Getting Session Keys
85
-
86
- Session keys are created by wallet owners and grant spending permissions to agents:
87
-
88
- 1. **From a wallet owner**: They create a session key at `/wallet/sessions`
89
- 2. **Programmatically**: Via the MixrPay API
90
-
91
- Session keys look like: `sk_live_abc123...` (mainnet) or `sk_test_abc123...` (testnet)
92
-
93
- ### Session Key Limits
94
-
95
- Each session key has configurable spending limits:
96
- - **Per-transaction**: Maximum amount per single request
97
- - **Daily**: Maximum total per 24 hours
98
- - **Total**: Maximum lifetime spend
99
- - **Expiration**: When the key becomes invalid
100
-
101
- ## πŸ“– Session Management
102
-
103
- ### Automatic (Recommended)
23
+ import { AgentWallet } from '@mixrpay/agent-sdk';
104
24
 
105
- `callMerchantApi()` handles sessions automatically:
25
+ const wallet = new AgentWallet({
26
+ sessionKey: process.env.MIXRPAY_SESSION_KEY!
27
+ });
106
28
 
107
- ```typescript
108
- // Sessions are created and reused automatically
109
29
  const response = await wallet.callMerchantApi({
110
30
  url: 'https://api.merchant.com/generate',
111
- merchantPublicKey: 'pk_live_abc123',
31
+ merchantPublicKey: 'pk_live_...',
112
32
  priceUsd: 0.05,
113
- body: { prompt: 'Hello' }
114
- });
115
- ```
116
-
117
- ### Manual Control
118
-
119
- For fine-grained control over sessions:
120
-
121
- ```typescript
122
- // Get or create a session
123
- const session = await wallet.getOrCreateSession({
124
- merchantPublicKey: 'pk_live_abc123',
125
- spendingLimitUsd: 25, // Max total spending
126
- durationDays: 7, // Session validity
127
- });
128
-
129
- console.log('Session ID:', session.id);
130
- console.log('Remaining:', session.remainingLimitUsd);
131
- console.log('Expires:', session.expiresAt);
132
-
133
- // Charge manually
134
- const charge = await wallet.chargeSession(session.id, 0.05, {
135
- feature: 'generate',
136
- idempotencyKey: `charge-${Date.now()}`,
137
- });
138
-
139
- // Then make your API call with the session
140
- const response = await fetch('https://api.merchant.com/generate', {
141
- method: 'POST',
142
- headers: {
143
- 'Content-Type': 'application/json',
144
- 'X-Mixr-Session': session.id,
145
- 'X-Mixr-Charged': 'true', // Tell merchant payment is done
146
- },
147
- body: JSON.stringify({ prompt: 'Hello' }),
148
- });
149
- ```
150
-
151
- ### List and Revoke Sessions
152
-
153
- ```typescript
154
- // List all active sessions
155
- const sessions = await wallet.listSessions();
156
- for (const session of sessions) {
157
- console.log(`${session.merchantName}: $${session.remainingLimitUsd} remaining`);
158
- }
159
-
160
- // Revoke a session (e.g., when done with a merchant)
161
- await wallet.revokeSession(session.id);
162
-
163
- // Get session statistics
164
- const stats = await wallet.getSessionStats();
165
- console.log(`Active sessions: ${stats.activeCount}`);
166
- console.log(`Total authorized: $${stats.totalAuthorizedUsd}`);
167
- ```
168
-
169
- ## πŸ’‘ Usage Examples
170
-
171
- ### With Payment Tracking
172
-
173
- ```typescript
174
- import { AgentWallet, PaymentEvent } from '@mixrpay/agent-sdk';
175
-
176
- const wallet = new AgentWallet({
177
- sessionKey: 'sk_live_...',
178
- onPayment: (payment: PaymentEvent) => {
179
- console.log(`πŸ’Έ Paid $${payment.amountUsd.toFixed(4)} to ${payment.recipient}`);
180
- },
33
+ body: { prompt: 'Hello world' }
181
34
  });
182
35
 
183
- // Make requests
184
- const response = await wallet.callMerchantApi({ ... });
185
-
186
- // Check spending
187
- const stats = await wallet.getSpendingStats();
188
- console.log(`Total spent: $${stats.totalSpentUsd.toFixed(2)}`);
189
- console.log(`Transactions: ${stats.txCount}`);
36
+ const data = await response.json();
190
37
  ```
191
38
 
192
- ### Error Handling
39
+ ## Error Handling
193
40
 
194
41
  ```typescript
195
- import {
196
- AgentWallet,
197
- InsufficientBalanceError,
198
- SpendingLimitExceededError,
199
- SessionKeyExpiredError,
200
- // Session Authorization Errors
201
- SessionExpiredError,
202
- SessionLimitExceededError,
203
- SessionNotFoundError,
204
- SessionRevokedError,
205
- } from '@mixrpay/agent-sdk';
206
-
207
- const wallet = new AgentWallet({ sessionKey: 'sk_live_...' });
42
+ import { AgentWallet, InsufficientBalanceError, SessionLimitExceededError } from '@mixrpay/agent-sdk';
208
43
 
209
44
  try {
210
45
  const response = await wallet.callMerchantApi({ ... });
211
46
  } catch (error) {
212
47
  if (error instanceof InsufficientBalanceError) {
213
- console.log(`❌ Not enough funds: need $${error.required}, have $${error.available}`);
214
- console.log(` Top up at: ${error.topUpUrl}`);
215
- } else if (error instanceof SessionExpiredError) {
216
- console.log(`❌ Session ${error.sessionId} expired`);
217
- // SDK will auto-create on next callMerchantApi()
218
- } else if (error instanceof SessionLimitExceededError) {
219
- console.log(`❌ Session limit exceeded`);
220
- console.log(` Limit: $${error.limit}, Requested: $${error.requested}, Remaining: $${error.remaining}`);
221
- } else if (error instanceof SessionNotFoundError) {
222
- console.log(`❌ Session ${error.sessionId} not found`);
223
- } else if (error instanceof SessionRevokedError) {
224
- console.log(`❌ Session ${error.sessionId} was revoked: ${error.reason || 'no reason given'}`);
225
- } else if (error instanceof SpendingLimitExceededError) {
226
- console.log(`❌ Session key limit exceeded: ${error.limitType}`);
227
- } else if (error instanceof SessionKeyExpiredError) {
228
- console.log(`❌ Session key expired at ${error.expiredAt}`);
229
- } else {
230
- throw error;
48
+ console.log(`Top up at: ${error.topUpUrl}`);
231
49
  }
232
50
  }
233
51
  ```
234
52
 
235
- ### With Client-Side Safety Limit
53
+ ## Spending Controls
236
54
 
237
55
  ```typescript
238
56
  const wallet = new AgentWallet({
239
57
  sessionKey: 'sk_live_...',
240
- maxPaymentUsd: 1.0, // Never pay more than $1 per request
241
- });
242
-
243
- // If an API tries to charge more than $1, the SDK will throw
244
- // SpendingLimitExceededError with limitType: 'client_max'
245
- ```
246
-
247
- ### Debug Mode
248
-
249
- ```typescript
250
- // Enable logging during initialization
251
- const wallet = new AgentWallet({
252
- sessionKey: 'sk_live_...',
253
- logLevel: 'debug', // 'debug' | 'info' | 'warn' | 'error' | 'none'
254
- });
255
-
256
- // Or toggle at runtime
257
- wallet.setDebug(true);
258
- ```
259
-
260
- ## πŸ€– AI Framework Integrations
261
-
262
- ### Vercel AI SDK
263
-
264
- ```typescript
265
- import { AgentWallet, SessionLimitExceededError } from '@mixrpay/agent-sdk';
266
- import { generateText } from 'ai';
267
- import { openai } from '@ai-sdk/openai';
268
- import { z } from 'zod';
269
-
270
- const wallet = new AgentWallet({
271
- sessionKey: process.env.MIXRPAY_SESSION_KEY!,
272
- maxPaymentUsd: 1.00,
58
+ maxPaymentUsd: 1.0,
59
+ onPayment: (payment) => console.log(`Paid $${payment.amountUsd}`),
273
60
  });
274
61
 
275
- const result = await generateText({
276
- model: openai('gpt-4'),
277
- tools: {
278
- paidSearch: {
279
- description: 'Search using a premium paid API',
280
- parameters: z.object({ query: z.string() }),
281
- execute: async ({ query }) => {
282
- try {
283
- const response = await wallet.callMerchantApi({
284
- url: 'https://api.search.com/query',
285
- merchantPublicKey: 'pk_live_...',
286
- priceUsd: 0.05,
287
- body: { query }
288
- });
289
- return response.json();
290
- } catch (error) {
291
- if (error instanceof SessionLimitExceededError) {
292
- return { error: 'Budget exceeded', limit: error.limitType };
293
- }
294
- throw error;
295
- }
296
- }
297
- }
298
- },
299
- prompt: 'Search for the latest AI news'
300
- });
62
+ const balance = await wallet.getBalance();
301
63
  ```
302
64
 
303
- ### LangChain.js
304
-
305
- ```typescript
306
- import { AgentWallet, InsufficientBalanceError } from '@mixrpay/agent-sdk';
307
- import { DynamicTool } from '@langchain/core/tools';
308
-
309
- const wallet = new AgentWallet({
310
- sessionKey: process.env.MIXRPAY_SESSION_KEY!,
311
- maxPaymentUsd: 0.50,
312
- });
313
-
314
- const paidSearchTool = new DynamicTool({
315
- name: 'paid_search',
316
- description: 'Premium search API ($0.05/query)',
317
- func: async (query: string) => {
318
- try {
319
- const response = await wallet.callMerchantApi({
320
- url: 'https://api.search.com/query',
321
- merchantPublicKey: 'pk_live_...',
322
- priceUsd: 0.05,
323
- body: { query }
324
- });
325
- const data = await response.json();
326
- return JSON.stringify(data.results);
327
- } catch (error) {
328
- if (error instanceof InsufficientBalanceError) {
329
- return `Error: Low balance. Top up: ${error.topUpUrl}`;
330
- }
331
- return `Error: ${error instanceof Error ? error.message : 'Unknown'}`;
332
- }
333
- }
334
- });
335
- ```
336
-
337
- ## πŸ“š API Reference
338
-
339
- ### AgentWallet
340
-
341
- ```typescript
342
- new AgentWallet({
343
- // Required
344
- sessionKey: string; // Session key (sk_live_... or sk_test_...)
345
-
346
- // Optional
347
- walletAddress?: string; // Smart wallet address (auto-detected)
348
- maxPaymentUsd?: number; // Client-side payment limit
349
- onPayment?: (PaymentEvent) => void; // Payment callback
350
- facilitatorUrl?: string; // x402 facilitator URL
351
- baseUrl?: string; // MixrPay API base URL
352
- timeout?: number; // Request timeout in ms (default: 30000)
353
- logLevel?: 'debug' | 'info' | 'warn' | 'error' | 'none';
354
- })
355
- ```
356
-
357
- ### Methods
358
-
359
- | Method | Description |
360
- |--------|-------------|
361
- | `callMerchantApi(options)` | Make request to MixrPay merchant (session-based) |
362
- | `fetch(url, init?)` | Make request to x402 API (drop-in for native fetch) |
363
- | `getOrCreateSession(options)` | Get or create session with merchant |
364
- | `chargeSession(id, amount, options?)` | Charge against a session |
365
- | `listSessions()` | List all active sessions |
366
- | `revokeSession(id)` | Revoke a session |
367
- | `getSessionStats()` | Get session statistics |
368
- | `getBalance()` | Get USDC balance in USD |
369
- | `getSpendingStats()` | Get spending statistics |
370
- | `getSessionKeyInfo()` | Get session key details and limits |
371
- | `getPaymentHistory()` | Get list of payments made |
372
- | `getTotalSpent()` | Get total amount spent |
373
- | `getWalletAddress()` | Get wallet address |
374
- | `getNetwork()` | Get network info (Base or Base Sepolia) |
375
- | `isTestnet()` | Check if using testnet |
376
- | `runDiagnostics()` | Run health checks |
377
- | `setDebug(enable)` | Toggle debug logging |
378
-
379
- ### Types
380
-
381
- ```typescript
382
- interface SessionAuthorization {
383
- id: string;
384
- merchantId: string;
385
- merchantName: string;
386
- status: 'pending' | 'active' | 'expired' | 'revoked';
387
- spendingLimitUsd: number;
388
- amountUsedUsd: number;
389
- remainingLimitUsd: number;
390
- expiresAt: Date;
391
- createdAt: Date;
392
- }
393
-
394
- interface SessionStats {
395
- activeCount: number;
396
- expiredCount: number;
397
- revokedCount: number;
398
- totalAuthorizedUsd: number;
399
- totalSpentUsd: number;
400
- totalRemainingUsd: number;
401
- activeSessions: Array<{
402
- id: string;
403
- merchantName: string;
404
- merchantPublicKey: string;
405
- spendingLimitUsd: number;
406
- remainingUsd: number;
407
- expiresAt: Date;
408
- }>;
409
- }
410
-
411
- interface ChargeResult {
412
- success: boolean;
413
- chargeId: string;
414
- amountUsd: number;
415
- txHash?: string;
416
- remainingSessionBalanceUsd: number;
417
- }
418
-
419
- interface PaymentEvent {
420
- amountUsd: number;
421
- recipient: string;
422
- txHash: string | null;
423
- timestamp: Date;
424
- description?: string;
425
- url?: string;
426
- }
427
- ```
428
-
429
- ### Exceptions
430
-
431
- | Exception | When Thrown |
432
- |-----------|-------------|
433
- | `InsufficientBalanceError` | Wallet doesn't have enough USDC |
434
- | `SessionKeyExpiredError` | Session key has expired |
435
- | `SpendingLimitExceededError` | Would exceed session key limits |
436
- | `SessionExpiredError` | Session authorization has expired |
437
- | `SessionLimitExceededError` | Would exceed session spending limit |
438
- | `SessionNotFoundError` | Session ID is invalid |
439
- | `SessionRevokedError` | Session was revoked |
440
- | `PaymentFailedError` | Payment transaction failed |
441
- | `InvalidSessionKeyError` | Invalid session key format |
442
- | `X402ProtocolError` | x402 protocol handling error |
443
-
444
- ## 🌐 Networks
445
-
446
- | Network | Chain ID | Session Key Prefix | USDC Address |
447
- |---------|----------|-------------------|--------------|
448
- | Base Mainnet | 8453 | `sk_live_` | Production USDC |
449
- | Base Sepolia | 84532 | `sk_test_` | Test USDC |
450
-
451
- ### Testing on Testnet
452
-
453
- ```typescript
454
- // Test environment setup
455
- const wallet = new AgentWallet({
456
- sessionKey: 'sk_test_...', // Use test key
457
- baseUrl: 'http://localhost:3000', // Local dev server
458
- });
459
-
460
- // The SDK automatically detects testnet from sk_test_ prefix
461
- console.log(`Testnet: ${wallet.isTestnet()}`); // true
462
- ```
463
-
464
- ## πŸ”§ Environment Variables
465
-
466
- | Variable | Required | Description |
467
- |----------|----------|-------------|
468
- | `MIXRPAY_SESSION_KEY` | Yes | Your session key (`sk_live_...` or `sk_test_...`) |
469
- | `MIXRPAY_BASE_URL` | No | MixrPay server URL (default: `https://www.mixrpay.com`) |
470
-
471
- ## πŸ”’ Security Best Practices
472
-
473
- 1. **Store session keys securely** - Use environment variables, never commit to source
474
- 2. **Set appropriate limits** - Use `maxPaymentUsd` as a safety net
475
- 3. **Monitor spending** - Use `onPayment` callback and `getSpendingStats()`
476
- 4. **Use testnet first** - Test with `sk_test_` keys before production
477
- 5. **Configure base URL** - Always set `baseUrl` explicitly in production
478
-
479
- ## πŸ“‹ Changelog
480
-
481
- ### v0.2.0 (Current)
482
- - Added session-based payments (`callMerchantApi()`)
483
- - Added session management (`getOrCreateSession()`, `listSessions()`, `revokeSession()`)
484
- - Added session-related error types
485
- - Improved documentation
65
+ ## Documentation
486
66
 
487
- ### v0.1.0
488
- - Initial release
489
- - x402 payment handling via `fetch()`
490
- - Session key validation and spending limits
491
- - Payment callbacks and statistics
67
+ [mixrpay.com/docs](https://www.mixrpay.com/docs)
492
68
 
493
- ## πŸ“ License
69
+ ## License
494
70
 
495
71
  MIT