@mixrpay/agent-sdk 0.1.1 β 0.3.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 +208 -221
- package/dist/index.cjs +555 -51
- package/dist/index.d.cts +356 -239
- package/dist/index.d.ts +356 -239
- package/dist/index.js +552 -37
- 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.remainingLimitUsd);
|
|
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.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
|
+
|
|
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,35 @@ import {
|
|
|
179
197
|
InsufficientBalanceError,
|
|
180
198
|
SpendingLimitExceededError,
|
|
181
199
|
SessionKeyExpiredError,
|
|
200
|
+
// Session Authorization Errors
|
|
201
|
+
SessionExpiredError,
|
|
202
|
+
SessionLimitExceededError,
|
|
203
|
+
SessionNotFoundError,
|
|
204
|
+
SessionRevokedError,
|
|
182
205
|
} from '@mixrpay/agent-sdk';
|
|
183
206
|
|
|
184
207
|
const wallet = new AgentWallet({ sessionKey: 'sk_live_...' });
|
|
185
208
|
|
|
186
209
|
try {
|
|
187
|
-
const response = await wallet.
|
|
188
|
-
console.log(await response.json());
|
|
210
|
+
const response = await wallet.callMerchantApi({ ... });
|
|
189
211
|
} catch (error) {
|
|
190
212
|
if (error instanceof InsufficientBalanceError) {
|
|
191
213
|
console.log(`β Not enough funds: need $${error.required}, have $${error.available}`);
|
|
192
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'}`);
|
|
193
225
|
} 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
|
-
}
|
|
226
|
+
console.log(`β Session key limit exceeded: ${error.limitType}`);
|
|
198
227
|
} else if (error instanceof SessionKeyExpiredError) {
|
|
199
228
|
console.log(`β Session key expired at ${error.expiredAt}`);
|
|
200
|
-
console.log(' Request a new key from the wallet owner.');
|
|
201
229
|
} else {
|
|
202
230
|
throw error;
|
|
203
231
|
}
|
|
@@ -227,28 +255,6 @@ const wallet = new AgentWallet({
|
|
|
227
255
|
|
|
228
256
|
// Or toggle at runtime
|
|
229
257
|
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
258
|
```
|
|
253
259
|
|
|
254
260
|
## π€ AI Framework Integrations
|
|
@@ -256,15 +262,14 @@ if (diagnostics.healthy) {
|
|
|
256
262
|
### Vercel AI SDK
|
|
257
263
|
|
|
258
264
|
```typescript
|
|
259
|
-
import { AgentWallet,
|
|
265
|
+
import { AgentWallet, SessionLimitExceededError } from '@mixrpay/agent-sdk';
|
|
260
266
|
import { generateText } from 'ai';
|
|
261
267
|
import { openai } from '@ai-sdk/openai';
|
|
262
268
|
import { z } from 'zod';
|
|
263
269
|
|
|
264
270
|
const wallet = new AgentWallet({
|
|
265
271
|
sessionKey: process.env.MIXRPAY_SESSION_KEY!,
|
|
266
|
-
maxPaymentUsd: 1.00,
|
|
267
|
-
onPayment: (p) => console.log(`Paid $${p.amountUsd} for API call`),
|
|
272
|
+
maxPaymentUsd: 1.00,
|
|
268
273
|
});
|
|
269
274
|
|
|
270
275
|
const result = await generateText({
|
|
@@ -275,25 +280,23 @@ const result = await generateText({
|
|
|
275
280
|
parameters: z.object({ query: z.string() }),
|
|
276
281
|
execute: async ({ query }) => {
|
|
277
282
|
try {
|
|
278
|
-
const response = await wallet.
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
283
|
+
const response = await wallet.callMerchantApi({
|
|
284
|
+
url: 'https://api.search.com/query',
|
|
285
|
+
merchantPublicKey: 'pk_live_...',
|
|
286
|
+
priceUsd: 0.05,
|
|
287
|
+
body: { query }
|
|
282
288
|
});
|
|
283
289
|
return response.json();
|
|
284
290
|
} catch (error) {
|
|
285
|
-
if (error instanceof
|
|
286
|
-
return { error: '
|
|
291
|
+
if (error instanceof SessionLimitExceededError) {
|
|
292
|
+
return { error: 'Budget exceeded', limit: error.limitType };
|
|
287
293
|
}
|
|
288
|
-
|
|
289
|
-
return { error: 'Spending limit reached', limit: error.limitType };
|
|
290
|
-
}
|
|
291
|
-
throw error; // Re-throw unexpected errors
|
|
294
|
+
throw error;
|
|
292
295
|
}
|
|
293
296
|
}
|
|
294
297
|
}
|
|
295
298
|
},
|
|
296
|
-
prompt: 'Search for the latest AI news
|
|
299
|
+
prompt: 'Search for the latest AI news'
|
|
297
300
|
});
|
|
298
301
|
```
|
|
299
302
|
|
|
@@ -305,33 +308,30 @@ import { DynamicTool } from '@langchain/core/tools';
|
|
|
305
308
|
|
|
306
309
|
const wallet = new AgentWallet({
|
|
307
310
|
sessionKey: process.env.MIXRPAY_SESSION_KEY!,
|
|
308
|
-
maxPaymentUsd: 0.50,
|
|
311
|
+
maxPaymentUsd: 0.50,
|
|
309
312
|
});
|
|
310
313
|
|
|
311
314
|
const paidSearchTool = new DynamicTool({
|
|
312
315
|
name: 'paid_search',
|
|
313
|
-
description: 'Premium search API ($0.05/query)
|
|
316
|
+
description: 'Premium search API ($0.05/query)',
|
|
314
317
|
func: async (query: string) => {
|
|
315
318
|
try {
|
|
316
|
-
const response = await wallet.
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
319
|
+
const response = await wallet.callMerchantApi({
|
|
320
|
+
url: 'https://api.search.com/query',
|
|
321
|
+
merchantPublicKey: 'pk_live_...',
|
|
322
|
+
priceUsd: 0.05,
|
|
323
|
+
body: { query }
|
|
320
324
|
});
|
|
321
325
|
const data = await response.json();
|
|
322
326
|
return JSON.stringify(data.results);
|
|
323
327
|
} catch (error) {
|
|
324
328
|
if (error instanceof InsufficientBalanceError) {
|
|
325
|
-
return `Error: Low balance
|
|
329
|
+
return `Error: Low balance. Top up: ${error.topUpUrl}`;
|
|
326
330
|
}
|
|
327
|
-
return `Error: ${error instanceof Error ? error.message : 'Unknown
|
|
331
|
+
return `Error: ${error instanceof Error ? error.message : 'Unknown'}`;
|
|
328
332
|
}
|
|
329
333
|
}
|
|
330
334
|
});
|
|
331
|
-
|
|
332
|
-
// Check spending before expensive operations
|
|
333
|
-
const stats = await wallet.getSpendingStats();
|
|
334
|
-
console.log(`Budget remaining: $${stats.remainingDailyUsd ?? 'unlimited'}`);
|
|
335
335
|
```
|
|
336
336
|
|
|
337
337
|
## π API Reference
|
|
@@ -354,11 +354,17 @@ new AgentWallet({
|
|
|
354
354
|
})
|
|
355
355
|
```
|
|
356
356
|
|
|
357
|
-
|
|
357
|
+
### Methods
|
|
358
358
|
|
|
359
359
|
| Method | Description |
|
|
360
360
|
|--------|-------------|
|
|
361
|
-
| `
|
|
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 |
|
|
362
368
|
| `getBalance()` | Get USDC balance in USD |
|
|
363
369
|
| `getSpendingStats()` | Get spending statistics |
|
|
364
370
|
| `getSessionKeyInfo()` | Get session key details and limits |
|
|
@@ -369,44 +375,54 @@ new AgentWallet({
|
|
|
369
375
|
| `isTestnet()` | Check if using testnet |
|
|
370
376
|
| `runDiagnostics()` | Run health checks |
|
|
371
377
|
| `setDebug(enable)` | Toggle debug logging |
|
|
372
|
-
| `setLogLevel(level)` | Set log level |
|
|
373
378
|
|
|
374
379
|
### Types
|
|
375
380
|
|
|
376
381
|
```typescript
|
|
377
|
-
interface
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
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;
|
|
384
392
|
}
|
|
385
393
|
|
|
386
|
-
interface
|
|
394
|
+
interface SessionStats {
|
|
395
|
+
activeCount: number;
|
|
396
|
+
expiredCount: number;
|
|
397
|
+
revokedCount: number;
|
|
398
|
+
totalAuthorizedUsd: number;
|
|
387
399
|
totalSpentUsd: number;
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
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
|
+
}>;
|
|
392
409
|
}
|
|
393
410
|
|
|
394
|
-
interface
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
name?: string;
|
|
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;
|
|
410
426
|
}
|
|
411
427
|
```
|
|
412
428
|
|
|
@@ -416,10 +432,14 @@ interface SessionKeyInfo {
|
|
|
416
432
|
|-----------|-------------|
|
|
417
433
|
| `InsufficientBalanceError` | Wallet doesn't have enough USDC |
|
|
418
434
|
| `SessionKeyExpiredError` | Session key has expired |
|
|
419
|
-
| `SpendingLimitExceededError` |
|
|
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 |
|
|
420
440
|
| `PaymentFailedError` | Payment transaction failed |
|
|
421
441
|
| `InvalidSessionKeyError` | Invalid session key format |
|
|
422
|
-
| `X402ProtocolError` |
|
|
442
|
+
| `X402ProtocolError` | x402 protocol handling error |
|
|
423
443
|
|
|
424
444
|
## π Networks
|
|
425
445
|
|
|
@@ -430,19 +450,15 @@ interface SessionKeyInfo {
|
|
|
430
450
|
|
|
431
451
|
### Testing on Testnet
|
|
432
452
|
|
|
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
453
|
```typescript
|
|
439
454
|
// Test environment setup
|
|
440
455
|
const wallet = new AgentWallet({
|
|
441
|
-
sessionKey:
|
|
442
|
-
baseUrl: 'http://localhost:3000', //
|
|
456
|
+
sessionKey: 'sk_test_...', // Use test key
|
|
457
|
+
baseUrl: 'http://localhost:3000', // Local dev server
|
|
443
458
|
});
|
|
444
459
|
|
|
445
460
|
// The SDK automatically detects testnet from sk_test_ prefix
|
|
461
|
+
console.log(`Testnet: ${wallet.isTestnet()}`); // true
|
|
446
462
|
```
|
|
447
463
|
|
|
448
464
|
## π§ Environment Variables
|
|
@@ -452,32 +468,6 @@ const wallet = new AgentWallet({
|
|
|
452
468
|
| `MIXRPAY_SESSION_KEY` | Yes | Your session key (`sk_live_...` or `sk_test_...`) |
|
|
453
469
|
| `MIXRPAY_BASE_URL` | No | MixrPay server URL (default: `https://mixrpay.com`) |
|
|
454
470
|
|
|
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
|
-
```
|
|
480
|
-
|
|
481
471
|
## π Security Best Practices
|
|
482
472
|
|
|
483
473
|
1. **Store session keys securely** - Use environment variables, never commit to source
|
|
@@ -486,22 +476,19 @@ MIXRPAY_BASE_URL=http://localhost:3000
|
|
|
486
476
|
4. **Use testnet first** - Test with `sk_test_` keys before production
|
|
487
477
|
5. **Configure base URL** - Always set `baseUrl` explicitly in production
|
|
488
478
|
|
|
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
479
|
## π Changelog
|
|
494
480
|
|
|
495
|
-
### v0.
|
|
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
|
|
486
|
+
|
|
487
|
+
### v0.1.0
|
|
496
488
|
- 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.
|
|
489
|
+
- x402 payment handling via `fetch()`
|
|
490
|
+
- Session key validation and spending limits
|
|
491
|
+
- Payment callbacks and statistics
|
|
505
492
|
|
|
506
493
|
## π License
|
|
507
494
|
|