@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 +26 -450
- package/dist/index.cjs +534 -0
- package/dist/index.d.cts +354 -1
- package/dist/index.d.ts +354 -1
- package/dist/index.js +534 -0
- package/package.json +2 -14
package/README.md
CHANGED
|
@@ -1,495 +1,71 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @mixrpay/agent-sdk
|
|
2
2
|
|
|
3
|
-
Enable AI agents to make
|
|
3
|
+
Enable AI agents to make payments.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
[](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
|
-
##
|
|
40
|
-
|
|
41
|
-
The Agent SDK supports **two payment patterns** depending on what API you're calling:
|
|
11
|
+
## Setup
|
|
42
12
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
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
|
-
|
|
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
|
-
|
|
66
|
-
|
|
67
|
-
Use `fetch()` when calling APIs that implement x402 but aren't MixrPay merchants:
|
|
20
|
+
## Usage
|
|
68
21
|
|
|
69
22
|
```typescript
|
|
70
|
-
|
|
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
|
-
|
|
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: '
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
53
|
+
## Spending Controls
|
|
236
54
|
|
|
237
55
|
```typescript
|
|
238
56
|
const wallet = new AgentWallet({
|
|
239
57
|
sessionKey: 'sk_live_...',
|
|
240
|
-
maxPaymentUsd: 1.0,
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
##
|
|
69
|
+
## License
|
|
494
70
|
|
|
495
71
|
MIT
|