@mixrpay/agent-sdk 0.1.0 β 0.2.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 +186 -223
- package/dist/index.cjs +412 -1
- package/dist/index.d.cts +244 -1
- package/dist/index.d.ts +244 -1
- package/dist/index.js +414 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# MixrPay Agent SDK for JavaScript/TypeScript
|
|
2
2
|
|
|
3
|
-
Enable AI agents to make autonomous payments
|
|
3
|
+
Enable AI agents to make autonomous payments. Supports both session-based payments (for MixrPay merchants) and x402 protocol (for external APIs).
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/@mixrpay/agent-sdk)
|
|
6
6
|
[](https://www.typescriptlang.org/)
|
|
@@ -10,20 +10,20 @@ Enable AI agents to make autonomous payments using x402 protocol with session ke
|
|
|
10
10
|
```typescript
|
|
11
11
|
import { AgentWallet } from '@mixrpay/agent-sdk';
|
|
12
12
|
|
|
13
|
-
// 1. Initialize with a session key (get this from the wallet owner)
|
|
14
13
|
const wallet = new AgentWallet({
|
|
15
|
-
sessionKey: 'sk_live_...'
|
|
14
|
+
sessionKey: 'sk_live_...' // Get from wallet owner
|
|
16
15
|
});
|
|
17
16
|
|
|
18
|
-
//
|
|
19
|
-
const response = await wallet.
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
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
23
|
});
|
|
24
24
|
|
|
25
|
-
//
|
|
26
|
-
|
|
25
|
+
// For external x402 APIs:
|
|
26
|
+
const response = await wallet.fetch('https://external-api.com/query');
|
|
27
27
|
```
|
|
28
28
|
|
|
29
29
|
## π¦ Installation
|
|
@@ -36,52 +36,57 @@ yarn add @mixrpay/agent-sdk
|
|
|
36
36
|
pnpm add @mixrpay/agent-sdk
|
|
37
37
|
```
|
|
38
38
|
|
|
39
|
-
##
|
|
39
|
+
## Two Payment Methods
|
|
40
|
+
|
|
41
|
+
The Agent SDK supports **two payment patterns** depending on what API you're calling:
|
|
42
|
+
|
|
43
|
+
### 1. Session-Based Payments (For MixrPay Merchants) β Recommended
|
|
40
44
|
|
|
41
|
-
|
|
45
|
+
Use `callMerchantApi()` when the API uses MixrPay:
|
|
42
46
|
|
|
43
47
|
```typescript
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
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' },
|
|
47
54
|
});
|
|
48
|
-
|
|
49
|
-
// Or use environment variable: MIXRPAY_BASE_URL
|
|
50
55
|
```
|
|
51
56
|
|
|
52
|
-
|
|
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
|
|
53
62
|
|
|
54
|
-
|
|
63
|
+
**When to use:** APIs built with MixrPay, or any API that accepts `X-Mixr-Session` headers.
|
|
55
64
|
|
|
56
|
-
|
|
57
|
-
import { AgentWallet, SDK_VERSION } from '@mixrpay/agent-sdk';
|
|
65
|
+
### 2. x402 Protocol (For External APIs)
|
|
58
66
|
|
|
59
|
-
|
|
60
|
-
console.log(`MixrPay Agent SDK v${SDK_VERSION}`);
|
|
67
|
+
Use `fetch()` when calling APIs that implement x402 but aren't MixrPay merchants:
|
|
61
68
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
});
|
|
68
|
-
console.log('β SDK initialized successfully');
|
|
69
|
-
|
|
70
|
-
// Check connection (will fail without a running server, but validates setup)
|
|
71
|
-
wallet.getBalance().catch(() => {
|
|
72
|
-
console.log('β SDK configured (server not running - expected in test)');
|
|
73
|
-
});
|
|
74
|
-
} catch (error) {
|
|
75
|
-
console.error('β SDK initialization failed:', error);
|
|
76
|
-
}
|
|
69
|
+
```typescript
|
|
70
|
+
const response = await wallet.fetch('https://external-api.com/query', {
|
|
71
|
+
method: 'POST',
|
|
72
|
+
body: JSON.stringify({ prompt: 'Hello' })
|
|
73
|
+
});
|
|
77
74
|
```
|
|
78
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
|
+
|
|
79
84
|
## π Getting Session Keys
|
|
80
85
|
|
|
81
86
|
Session keys are created by wallet owners and grant spending permissions to agents:
|
|
82
87
|
|
|
83
|
-
1. **From a wallet owner**: They create a session key at
|
|
84
|
-
2. **Programmatically**: Via the MixrPay API
|
|
88
|
+
1. **From a wallet owner**: They create a session key at `/wallet/sessions`
|
|
89
|
+
2. **Programmatically**: Via the MixrPay API
|
|
85
90
|
|
|
86
91
|
Session keys look like: `sk_live_abc123...` (mainnet) or `sk_test_abc123...` (testnet)
|
|
87
92
|
|
|
@@ -93,58 +98,76 @@ Each session key has configurable spending limits:
|
|
|
93
98
|
- **Total**: Maximum lifetime spend
|
|
94
99
|
- **Expiration**: When the key becomes invalid
|
|
95
100
|
|
|
96
|
-
##
|
|
101
|
+
## π Session Management
|
|
97
102
|
|
|
98
|
-
|
|
99
|
-
βββββββββββββββ βββββββββββββββ βββββββββββββββ
|
|
100
|
-
β Agent ββββββΆβ Paid API ββββββΆβ Facilitator β
|
|
101
|
-
β (you) βββββββ (402) βββββββ (x402) β
|
|
102
|
-
βββββββββββββββ βββββββββββββββ βββββββββββββββ
|
|
103
|
-
β β β
|
|
104
|
-
β 1. Request β β
|
|
105
|
-
ββββββββββββββββββββΆβ β
|
|
106
|
-
β β β
|
|
107
|
-
β 2. 402 + price β β
|
|
108
|
-
βββββββββββββββββββββ€ β
|
|
109
|
-
β β β
|
|
110
|
-
β 3. Sign payment β β
|
|
111
|
-
ββββββββββββββββββββΆβ β
|
|
112
|
-
β β 4. Process β
|
|
113
|
-
β ββββββββββββββββββββΆβ
|
|
114
|
-
β β β
|
|
115
|
-
β 5. Response β 5. Confirm β
|
|
116
|
-
βββββββββββββββββββββ€ββββββββββββββββββββ€
|
|
117
|
-
β β β
|
|
118
|
-
```
|
|
103
|
+
### Automatic (Recommended)
|
|
119
104
|
|
|
120
|
-
|
|
121
|
-
2. The server returns `402 Payment Required` with pricing
|
|
122
|
-
3. The SDK automatically signs a USDC transfer authorization
|
|
123
|
-
4. The facilitator processes the payment
|
|
124
|
-
5. You receive the API response
|
|
105
|
+
`callMerchantApi()` handles sessions automatically:
|
|
125
106
|
|
|
126
|
-
|
|
107
|
+
```typescript
|
|
108
|
+
// Sessions are created and reused automatically
|
|
109
|
+
const response = await wallet.callMerchantApi({
|
|
110
|
+
url: 'https://api.merchant.com/generate',
|
|
111
|
+
merchantPublicKey: 'pk_live_abc123',
|
|
112
|
+
priceUsd: 0.05,
|
|
113
|
+
body: { prompt: 'Hello' }
|
|
114
|
+
});
|
|
115
|
+
```
|
|
127
116
|
|
|
128
|
-
###
|
|
117
|
+
### Manual Control
|
|
129
118
|
|
|
130
|
-
|
|
131
|
-
import { AgentWallet } from '@mixrpay/agent-sdk';
|
|
119
|
+
For fine-grained control over sessions:
|
|
132
120
|
|
|
133
|
-
|
|
134
|
-
|
|
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
|
|
135
127
|
});
|
|
136
128
|
|
|
137
|
-
|
|
138
|
-
|
|
129
|
+
console.log('Session ID:', session.id);
|
|
130
|
+
console.log('Remaining:', session.remainingUsd);
|
|
131
|
+
console.log('Expires:', session.expiresAt);
|
|
139
132
|
|
|
140
|
-
//
|
|
141
|
-
const
|
|
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', {
|
|
142
141
|
method: 'POST',
|
|
143
|
-
headers: {
|
|
144
|
-
|
|
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' }),
|
|
145
148
|
});
|
|
146
149
|
```
|
|
147
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.remainingUsd} 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
|
+
|
|
148
171
|
### With Payment Tracking
|
|
149
172
|
|
|
150
173
|
```typescript
|
|
@@ -154,21 +177,16 @@ const wallet = new AgentWallet({
|
|
|
154
177
|
sessionKey: 'sk_live_...',
|
|
155
178
|
onPayment: (payment: PaymentEvent) => {
|
|
156
179
|
console.log(`πΈ Paid $${payment.amountUsd.toFixed(4)} to ${payment.recipient}`);
|
|
157
|
-
console.log(` For: ${payment.description || 'API call'}`);
|
|
158
180
|
},
|
|
159
181
|
});
|
|
160
182
|
|
|
161
183
|
// Make requests
|
|
162
|
-
|
|
163
|
-
await wallet.fetch(`https://api.example.com/query/${i}`);
|
|
164
|
-
}
|
|
184
|
+
const response = await wallet.callMerchantApi({ ... });
|
|
165
185
|
|
|
166
186
|
// Check spending
|
|
167
187
|
const stats = await wallet.getSpendingStats();
|
|
168
|
-
console.log(
|
|
169
|
-
console.log(`
|
|
170
|
-
console.log(` Transactions: ${stats.txCount}`);
|
|
171
|
-
console.log(` Remaining daily: $${stats.remainingDailyUsd?.toFixed(2) ?? 'unlimited'}`);
|
|
188
|
+
console.log(`Total spent: $${stats.totalSpentUsd.toFixed(2)}`);
|
|
189
|
+
console.log(`Transactions: ${stats.txCount}`);
|
|
172
190
|
```
|
|
173
191
|
|
|
174
192
|
### Error Handling
|
|
@@ -179,25 +197,28 @@ import {
|
|
|
179
197
|
InsufficientBalanceError,
|
|
180
198
|
SpendingLimitExceededError,
|
|
181
199
|
SessionKeyExpiredError,
|
|
200
|
+
SessionExpiredError,
|
|
201
|
+
SessionLimitExceededError,
|
|
182
202
|
} from '@mixrpay/agent-sdk';
|
|
183
203
|
|
|
184
204
|
const wallet = new AgentWallet({ sessionKey: 'sk_live_...' });
|
|
185
205
|
|
|
186
206
|
try {
|
|
187
|
-
const response = await wallet.
|
|
188
|
-
console.log(await response.json());
|
|
207
|
+
const response = await wallet.callMerchantApi({ ... });
|
|
189
208
|
} catch (error) {
|
|
190
209
|
if (error instanceof InsufficientBalanceError) {
|
|
191
210
|
console.log(`β Not enough funds: need $${error.required}, have $${error.available}`);
|
|
192
211
|
console.log(` Top up at: ${error.topUpUrl}`);
|
|
212
|
+
} else if (error instanceof SessionExpiredError) {
|
|
213
|
+
console.log('β Session expired, creating new one...');
|
|
214
|
+
// SDK will auto-create on next callMerchantApi()
|
|
215
|
+
} else if (error instanceof SessionLimitExceededError) {
|
|
216
|
+
console.log(`β Session limit exceeded: ${error.limitType}`);
|
|
217
|
+
console.log(` Limit: $${error.limit}, Requested: $${error.requested}`);
|
|
193
218
|
} else if (error instanceof SpendingLimitExceededError) {
|
|
194
|
-
console.log(`β
|
|
195
|
-
if (error.limitType === 'daily') {
|
|
196
|
-
console.log(' Try again tomorrow, or request a higher limit.');
|
|
197
|
-
}
|
|
219
|
+
console.log(`β Session key limit exceeded: ${error.limitType}`);
|
|
198
220
|
} else if (error instanceof SessionKeyExpiredError) {
|
|
199
221
|
console.log(`β Session key expired at ${error.expiredAt}`);
|
|
200
|
-
console.log(' Request a new key from the wallet owner.');
|
|
201
222
|
} else {
|
|
202
223
|
throw error;
|
|
203
224
|
}
|
|
@@ -227,28 +248,6 @@ const wallet = new AgentWallet({
|
|
|
227
248
|
|
|
228
249
|
// Or toggle at runtime
|
|
229
250
|
wallet.setDebug(true);
|
|
230
|
-
await wallet.fetch('https://api.example.com/endpoint');
|
|
231
|
-
wallet.setDebug(false);
|
|
232
|
-
```
|
|
233
|
-
|
|
234
|
-
### Diagnostics
|
|
235
|
-
|
|
236
|
-
```typescript
|
|
237
|
-
const wallet = new AgentWallet({ sessionKey: 'sk_live_...' });
|
|
238
|
-
|
|
239
|
-
// Run health checks
|
|
240
|
-
const diagnostics = await wallet.runDiagnostics();
|
|
241
|
-
|
|
242
|
-
if (diagnostics.healthy) {
|
|
243
|
-
console.log('β
Wallet is ready to use');
|
|
244
|
-
console.log(` Network: ${diagnostics.network}`);
|
|
245
|
-
console.log(` Wallet: ${diagnostics.walletAddress}`);
|
|
246
|
-
} else {
|
|
247
|
-
console.log('β Issues found:');
|
|
248
|
-
for (const issue of diagnostics.issues) {
|
|
249
|
-
console.log(` - ${issue}`);
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
251
|
```
|
|
253
252
|
|
|
254
253
|
## π€ AI Framework Integrations
|
|
@@ -256,15 +255,14 @@ if (diagnostics.healthy) {
|
|
|
256
255
|
### Vercel AI SDK
|
|
257
256
|
|
|
258
257
|
```typescript
|
|
259
|
-
import { AgentWallet,
|
|
258
|
+
import { AgentWallet, SessionLimitExceededError } from '@mixrpay/agent-sdk';
|
|
260
259
|
import { generateText } from 'ai';
|
|
261
260
|
import { openai } from '@ai-sdk/openai';
|
|
262
261
|
import { z } from 'zod';
|
|
263
262
|
|
|
264
263
|
const wallet = new AgentWallet({
|
|
265
264
|
sessionKey: process.env.MIXRPAY_SESSION_KEY!,
|
|
266
|
-
maxPaymentUsd: 1.00,
|
|
267
|
-
onPayment: (p) => console.log(`Paid $${p.amountUsd} for API call`),
|
|
265
|
+
maxPaymentUsd: 1.00,
|
|
268
266
|
});
|
|
269
267
|
|
|
270
268
|
const result = await generateText({
|
|
@@ -275,25 +273,23 @@ const result = await generateText({
|
|
|
275
273
|
parameters: z.object({ query: z.string() }),
|
|
276
274
|
execute: async ({ query }) => {
|
|
277
275
|
try {
|
|
278
|
-
const response = await wallet.
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
276
|
+
const response = await wallet.callMerchantApi({
|
|
277
|
+
url: 'https://api.search.com/query',
|
|
278
|
+
merchantPublicKey: 'pk_live_...',
|
|
279
|
+
priceUsd: 0.05,
|
|
280
|
+
body: { query }
|
|
282
281
|
});
|
|
283
282
|
return response.json();
|
|
284
283
|
} catch (error) {
|
|
285
|
-
if (error instanceof
|
|
286
|
-
return { error: '
|
|
284
|
+
if (error instanceof SessionLimitExceededError) {
|
|
285
|
+
return { error: 'Budget exceeded', limit: error.limitType };
|
|
287
286
|
}
|
|
288
|
-
|
|
289
|
-
return { error: 'Spending limit reached', limit: error.limitType };
|
|
290
|
-
}
|
|
291
|
-
throw error; // Re-throw unexpected errors
|
|
287
|
+
throw error;
|
|
292
288
|
}
|
|
293
289
|
}
|
|
294
290
|
}
|
|
295
291
|
},
|
|
296
|
-
prompt: 'Search for the latest AI news
|
|
292
|
+
prompt: 'Search for the latest AI news'
|
|
297
293
|
});
|
|
298
294
|
```
|
|
299
295
|
|
|
@@ -305,33 +301,30 @@ import { DynamicTool } from '@langchain/core/tools';
|
|
|
305
301
|
|
|
306
302
|
const wallet = new AgentWallet({
|
|
307
303
|
sessionKey: process.env.MIXRPAY_SESSION_KEY!,
|
|
308
|
-
maxPaymentUsd: 0.50,
|
|
304
|
+
maxPaymentUsd: 0.50,
|
|
309
305
|
});
|
|
310
306
|
|
|
311
307
|
const paidSearchTool = new DynamicTool({
|
|
312
308
|
name: 'paid_search',
|
|
313
|
-
description: 'Premium search API ($0.05/query)
|
|
309
|
+
description: 'Premium search API ($0.05/query)',
|
|
314
310
|
func: async (query: string) => {
|
|
315
311
|
try {
|
|
316
|
-
const response = await wallet.
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
312
|
+
const response = await wallet.callMerchantApi({
|
|
313
|
+
url: 'https://api.search.com/query',
|
|
314
|
+
merchantPublicKey: 'pk_live_...',
|
|
315
|
+
priceUsd: 0.05,
|
|
316
|
+
body: { query }
|
|
320
317
|
});
|
|
321
318
|
const data = await response.json();
|
|
322
319
|
return JSON.stringify(data.results);
|
|
323
320
|
} catch (error) {
|
|
324
321
|
if (error instanceof InsufficientBalanceError) {
|
|
325
|
-
return `Error: Low balance
|
|
322
|
+
return `Error: Low balance. Top up: ${error.topUpUrl}`;
|
|
326
323
|
}
|
|
327
|
-
return `Error: ${error instanceof Error ? error.message : 'Unknown
|
|
324
|
+
return `Error: ${error instanceof Error ? error.message : 'Unknown'}`;
|
|
328
325
|
}
|
|
329
326
|
}
|
|
330
327
|
});
|
|
331
|
-
|
|
332
|
-
// Check spending before expensive operations
|
|
333
|
-
const stats = await wallet.getSpendingStats();
|
|
334
|
-
console.log(`Budget remaining: $${stats.remainingDailyUsd ?? 'unlimited'}`);
|
|
335
328
|
```
|
|
336
329
|
|
|
337
330
|
## π API Reference
|
|
@@ -354,11 +347,17 @@ new AgentWallet({
|
|
|
354
347
|
})
|
|
355
348
|
```
|
|
356
349
|
|
|
357
|
-
|
|
350
|
+
### Methods
|
|
358
351
|
|
|
359
352
|
| Method | Description |
|
|
360
353
|
|--------|-------------|
|
|
361
|
-
| `
|
|
354
|
+
| `callMerchantApi(options)` | Make request to MixrPay merchant (session-based) |
|
|
355
|
+
| `fetch(url, init?)` | Make request to x402 API (drop-in for native fetch) |
|
|
356
|
+
| `getOrCreateSession(options)` | Get or create session with merchant |
|
|
357
|
+
| `chargeSession(id, amount, options?)` | Charge against a session |
|
|
358
|
+
| `listSessions()` | List all active sessions |
|
|
359
|
+
| `revokeSession(id)` | Revoke a session |
|
|
360
|
+
| `getSessionStats()` | Get session statistics |
|
|
362
361
|
| `getBalance()` | Get USDC balance in USD |
|
|
363
362
|
| `getSpendingStats()` | Get spending statistics |
|
|
364
363
|
| `getSessionKeyInfo()` | Get session key details and limits |
|
|
@@ -369,44 +368,37 @@ new AgentWallet({
|
|
|
369
368
|
| `isTestnet()` | Check if using testnet |
|
|
370
369
|
| `runDiagnostics()` | Run health checks |
|
|
371
370
|
| `setDebug(enable)` | Toggle debug logging |
|
|
372
|
-
| `setLogLevel(level)` | Set log level |
|
|
373
371
|
|
|
374
372
|
### Types
|
|
375
373
|
|
|
376
374
|
```typescript
|
|
377
|
-
interface
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
375
|
+
interface Session {
|
|
376
|
+
id: string;
|
|
377
|
+
merchantPublicKey: string;
|
|
378
|
+
merchantName?: string;
|
|
379
|
+
spendingLimitUsd: number;
|
|
380
|
+
spentUsd: number;
|
|
381
|
+
remainingUsd: number;
|
|
382
|
+
status: 'active' | 'expired' | 'revoked';
|
|
383
|
+
expiresAt: Date;
|
|
384
|
+
createdAt: Date;
|
|
384
385
|
}
|
|
385
386
|
|
|
386
|
-
interface
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
387
|
+
interface ChargeResult {
|
|
388
|
+
success: boolean;
|
|
389
|
+
chargeId: string;
|
|
390
|
+
amountUsd: number;
|
|
391
|
+
txHash?: string;
|
|
392
|
+
remainingUsd: number;
|
|
392
393
|
}
|
|
393
394
|
|
|
394
|
-
interface
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
};
|
|
402
|
-
usage: {
|
|
403
|
-
todayUsd: number;
|
|
404
|
-
totalUsd: number;
|
|
405
|
-
txCount: number;
|
|
406
|
-
};
|
|
407
|
-
expiresAt: Date | null;
|
|
408
|
-
createdAt: Date | null;
|
|
409
|
-
name?: string;
|
|
395
|
+
interface PaymentEvent {
|
|
396
|
+
amountUsd: number;
|
|
397
|
+
recipient: string;
|
|
398
|
+
txHash: string | null;
|
|
399
|
+
timestamp: Date;
|
|
400
|
+
description?: string;
|
|
401
|
+
url?: string;
|
|
410
402
|
}
|
|
411
403
|
```
|
|
412
404
|
|
|
@@ -416,10 +408,14 @@ interface SessionKeyInfo {
|
|
|
416
408
|
|-----------|-------------|
|
|
417
409
|
| `InsufficientBalanceError` | Wallet doesn't have enough USDC |
|
|
418
410
|
| `SessionKeyExpiredError` | Session key has expired |
|
|
419
|
-
| `SpendingLimitExceededError` |
|
|
411
|
+
| `SpendingLimitExceededError` | Would exceed session key limits |
|
|
412
|
+
| `SessionExpiredError` | Session authorization has expired |
|
|
413
|
+
| `SessionLimitExceededError` | Would exceed session spending limit |
|
|
414
|
+
| `SessionNotFoundError` | Session ID is invalid |
|
|
415
|
+
| `SessionRevokedError` | Session was revoked |
|
|
420
416
|
| `PaymentFailedError` | Payment transaction failed |
|
|
421
417
|
| `InvalidSessionKeyError` | Invalid session key format |
|
|
422
|
-
| `X402ProtocolError` |
|
|
418
|
+
| `X402ProtocolError` | x402 protocol handling error |
|
|
423
419
|
|
|
424
420
|
## π Networks
|
|
425
421
|
|
|
@@ -430,19 +426,15 @@ interface SessionKeyInfo {
|
|
|
430
426
|
|
|
431
427
|
### Testing on Testnet
|
|
432
428
|
|
|
433
|
-
1. **Get test ETH**: Use the [Base Sepolia faucet](https://www.alchemy.com/faucets/base-sepolia)
|
|
434
|
-
2. **Get test USDC**: Available from the wallet dashboard after funding with test ETH
|
|
435
|
-
3. **Create test session key**: Use the wallet dashboard to create `sk_test_...` keys
|
|
436
|
-
4. **Test your integration**: Use test keys with your development environment
|
|
437
|
-
|
|
438
429
|
```typescript
|
|
439
430
|
// Test environment setup
|
|
440
431
|
const wallet = new AgentWallet({
|
|
441
|
-
sessionKey:
|
|
442
|
-
baseUrl: 'http://localhost:3000', //
|
|
432
|
+
sessionKey: 'sk_test_...', // Use test key
|
|
433
|
+
baseUrl: 'http://localhost:3000', // Local dev server
|
|
443
434
|
});
|
|
444
435
|
|
|
445
436
|
// The SDK automatically detects testnet from sk_test_ prefix
|
|
437
|
+
console.log(`Testnet: ${wallet.isTestnet()}`); // true
|
|
446
438
|
```
|
|
447
439
|
|
|
448
440
|
## π§ Environment Variables
|
|
@@ -450,33 +442,7 @@ const wallet = new AgentWallet({
|
|
|
450
442
|
| Variable | Required | Description |
|
|
451
443
|
|----------|----------|-------------|
|
|
452
444
|
| `MIXRPAY_SESSION_KEY` | Yes | Your session key (`sk_live_...` or `sk_test_...`) |
|
|
453
|
-
| `MIXRPAY_BASE_URL` | No | MixrPay server URL (default: `
|
|
454
|
-
|
|
455
|
-
### x402 Facilitator
|
|
456
|
-
|
|
457
|
-
The SDK uses the x402 protocol facilitator at `https://x402.org/facilitator` by default. The facilitator:
|
|
458
|
-
- Verifies payment signatures
|
|
459
|
-
- Submits transactions to the blockchain
|
|
460
|
-
- Returns settlement confirmation
|
|
461
|
-
|
|
462
|
-
You can use a custom facilitator for testing or self-hosted deployments:
|
|
463
|
-
```typescript
|
|
464
|
-
const wallet = new AgentWallet({
|
|
465
|
-
sessionKey: 'sk_live_...',
|
|
466
|
-
facilitatorUrl: 'https://your-facilitator.com', // Custom facilitator
|
|
467
|
-
});
|
|
468
|
-
```
|
|
469
|
-
|
|
470
|
-
Example `.env` file:
|
|
471
|
-
```bash
|
|
472
|
-
# Production
|
|
473
|
-
MIXRPAY_SESSION_KEY=sk_live_abc123...
|
|
474
|
-
MIXRPAY_BASE_URL=https://your-mixrpay-server.com
|
|
475
|
-
|
|
476
|
-
# Development (testnet)
|
|
477
|
-
MIXRPAY_SESSION_KEY=sk_test_abc123...
|
|
478
|
-
MIXRPAY_BASE_URL=http://localhost:3000
|
|
479
|
-
```
|
|
445
|
+
| `MIXRPAY_BASE_URL` | No | MixrPay server URL (default: `https://mixrpay.com`) |
|
|
480
446
|
|
|
481
447
|
## π Security Best Practices
|
|
482
448
|
|
|
@@ -486,22 +452,19 @@ MIXRPAY_BASE_URL=http://localhost:3000
|
|
|
486
452
|
4. **Use testnet first** - Test with `sk_test_` keys before production
|
|
487
453
|
5. **Configure base URL** - Always set `baseUrl` explicitly in production
|
|
488
454
|
|
|
489
|
-
## π Browser Support
|
|
490
|
-
|
|
491
|
-
This SDK works in both Node.js and browser environments. In browsers, it uses the native `fetch` and `crypto` APIs.
|
|
492
|
-
|
|
493
455
|
## π Changelog
|
|
494
456
|
|
|
495
|
-
### v0.
|
|
457
|
+
### v0.2.0 (Current)
|
|
458
|
+
- Added session-based payments (`callMerchantApi()`)
|
|
459
|
+
- Added session management (`getOrCreateSession()`, `listSessions()`, `revokeSession()`)
|
|
460
|
+
- Added session-related error types
|
|
461
|
+
- Improved documentation
|
|
462
|
+
|
|
463
|
+
### v0.1.0
|
|
496
464
|
- Initial release
|
|
497
|
-
-
|
|
498
|
-
-
|
|
499
|
-
-
|
|
500
|
-
- Payment callbacks and spending statistics
|
|
501
|
-
- Vercel AI SDK and LangChain.js integration examples
|
|
502
|
-
- Debug mode and diagnostics
|
|
503
|
-
|
|
504
|
-
See [CHANGELOG.md](./CHANGELOG.md) for full release history.
|
|
465
|
+
- x402 payment handling via `fetch()`
|
|
466
|
+
- Session key validation and spending limits
|
|
467
|
+
- Payment callbacks and statistics
|
|
505
468
|
|
|
506
469
|
## π License
|
|
507
470
|
|