lane-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 +1061 -0
- package/dist/cli/index.js +7413 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/index.cjs +3249 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1985 -0
- package/dist/index.d.ts +1985 -0
- package/dist/index.js +3200 -0
- package/dist/index.js.map +1 -0
- package/dist/server/index.js +2610 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server-http.cjs +2378 -0
- package/dist/server-http.cjs.map +1 -0
- package/dist/server-http.js +2376 -0
- package/dist/server-http.js.map +1 -0
- package/dist/server-stdio.cjs +2356 -0
- package/dist/server-stdio.cjs.map +1 -0
- package/dist/server-stdio.js +2354 -0
- package/dist/server-stdio.js.map +1 -0
- package/package.json +68 -0
package/README.md
ADDED
|
@@ -0,0 +1,1061 @@
|
|
|
1
|
+
# Lane Agent SDK
|
|
2
|
+
|
|
3
|
+
> `npm install lane` — Add wallets and payments to your AI agents.
|
|
4
|
+
|
|
5
|
+
Lane is the payment infrastructure for AI agents. It lets agent developers give their agents the ability to discover merchants, manage payment methods, and complete purchases — all through a type-safe SDK, 14 MCP tools, and a CLI.
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
import Lane from 'lane'
|
|
9
|
+
|
|
10
|
+
const lane = Lane.fromApiKey(process.env.LANE_KEY!)
|
|
11
|
+
|
|
12
|
+
// Discover merchants
|
|
13
|
+
const { data: merchants } = await lane.merchants.list({ query: 'sneakers' })
|
|
14
|
+
const merchant = merchants[0]
|
|
15
|
+
|
|
16
|
+
// Search products
|
|
17
|
+
const { data: products } = await lane.products.search({ query: 'jordan 4' })
|
|
18
|
+
|
|
19
|
+
// Execute payment
|
|
20
|
+
const txn = await lane.pay.execute({
|
|
21
|
+
recipient: merchant.domain,
|
|
22
|
+
amount: 19999, // cents
|
|
23
|
+
currency: 'USD',
|
|
24
|
+
description: 'Jordan 4 Retro',
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
console.log(txn.status) // 'success'
|
|
28
|
+
console.log(txn.receiptUrl) // 'https://...'
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Table of Contents
|
|
32
|
+
|
|
33
|
+
- [How It Works](#how-it-works)
|
|
34
|
+
- [Quick Start](#quick-start)
|
|
35
|
+
- [Authentication](#authentication)
|
|
36
|
+
- [SDK Resources](#sdk-resources)
|
|
37
|
+
- [MCP Integration](#mcp-integration)
|
|
38
|
+
- [CLI](#cli)
|
|
39
|
+
- [Payment Routing](#payment-routing)
|
|
40
|
+
- [Merchant Directory](#merchant-directory)
|
|
41
|
+
- [Security](#security)
|
|
42
|
+
- [Enterprise Features](#enterprise-features)
|
|
43
|
+
- [Server](#server)
|
|
44
|
+
- [Architecture](#architecture)
|
|
45
|
+
- [Development](#development)
|
|
46
|
+
|
|
47
|
+
## How It Works
|
|
48
|
+
|
|
49
|
+
### End-to-End Agent Payment Flow
|
|
50
|
+
|
|
51
|
+
This is the core flow when an AI agent discovers a merchant and makes a purchase:
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
AI Agent (Claude, Cursor, etc.)
|
|
55
|
+
│
|
|
56
|
+
│ 1. "Find me sneakers under $200"
|
|
57
|
+
│
|
|
58
|
+
▼
|
|
59
|
+
┌──────────────────────────────────────────────────────────────────────────┐
|
|
60
|
+
│ Lane SDK │
|
|
61
|
+
│ │
|
|
62
|
+
│ ┌─────────────────┐ ┌─────────────────┐ ┌──────────────────────┐ │
|
|
63
|
+
│ │ 2. DISCOVER │ │ 3. SEARCH │ │ 4. PAY │ │
|
|
64
|
+
│ │ │ │ │ │ │ │
|
|
65
|
+
│ │ merchants.list │───▶│ products.search │───▶│ pay.execute │ │
|
|
66
|
+
│ │ ({ query: │ │ ({ query: │ │ ({ recipient, │ │
|
|
67
|
+
│ │ "sneakers" }) │ │ "jordan 4" }) │ │ amount: 19999 }) │ │
|
|
68
|
+
│ └────────┬─────────┘ └────────┬─────────┘ └──────────┬───────────┘ │
|
|
69
|
+
│ │ │ │ │
|
|
70
|
+
└───────────┼───────────────────────┼──────────────────────────┼────────────┘
|
|
71
|
+
│ │ │
|
|
72
|
+
▼ ▼ ▼
|
|
73
|
+
┌───────────────────┐ ┌───────────────────┐ ┌────────────────────────────┐
|
|
74
|
+
│ Merchant Directory│ │ Product Catalog │ │ Payment Pipeline │
|
|
75
|
+
│ │ │ │ │ │
|
|
76
|
+
│ • Legendary │ │ • Jordan 4 Retro │ │ Budget ──▶ Route ──▶ PSP │
|
|
77
|
+
│ Sneakers │ │ $199.99 │ │ Check Engine Charge│
|
|
78
|
+
│ • tier: onboarded │ │ • Air Max 90 │ │ │
|
|
79
|
+
│ • fashion/shoes │ │ $129.99 │ │ ┌────────────────────┐ │
|
|
80
|
+
│ │ │ │ │ │ Routing Decision: │ │
|
|
81
|
+
│ │ │ │ │ │ billing_api (Tier 1)│ │
|
|
82
|
+
│ │ │ │ │ └────────────────────┘ │
|
|
83
|
+
└───────────────────┘ └───────────────────┘ └────────────────────────────┘
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Three Ways to Integrate
|
|
87
|
+
|
|
88
|
+
```
|
|
89
|
+
┌─────────────────────────────────────────────────────────────────────────┐
|
|
90
|
+
│ Your Application │
|
|
91
|
+
├──────────────────┬────────────────────────┬──────────────────────────────┤
|
|
92
|
+
│ │ │ │
|
|
93
|
+
│ MCP Server │ SDK (TypeScript) │ CLI │
|
|
94
|
+
│ │ │ │
|
|
95
|
+
│ For AI agents │ For application code │ For developers & scripts │
|
|
96
|
+
│ that speak MCP │ that calls Lane APIs │ that need quick access │
|
|
97
|
+
│ │ │ │
|
|
98
|
+
│ 14 tools: │ 17 resources: │ 16 commands: │
|
|
99
|
+
│ • discover_ │ • lane.merchants │ • lane login │
|
|
100
|
+
│ merchants │ • lane.pay │ • lane pay │
|
|
101
|
+
│ • pay │ • lane.wallets │ • lane balance │
|
|
102
|
+
│ • checkout │ • lane.checkout │ • lane checkout │
|
|
103
|
+
│ • check_balance │ • lane.admin │ • lane set-budget │
|
|
104
|
+
│ • ... │ • ... │ • ... │
|
|
105
|
+
│ │ │ │
|
|
106
|
+
│ ┌────────────┐ │ ┌──────────────────┐ │ ┌────────────────────────┐ │
|
|
107
|
+
│ │ stdio or │ │ │ Lane.fromApiKey() │ │ │ npx lane <command> │ │
|
|
108
|
+
│ │ HTTP │ │ │ Lane.create() │ │ │ Reads ~/.lane/creds │ │
|
|
109
|
+
│ │ transport │ │ │ │ │ │ │ │
|
|
110
|
+
│ └─────┬──────┘ │ └────────┬─────────┘ │ └───────────┬───────────┘ │
|
|
111
|
+
│ │ │ │ │ │ │
|
|
112
|
+
├────────┴─────────┴───────────┴─────────────┴──────────────┴──────────────┤
|
|
113
|
+
│ Lane HTTP Client │
|
|
114
|
+
│ HMAC-SHA256 · Retries · Circuit Breaker │
|
|
115
|
+
└──────────────────────────────────┬───────────────────────────────────────┘
|
|
116
|
+
│
|
|
117
|
+
▼
|
|
118
|
+
Lane API Server
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Payment Routing Decision Tree
|
|
122
|
+
|
|
123
|
+
```
|
|
124
|
+
Incoming Payment
|
|
125
|
+
│
|
|
126
|
+
▼
|
|
127
|
+
┌───────────────────┐
|
|
128
|
+
│ Budget Check │
|
|
129
|
+
│ within limits? │
|
|
130
|
+
└────────┬──────────┘
|
|
131
|
+
│
|
|
132
|
+
┌────────┴────────┐
|
|
133
|
+
│ NO │ YES
|
|
134
|
+
▼ ▼
|
|
135
|
+
┌──────────┐ ┌──────────────────┐
|
|
136
|
+
│ DENIED │ │ Lookup Merchant │
|
|
137
|
+
│ budget │ │ in Registry │
|
|
138
|
+
│ exceeded│ └────────┬──────────┘
|
|
139
|
+
└──────────┘ │
|
|
140
|
+
┌────────┴─────────┐
|
|
141
|
+
│ │
|
|
142
|
+
▼ ▼
|
|
143
|
+
Has Billing API? Supports ACP?
|
|
144
|
+
│ │
|
|
145
|
+
┌─────┴─────┐ ┌─────┴─────┐
|
|
146
|
+
│YES │NO │YES │NO
|
|
147
|
+
▼ │ ▼ │
|
|
148
|
+
┌─────────────┐ │ ┌──────────┐ │
|
|
149
|
+
│ TIER 1 │ │ │ TIER 2 │ │
|
|
150
|
+
│ Billing API │ │ │ ACP │ │
|
|
151
|
+
│ (cheapest) │ │ │(protocol)│ │
|
|
152
|
+
└─────────────┘ │ └──────────┘ │
|
|
153
|
+
│ │
|
|
154
|
+
└─────────┬─────────┘
|
|
155
|
+
│
|
|
156
|
+
▼
|
|
157
|
+
Has VIC Token +
|
|
158
|
+
Visa Card?
|
|
159
|
+
│
|
|
160
|
+
┌─────┴─────┐
|
|
161
|
+
│YES │NO
|
|
162
|
+
▼ ▼
|
|
163
|
+
┌──────────┐ ┌──────────┐
|
|
164
|
+
│ TIER 3 │ │ TIER 4 │
|
|
165
|
+
│ VIC │ │ Fallback │
|
|
166
|
+
│ (Visa │ │ (standard│
|
|
167
|
+
│ network)│ │ card) │
|
|
168
|
+
└──────────┘ └──────────┘
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Merchant Discovery Flow
|
|
172
|
+
|
|
173
|
+
```
|
|
174
|
+
┌──────────────────────────────────────────┐
|
|
175
|
+
│ Merchant Directory Service │
|
|
176
|
+
│ │
|
|
177
|
+
│ In-Memory Cache (refreshed every 30m) │
|
|
178
|
+
└───────────┬──────────────┬───────────────┘
|
|
179
|
+
│ │
|
|
180
|
+
┌─────────────────┘ └──────────────────┐
|
|
181
|
+
│ │
|
|
182
|
+
▼ ▼
|
|
183
|
+
┌─────────────────────┐ ┌──────────────────────┐
|
|
184
|
+
│ Lane-Onboarded │ │ Protocol Discovery │
|
|
185
|
+
│ (Tier 1) │ │ (Tier 2) │
|
|
186
|
+
│ │ │ │
|
|
187
|
+
│ Sync from Lane │ │ Probe domain: │
|
|
188
|
+
│ backend on startup │ │ │
|
|
189
|
+
│ │ │ GET /.well-known/ucp│
|
|
190
|
+
│ POST /merchants/ │ │ GET /.well-known/acp│
|
|
191
|
+
│ sync │ │ │
|
|
192
|
+
│ │ │ POST /merchants/ │
|
|
193
|
+
│ Full checkout API │ │ discover │
|
|
194
|
+
│ Product catalog │ │ │
|
|
195
|
+
│ Payment routing │ │ Protocol endpoints │
|
|
196
|
+
└─────────┬───────────┘ │ Cached manifests │
|
|
197
|
+
│ └──────────┬───────────┘
|
|
198
|
+
│ │
|
|
199
|
+
▼ ▼
|
|
200
|
+
┌──────────────────────────────────────────────────────────────────────┐
|
|
201
|
+
│ merchant_directory (PostgreSQL) │
|
|
202
|
+
│ │
|
|
203
|
+
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
|
204
|
+
│ │ id │ name │ tier │ type │ vertical │ │
|
|
205
|
+
│ ├────┼────────────────────┼───────────────┼───────────┼──────────┤ │
|
|
206
|
+
│ │ ...│ Legendary Sneakers │ lane_onboarded│ ecommerce │ fashion │ │
|
|
207
|
+
│ │ ...│ shop.example.com │ protocol │ ecommerce │ ... │ │
|
|
208
|
+
│ └─────────────────────────────────────────────────────────────────┘ │
|
|
209
|
+
│ │
|
|
210
|
+
│ Indexes: slug (unique), domain (unique), subcategories (GIN), │
|
|
211
|
+
│ name (trigram), tier, status, merchant_type, vertical │
|
|
212
|
+
└──────────────────────────────────────────────────────────────────────┘
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### Security & Card Data Flow
|
|
216
|
+
|
|
217
|
+
```
|
|
218
|
+
Agent adds a card
|
|
219
|
+
│
|
|
220
|
+
▼
|
|
221
|
+
┌────────────────────┐
|
|
222
|
+
│ VGS Collect Form │ Card PAN entered in
|
|
223
|
+
│ (iframe/hosted) │ VGS-controlled form
|
|
224
|
+
└─────────┬──────────┘
|
|
225
|
+
│
|
|
226
|
+
│ PAN goes directly to VGS
|
|
227
|
+
│ (never touches Lane servers)
|
|
228
|
+
▼
|
|
229
|
+
┌────────────────────┐
|
|
230
|
+
│ VGS Vault │ PAN stored as token
|
|
231
|
+
│ │ tok_4111...1234
|
|
232
|
+
│ PCI DSS Level 1 │
|
|
233
|
+
└─────────┬──────────┘
|
|
234
|
+
│
|
|
235
|
+
│ Token (alias) returned
|
|
236
|
+
▼
|
|
237
|
+
┌────────────────────┐
|
|
238
|
+
│ Lane Server │ Stores only: last4,
|
|
239
|
+
│ │ brand, token alias
|
|
240
|
+
│ Never sees PAN │ (never the full PAN)
|
|
241
|
+
└─────────┬──────────┘
|
|
242
|
+
│
|
|
243
|
+
│ Payment request with token
|
|
244
|
+
▼
|
|
245
|
+
┌────────────────────┐
|
|
246
|
+
│ VGS Outbound │ VGS replaces token
|
|
247
|
+
│ Proxy │ with real PAN in-flight
|
|
248
|
+
└─────────┬──────────┘
|
|
249
|
+
│
|
|
250
|
+
│ Real PAN sent to PSP
|
|
251
|
+
▼
|
|
252
|
+
┌────────────────────┐
|
|
253
|
+
│ PSP │ Stripe / Worldpay /
|
|
254
|
+
│ (Payment │ CyberSource processes
|
|
255
|
+
│ Processor) │ the charge
|
|
256
|
+
└────────────────────┘
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
### Enterprise Budget Enforcement
|
|
260
|
+
|
|
261
|
+
```
|
|
262
|
+
Payment Request ($150)
|
|
263
|
+
│
|
|
264
|
+
▼
|
|
265
|
+
┌─────────────────────────────────────┐
|
|
266
|
+
│ Hierarchical Budget Check │
|
|
267
|
+
│ │
|
|
268
|
+
│ Org Budget $10,000/mo ✓ pass │
|
|
269
|
+
│ │ │
|
|
270
|
+
│ ▼ │
|
|
271
|
+
│ Team Budget $2,000/mo ✓ pass │
|
|
272
|
+
│ │ │
|
|
273
|
+
│ ▼ │
|
|
274
|
+
│ Dev Budget $500/day ✓ pass │
|
|
275
|
+
│ │ │
|
|
276
|
+
│ ▼ │
|
|
277
|
+
│ Agent Policy $200/txn ✓ pass │
|
|
278
|
+
│ │ │
|
|
279
|
+
│ ▼ │
|
|
280
|
+
│ Merchant allowlist ✓ pass │
|
|
281
|
+
│ Allowlist check │
|
|
282
|
+
│ │ │
|
|
283
|
+
│ ▼ │
|
|
284
|
+
│ MCC Check 5661 (shoes) ✓ pass │
|
|
285
|
+
│ │
|
|
286
|
+
│ Effective limit = min(all levels) │
|
|
287
|
+
└────────────────┬────────────────────┘
|
|
288
|
+
│
|
|
289
|
+
All passed
|
|
290
|
+
│
|
|
291
|
+
▼
|
|
292
|
+
Route to Payment
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
## Quick Start
|
|
296
|
+
|
|
297
|
+
```bash
|
|
298
|
+
# Install
|
|
299
|
+
npm install lane
|
|
300
|
+
|
|
301
|
+
# Authenticate (opens browser)
|
|
302
|
+
npx lane login
|
|
303
|
+
|
|
304
|
+
# Verify
|
|
305
|
+
npx lane whoami
|
|
306
|
+
|
|
307
|
+
# Check balance
|
|
308
|
+
npx lane balance
|
|
309
|
+
|
|
310
|
+
# Make a payment
|
|
311
|
+
npx lane pay --recipient replicate.com --amount 20.00
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
### Programmatic Usage
|
|
315
|
+
|
|
316
|
+
```ts
|
|
317
|
+
import Lane from 'lane'
|
|
318
|
+
|
|
319
|
+
// Option 1: Async config resolution (constructor > env > credentials file)
|
|
320
|
+
const lane = await Lane.create()
|
|
321
|
+
|
|
322
|
+
// Option 2: Explicit API key
|
|
323
|
+
const lane = Lane.fromApiKey('lane_sk_...')
|
|
324
|
+
|
|
325
|
+
// Option 3: Test mode
|
|
326
|
+
const lane = Lane.fromApiKey('lane_sk_test_...', { testMode: true })
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
## Authentication
|
|
330
|
+
|
|
331
|
+
Config resolution order (first match wins):
|
|
332
|
+
|
|
333
|
+
1. **Constructor:** `Lane.fromApiKey('lane_sk_...')` or `Lane.create({ apiKey: '...' })`
|
|
334
|
+
2. **Environment variable:** `LANE_API_KEY`
|
|
335
|
+
3. **Credentials file:** `~/.lane/credentials.json` (written by `npx lane login`)
|
|
336
|
+
|
|
337
|
+
```ts
|
|
338
|
+
// Check who you are
|
|
339
|
+
const profile = await lane.auth.whoami()
|
|
340
|
+
// { id: 'dev_...', email: 'you@company.com', plan: 'pro', memberSince: '2025-01-15' }
|
|
341
|
+
|
|
342
|
+
// Rotate API key (old key valid for 15 min)
|
|
343
|
+
const { apiKey, expiresOldKeyAt } = await lane.auth.rotateKey()
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
## SDK Resources
|
|
347
|
+
|
|
348
|
+
The SDK exposes 17 resource classes, all lazily initialized on first access.
|
|
349
|
+
|
|
350
|
+
### Core Resources
|
|
351
|
+
|
|
352
|
+
| Resource | Description | Key Methods |
|
|
353
|
+
|---|---|---|
|
|
354
|
+
| `lane.auth` | Authentication & key management | `whoami()`, `login()`, `rotateKey()` |
|
|
355
|
+
| `lane.wallets` | Wallet lifecycle & cards | `create()`, `list()`, `balance()`, `deposit()`, `listCards()`, `getAddCardLink()` |
|
|
356
|
+
| `lane.pay` | Payment execution | `createToken()`, `execute()`, `listTransactions()`, `refund()` |
|
|
357
|
+
| `lane.products` | Product discovery | `search()`, `get()`, `listMerchants()` |
|
|
358
|
+
| `lane.checkout` | Checkout sessions | `create()`, `complete()`, `get()`, `cancel()` |
|
|
359
|
+
| `lane.merchants` | Merchant directory | `list()`, `get()`, `listByVertical()`, `discover()`, `verticals()` |
|
|
360
|
+
| `lane.sell` | Seller tools (Make-a-SaaS) | `create()`, `list()`, `analytics()`, `createSoftwareProduct()` |
|
|
361
|
+
| `lane.webhooks` | Webhook management | `create()`, `list()`, `verify()`, `constructEvent()` |
|
|
362
|
+
| `lane.admin` | Spending & budgets | `spending()`, `setBudget()`, `listMembers()`, `exportData()` |
|
|
363
|
+
| `lane.subscriptions` | Subscription management | `create()`, `cancel()`, `upgrade()`, `pause()`, `resume()` |
|
|
364
|
+
|
|
365
|
+
### Phase 2 — VIC (Visa Intelligent Commerce)
|
|
366
|
+
|
|
367
|
+
| Resource | Description | Key Methods |
|
|
368
|
+
|---|---|---|
|
|
369
|
+
| `lane.vic` | Visa network tokens | `issue()`, `getCryptogram()`, `revoke()`, `suspend()` |
|
|
370
|
+
|
|
371
|
+
### Phase 4 — Make-a-SaaS
|
|
372
|
+
|
|
373
|
+
| Resource | Description | Key Methods |
|
|
374
|
+
|---|---|---|
|
|
375
|
+
| `lane.metering` | Usage tracking for sellers | `record()`, `recordBatch()`, `report()`, `setConfig()` |
|
|
376
|
+
| `lane.payouts` | Seller disbursements | `getConfig()`, `setConfig()`, `list()` |
|
|
377
|
+
|
|
378
|
+
### Phase 5 — Corporate Agent Spend
|
|
379
|
+
|
|
380
|
+
| Resource | Description | Key Methods |
|
|
381
|
+
|---|---|---|
|
|
382
|
+
| `lane.teams` | Team management | `create()`, `addMember()`, `setBudget()`, `getHierarchicalBudget()` |
|
|
383
|
+
| `lane.agents` | Agent fleet management | `register()`, `setPolicy()`, `suspend()`, `assignWallet()` |
|
|
384
|
+
| `lane.audit` | SOC 2 audit trail | `query()`, `export()`, `summary()` |
|
|
385
|
+
|
|
386
|
+
### Phase 6 — Agent Identity
|
|
387
|
+
|
|
388
|
+
| Resource | Description | Key Methods |
|
|
389
|
+
|---|---|---|
|
|
390
|
+
| `lane.identity` | Agent KYC chain | `register()`, `verify()`, `getAttestation()`, `refreshAttestation()` |
|
|
391
|
+
|
|
392
|
+
### Usage Examples
|
|
393
|
+
|
|
394
|
+
```ts
|
|
395
|
+
// Wallets & Cards
|
|
396
|
+
const wallet = await lane.wallets.create({ userId: 'user_123' })
|
|
397
|
+
const cards = await lane.wallets.listCards(wallet.id)
|
|
398
|
+
const balance = await lane.wallets.balance(wallet.id)
|
|
399
|
+
|
|
400
|
+
// Payments
|
|
401
|
+
const token = await lane.pay.createToken({
|
|
402
|
+
walletId: wallet.id,
|
|
403
|
+
amount: 5000,
|
|
404
|
+
merchant: 'legendarysneakers.com',
|
|
405
|
+
expiresIn: '1h',
|
|
406
|
+
})
|
|
407
|
+
const txn = await lane.pay.execute({
|
|
408
|
+
tokenId: token.id,
|
|
409
|
+
recipient: 'legendarysneakers.com',
|
|
410
|
+
amount: 4999,
|
|
411
|
+
})
|
|
412
|
+
|
|
413
|
+
// Refunds
|
|
414
|
+
const refund = await lane.pay.refund({
|
|
415
|
+
transactionId: txn.id,
|
|
416
|
+
reason: 'Wrong size',
|
|
417
|
+
})
|
|
418
|
+
|
|
419
|
+
// Checkout profiles (saved address/email for faster checkout)
|
|
420
|
+
await lane.wallets.setProfile(wallet.id, {
|
|
421
|
+
email: 'agent@company.com',
|
|
422
|
+
fullName: 'AI Agent',
|
|
423
|
+
billingLine1: '123 Main St',
|
|
424
|
+
billingCity: 'San Francisco',
|
|
425
|
+
billingState: 'CA',
|
|
426
|
+
billingPostalCode: '94105',
|
|
427
|
+
billingCountry: 'US',
|
|
428
|
+
})
|
|
429
|
+
|
|
430
|
+
// Merchant accounts (saved credentials per merchant)
|
|
431
|
+
await lane.wallets.saveMerchantAccount(wallet.id, {
|
|
432
|
+
merchantDomain: 'legendarysneakers.com',
|
|
433
|
+
merchantName: 'Legendary Sneakers',
|
|
434
|
+
authType: 'api_key',
|
|
435
|
+
apiKeyAlias: 'vgs_tok_...',
|
|
436
|
+
})
|
|
437
|
+
|
|
438
|
+
// Budgets
|
|
439
|
+
await lane.admin.setBudget({
|
|
440
|
+
dailyLimit: 10000, // $100.00
|
|
441
|
+
perTaskLimit: 5000, // $50.00
|
|
442
|
+
merchantAllowlist: ['legendarysneakers.com'],
|
|
443
|
+
})
|
|
444
|
+
|
|
445
|
+
// Subscriptions
|
|
446
|
+
const sub = await lane.subscriptions.create({
|
|
447
|
+
productId: 'prod_...',
|
|
448
|
+
plan: 'pro',
|
|
449
|
+
paymentSource: 'wallet',
|
|
450
|
+
})
|
|
451
|
+
|
|
452
|
+
// Agent fleet management
|
|
453
|
+
const agent = await lane.agents.register({
|
|
454
|
+
name: 'shopping-agent',
|
|
455
|
+
type: 'autonomous',
|
|
456
|
+
walletId: wallet.id,
|
|
457
|
+
policy: {
|
|
458
|
+
budget: { dailyLimit: 5000 },
|
|
459
|
+
maxTransactionAmount: 2500,
|
|
460
|
+
canDiscover: true,
|
|
461
|
+
canRefund: false,
|
|
462
|
+
},
|
|
463
|
+
})
|
|
464
|
+
|
|
465
|
+
// Webhooks
|
|
466
|
+
await lane.webhooks.create({
|
|
467
|
+
url: 'https://api.myapp.com/hooks/lane',
|
|
468
|
+
events: ['transaction.completed', 'budget.exceeded'],
|
|
469
|
+
})
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
## MCP Integration
|
|
473
|
+
|
|
474
|
+
Lane ships with 14 MCP tools that any AI agent (Claude, Cursor, etc.) can use out of the box.
|
|
475
|
+
|
|
476
|
+
### Setup
|
|
477
|
+
|
|
478
|
+
```bash
|
|
479
|
+
# Auto-configure for Claude Desktop / Cursor
|
|
480
|
+
npx lane setup-mcp
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
Or add to your `claude_desktop_config.json`:
|
|
484
|
+
|
|
485
|
+
```json
|
|
486
|
+
{
|
|
487
|
+
"mcpServers": {
|
|
488
|
+
"lane": {
|
|
489
|
+
"command": "npx",
|
|
490
|
+
"args": ["lane-mcp-server"],
|
|
491
|
+
"env": {
|
|
492
|
+
"LANE_API_KEY": "lane_sk_..."
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
```
|
|
498
|
+
|
|
499
|
+
### Programmatic MCP Server
|
|
500
|
+
|
|
501
|
+
```ts
|
|
502
|
+
import { Lane, LaneMCPServer } from 'lane'
|
|
503
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
|
|
504
|
+
|
|
505
|
+
const lane = Lane.fromApiKey(process.env.LANE_API_KEY!)
|
|
506
|
+
const server = new LaneMCPServer(lane)
|
|
507
|
+
|
|
508
|
+
const transport = new StdioServerTransport()
|
|
509
|
+
await server.mcp.connect(transport)
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
### Available Tools (14)
|
|
513
|
+
|
|
514
|
+
| Tool | Description | Key Inputs |
|
|
515
|
+
|---|---|---|
|
|
516
|
+
| `whoami` | Get authenticated developer profile | — |
|
|
517
|
+
| `check_balance` | Get wallet balance | `walletId?` |
|
|
518
|
+
| `list_cards` | List cards in wallet | `walletId?` |
|
|
519
|
+
| `pay` | Execute a payment | `amount`, `recipient`, `currency?`, `description?` |
|
|
520
|
+
| `list_transactions` | List transaction history | `limit?`, `offset?` |
|
|
521
|
+
| `search_products` | Search product catalog | `query`, `type?`, `limit?` |
|
|
522
|
+
| `search_software` | Search software products | `query`, `type?`, `pricingModel?` |
|
|
523
|
+
| `checkout` | Purchase a product | `productId`, `walletId?`, `quantity?` |
|
|
524
|
+
| `set_budget` | Set spending limits | `daily?`, `weekly?`, `monthly?`, `perTask?` |
|
|
525
|
+
| `request_refund` | Refund a transaction | `transactionId`, `amount?`, `reason?` |
|
|
526
|
+
| `subscribe` | Create a subscription | `productId`, `plan`, `walletId?` |
|
|
527
|
+
| `list_subscriptions` | List active subscriptions | `status?`, `limit?` |
|
|
528
|
+
| `cancel_subscription` | Cancel a subscription | `subscriptionId` |
|
|
529
|
+
| `discover_merchants` | Search merchant directory | `query?`, `merchantType?`, `vertical?`, `subcategory?` |
|
|
530
|
+
|
|
531
|
+
## CLI
|
|
532
|
+
|
|
533
|
+
```
|
|
534
|
+
lane <command>
|
|
535
|
+
|
|
536
|
+
Authentication:
|
|
537
|
+
lane login Start OAuth login flow (opens browser)
|
|
538
|
+
lane logout Delete stored credentials
|
|
539
|
+
lane whoami Display authenticated developer profile
|
|
540
|
+
lane rotate-key Rotate API key
|
|
541
|
+
|
|
542
|
+
Wallet:
|
|
543
|
+
lane balance Get wallet balance
|
|
544
|
+
lane cards List cards in wallet
|
|
545
|
+
lane add-card Get VGS Collect link to securely add a card
|
|
546
|
+
lane wallet Wallet management (list, create, deposit)
|
|
547
|
+
lane transactions List transaction history
|
|
548
|
+
|
|
549
|
+
Payments:
|
|
550
|
+
lane pay Execute a payment
|
|
551
|
+
lane checkout Purchase a product from catalog
|
|
552
|
+
lane set-budget Set spending limits
|
|
553
|
+
|
|
554
|
+
Seller:
|
|
555
|
+
lane vendor Seller tools (list products, view analytics)
|
|
556
|
+
lane schema Display API schema
|
|
557
|
+
|
|
558
|
+
Setup:
|
|
559
|
+
lane setup-mcp Configure MCP server for Claude/Cursor
|
|
560
|
+
lane dashboard Open Lane dashboard in browser
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
## Payment Routing
|
|
564
|
+
|
|
565
|
+
Lane's routing engine selects the optimal payment path for each transaction using a 4-tier priority system:
|
|
566
|
+
|
|
567
|
+
```
|
|
568
|
+
Tier 1: Billing API — Direct merchant API integration (cheapest, fastest)
|
|
569
|
+
Tier 2: ACP — Agent Commerce Protocol checkout
|
|
570
|
+
Tier 3: VIC — Visa Intelligent Commerce token (works at any Visa merchant)
|
|
571
|
+
Tier 4: Fallback — Standard card payment via PSP
|
|
572
|
+
```
|
|
573
|
+
|
|
574
|
+
The router considers merchant capabilities, card brand, VIC token availability, and budget constraints:
|
|
575
|
+
|
|
576
|
+
```ts
|
|
577
|
+
import { PaymentRouter, MerchantRegistry } from 'lane'
|
|
578
|
+
|
|
579
|
+
const registry = new MerchantRegistry()
|
|
580
|
+
registry.register({
|
|
581
|
+
merchantId: 'merch_123',
|
|
582
|
+
hasBillingAPI: true,
|
|
583
|
+
supportsACP: true,
|
|
584
|
+
supportsVIC: false,
|
|
585
|
+
acceptsVisa: true,
|
|
586
|
+
acceptsMastercard: true,
|
|
587
|
+
mccs: ['5661'],
|
|
588
|
+
})
|
|
589
|
+
|
|
590
|
+
const router = new PaymentRouter(registry)
|
|
591
|
+
const decision = router.route({
|
|
592
|
+
amount: 4999,
|
|
593
|
+
currency: 'USD',
|
|
594
|
+
merchantId: 'merch_123',
|
|
595
|
+
cardBrand: 'visa',
|
|
596
|
+
hasVICToken: false,
|
|
597
|
+
})
|
|
598
|
+
// { route: 'billing_api', reason: 'Merchant has direct billing API integration (cheapest path).', fallbacks: ['acp', 'fallback'] }
|
|
599
|
+
```
|
|
600
|
+
|
|
601
|
+
The `MerchantRegistry` can be populated directly from the merchant directory:
|
|
602
|
+
|
|
603
|
+
```ts
|
|
604
|
+
const capabilities = await container.merchantDirectory.populateRegistry()
|
|
605
|
+
const registry = MerchantRegistry.fromDirectory(capabilities)
|
|
606
|
+
```
|
|
607
|
+
|
|
608
|
+
## Merchant Directory
|
|
609
|
+
|
|
610
|
+
The merchant directory is a live, queryable registry of AI-shoppable merchants. Two tiers:
|
|
611
|
+
|
|
612
|
+
- **Lane-onboarded** — Full checkout API, synced from Lane backend (e.g., Legendary Sneakers)
|
|
613
|
+
- **Protocol-compatible** — Merchants exposing `/.well-known/acp` or `/.well-known/ucp` endpoints
|
|
614
|
+
|
|
615
|
+
### Taxonomy
|
|
616
|
+
|
|
617
|
+
Merchants are classified hierarchically:
|
|
618
|
+
|
|
619
|
+
| Type | Verticals | Example Subcategories |
|
|
620
|
+
|---|---|---|
|
|
621
|
+
| `ecommerce` | fashion, electronics, beauty, home, food_beverage, sports_outdoor, kids_baby | shoes, sneakers, laptops, skincare |
|
|
622
|
+
| `software` | developer_tools, productivity, ai_ml, security | hosting, databases, ci_cd, auth |
|
|
623
|
+
| `api` | data, communications, payments, infrastructure | enrichment, sms, processing, cdn |
|
|
624
|
+
| `saas` | business, marketing, finance | crm, analytics, accounting |
|
|
625
|
+
| `skill` | agent_tools | web_scraping, code_gen, research |
|
|
626
|
+
| `service` | travel, delivery, professional | flights, food, legal |
|
|
627
|
+
|
|
628
|
+
### Vertical-Specific Product Attributes
|
|
629
|
+
|
|
630
|
+
Each merchant stores a `productAttributes` schema tailored to its vertical:
|
|
631
|
+
|
|
632
|
+
```ts
|
|
633
|
+
// Fashion/shoes merchant
|
|
634
|
+
{ available_sizes: ['7','8','9'], colors: ['black','white'], brands: ['Nike','Jordan'] }
|
|
635
|
+
|
|
636
|
+
// Electronics merchant
|
|
637
|
+
{ specs: { ram_gb: 16, storage_gb: 512 }, brand: 'Apple', model_year: 2025 }
|
|
638
|
+
|
|
639
|
+
// Software merchant
|
|
640
|
+
{ runtime: 'node', sdk_package: '@acme/sdk', docs_url: '...' }
|
|
641
|
+
```
|
|
642
|
+
|
|
643
|
+
### Usage
|
|
644
|
+
|
|
645
|
+
```ts
|
|
646
|
+
// Search by text
|
|
647
|
+
const { data } = await lane.merchants.list({ query: 'sneakers' })
|
|
648
|
+
|
|
649
|
+
// Filter by vertical
|
|
650
|
+
const fashion = await lane.merchants.listByVertical('fashion')
|
|
651
|
+
|
|
652
|
+
// Filter by protocol
|
|
653
|
+
const acpMerchants = await lane.merchants.listByProtocol('acp')
|
|
654
|
+
|
|
655
|
+
// Lane-onboarded only
|
|
656
|
+
const onboarded = await lane.merchants.listOnboarded()
|
|
657
|
+
|
|
658
|
+
// List all verticals and subcategories
|
|
659
|
+
const verticals = await lane.merchants.verticals()
|
|
660
|
+
|
|
661
|
+
// Discover a protocol-compatible merchant by domain
|
|
662
|
+
const result = await lane.merchants.discover('shop.example.com')
|
|
663
|
+
```
|
|
664
|
+
|
|
665
|
+
### Seeded Merchants
|
|
666
|
+
|
|
667
|
+
The directory ships with pre-populated merchants including:
|
|
668
|
+
|
|
669
|
+
- **Legendary Sneakers** (`legendarysneakers.com`) — Premium sneakers and streetwear. Lane-onboarded, Shopify/Worldpay, billing API + ACP support. Fashion vertical with sizes 7-13, brands (Nike, Jordan, Adidas, New Balance, Yeezy).
|
|
670
|
+
|
|
671
|
+
Additional merchants are synced from the Lane backend on startup or via the sync API.
|
|
672
|
+
|
|
673
|
+
## Security
|
|
674
|
+
|
|
675
|
+
### PCI DSS Compliance
|
|
676
|
+
|
|
677
|
+
Card PANs **never** touch Lane servers. All card data is tokenized through [VGS](https://www.verygoodsecurity.com/) (Very Good Security):
|
|
678
|
+
|
|
679
|
+
```ts
|
|
680
|
+
import { VGSOutboundProxy, detectCardBrand, luhnCheck } from 'lane'
|
|
681
|
+
|
|
682
|
+
// Card utilities
|
|
683
|
+
detectCardBrand('4111111111111111') // 'visa'
|
|
684
|
+
luhnCheck('4111111111111111') // true
|
|
685
|
+
|
|
686
|
+
// Generate secure card collection form
|
|
687
|
+
import { generateCollectPage } from 'lane'
|
|
688
|
+
const html = generateCollectPage({
|
|
689
|
+
vaultId: 'tnt...',
|
|
690
|
+
environment: 'sandbox',
|
|
691
|
+
formId: 'card-form',
|
|
692
|
+
redirectUrl: 'https://app.example.com/done',
|
|
693
|
+
})
|
|
694
|
+
```
|
|
695
|
+
|
|
696
|
+
### HMAC Request Signing
|
|
697
|
+
|
|
698
|
+
Every SDK request is signed with HMAC-SHA256:
|
|
699
|
+
|
|
700
|
+
```ts
|
|
701
|
+
import { HMACSignature, verifyWebhookSignature } from 'lane'
|
|
702
|
+
|
|
703
|
+
// Verify incoming webhook
|
|
704
|
+
const isValid = verifyWebhookSignature(
|
|
705
|
+
rawBody,
|
|
706
|
+
req.headers['x-lane-signature'],
|
|
707
|
+
webhookSecret,
|
|
708
|
+
parseInt(req.headers['x-lane-timestamp']),
|
|
709
|
+
)
|
|
710
|
+
```
|
|
711
|
+
|
|
712
|
+
### Credential Storage
|
|
713
|
+
|
|
714
|
+
Credentials are stored at `~/.lane/credentials.json` with `0600` file permissions (owner read/write only). Directory permissions are set to `0700`.
|
|
715
|
+
|
|
716
|
+
### HTTP Client Resilience
|
|
717
|
+
|
|
718
|
+
- **Automatic retries** with exponential backoff (1s, 3s, max 5s jitter) on 5xx and 429
|
|
719
|
+
- **Circuit breaker** pattern (3 consecutive failures opens circuit for 30s)
|
|
720
|
+
- **Idempotency keys** to prevent duplicate charges on retry
|
|
721
|
+
- **Rate limit awareness** with `Retry-After` header support
|
|
722
|
+
|
|
723
|
+
## Enterprise Features
|
|
724
|
+
|
|
725
|
+
### Hierarchical Budgets
|
|
726
|
+
|
|
727
|
+
Budget limits cascade: Organization > Team > Developer > Agent. The effective limit is the minimum across all levels.
|
|
728
|
+
|
|
729
|
+
```ts
|
|
730
|
+
// Set team budget
|
|
731
|
+
await lane.teams.setBudget('team_123', {
|
|
732
|
+
dailyLimit: 100000, // $1,000
|
|
733
|
+
monthlyLimit: 1000000, // $10,000
|
|
734
|
+
perTaskLimit: 10000, // $100
|
|
735
|
+
})
|
|
736
|
+
|
|
737
|
+
// View effective limits
|
|
738
|
+
const budget = await lane.teams.getHierarchicalBudget('team_123')
|
|
739
|
+
// { orgBudget, teamBudget, developerBudget, agentBudget, effectiveLimits }
|
|
740
|
+
```
|
|
741
|
+
|
|
742
|
+
### Agent Policies
|
|
743
|
+
|
|
744
|
+
Per-agent spending constraints:
|
|
745
|
+
|
|
746
|
+
```ts
|
|
747
|
+
await lane.agents.setPolicy('agent_123', {
|
|
748
|
+
budget: { dailyLimit: 5000 },
|
|
749
|
+
allowedMCCs: ['5661', '5699'], // Shoe stores only
|
|
750
|
+
maxTransactionAmount: 25000, // $250 max per transaction
|
|
751
|
+
canRefund: false,
|
|
752
|
+
canDiscover: true,
|
|
753
|
+
approvalThreshold: 10000, // Human approval above $100
|
|
754
|
+
})
|
|
755
|
+
```
|
|
756
|
+
|
|
757
|
+
### Agent Identity & KYC Chain
|
|
758
|
+
|
|
759
|
+
Lane-issued identity credentials with a 4-step verification chain: Human (developer KYC) > Lane (platform verification) > Agent (registration + policy binding) > Transaction (cryptographic attestation).
|
|
760
|
+
|
|
761
|
+
```ts
|
|
762
|
+
const identity = await lane.identity.register({
|
|
763
|
+
agentId: 'agent_123',
|
|
764
|
+
capabilities: ['payments', 'product_discovery'],
|
|
765
|
+
purpose: 'Autonomous shopping assistant',
|
|
766
|
+
})
|
|
767
|
+
|
|
768
|
+
const attestation = await lane.identity.getAttestation(identity.id)
|
|
769
|
+
```
|
|
770
|
+
|
|
771
|
+
### Audit Trail
|
|
772
|
+
|
|
773
|
+
Immutable audit log for SOC 2 compliance:
|
|
774
|
+
|
|
775
|
+
```ts
|
|
776
|
+
const { data: entries } = await lane.audit.query({
|
|
777
|
+
startDate: '2025-01-01',
|
|
778
|
+
actorType: 'agent',
|
|
779
|
+
action: 'payment.execute',
|
|
780
|
+
limit: 50,
|
|
781
|
+
})
|
|
782
|
+
|
|
783
|
+
const summary = await lane.audit.summary({ period: '30d' })
|
|
784
|
+
// { totalEntries, byAction, byActorType, topActors }
|
|
785
|
+
```
|
|
786
|
+
|
|
787
|
+
### GDPR
|
|
788
|
+
|
|
789
|
+
```ts
|
|
790
|
+
const data = await lane.admin.exportData()
|
|
791
|
+
const { deletionCompletesAt } = await lane.admin.deleteAccount()
|
|
792
|
+
```
|
|
793
|
+
|
|
794
|
+
## Server
|
|
795
|
+
|
|
796
|
+
The SDK includes a full Express backend with OOP service architecture.
|
|
797
|
+
|
|
798
|
+
### Environment Variables
|
|
799
|
+
|
|
800
|
+
```bash
|
|
801
|
+
SUPABASE_URL=https://...supabase.co # Required
|
|
802
|
+
SUPABASE_SERVICE_KEY=eyJ0eXAi... # Required
|
|
803
|
+
PORT=3001 # Default: 3001
|
|
804
|
+
LOG_LEVEL=INFO # DEBUG | INFO | WARN | ERROR
|
|
805
|
+
|
|
806
|
+
# Merchant directory sync (optional)
|
|
807
|
+
LANE_BACKEND_URL=https://app.getonlane.com
|
|
808
|
+
LANE_BACKEND_TOKEN=...
|
|
809
|
+
```
|
|
810
|
+
|
|
811
|
+
### API Routes
|
|
812
|
+
|
|
813
|
+
All routes are under `/api/sdk/` and require API key authentication.
|
|
814
|
+
|
|
815
|
+
| Prefix | Description |
|
|
816
|
+
|---|---|
|
|
817
|
+
| `/api/sdk/auth` | Login, token exchange, key rotation |
|
|
818
|
+
| `/api/sdk/wallets` | Wallet CRUD, cards, profiles, merchant accounts |
|
|
819
|
+
| `/api/sdk/pay` | Token creation, payment execution, refunds |
|
|
820
|
+
| `/api/sdk/admin` | Spending reports, budgets, team members |
|
|
821
|
+
| `/api/sdk/merchants` | Merchant directory (list, get, capabilities, sync, discover) |
|
|
822
|
+
|
|
823
|
+
### Middleware Stack
|
|
824
|
+
|
|
825
|
+
```
|
|
826
|
+
Request → JSON Parser → CORS → API Key Auth → Rate Limit → HMAC Verify → Audit → Route → Error Handler
|
|
827
|
+
```
|
|
828
|
+
|
|
829
|
+
### Services (9)
|
|
830
|
+
|
|
831
|
+
| Service | Description |
|
|
832
|
+
|---|---|
|
|
833
|
+
| `WalletService` | Wallet lifecycle, balance tracking |
|
|
834
|
+
| `CardService` | Card management, VGS tokenization |
|
|
835
|
+
| `TokenService` | Agentic token lifecycle (create, validate, consume, expire) |
|
|
836
|
+
| `PaymentService` | Payment execution, PSP routing, refunds |
|
|
837
|
+
| `BudgetService` | Budget enforcement, spending counters, period resets |
|
|
838
|
+
| `ProfileService` | Checkout profiles (address, email, phone) |
|
|
839
|
+
| `MerchantAccountService` | Saved merchant credentials per wallet |
|
|
840
|
+
| `MerchantDirectoryService` | Merchant registry, backend sync, protocol discovery |
|
|
841
|
+
| `VGSProxyService` | VGS outbound proxy for PCI-compliant card operations |
|
|
842
|
+
|
|
843
|
+
### Database
|
|
844
|
+
|
|
845
|
+
11 SQL migrations using Supabase (PostgreSQL) with Row Level Security on all tables:
|
|
846
|
+
|
|
847
|
+
```
|
|
848
|
+
001_developers.sql — Developer accounts
|
|
849
|
+
002_api_keys.sql — API key management
|
|
850
|
+
003_vgs_vault_configs.sql — VGS vault configurations
|
|
851
|
+
004_wallets_cards.sql — Wallets and payment cards
|
|
852
|
+
005_checkout_profiles.sql — Saved checkout information
|
|
853
|
+
006_merchant_accounts.sql — Per-merchant credentials
|
|
854
|
+
007_agentic_tokens.sql — Scoped payment tokens
|
|
855
|
+
008_transactions.sql — Transaction ledger
|
|
856
|
+
009_budgets.sql — Spending limits and counters
|
|
857
|
+
010_audit_log.sql — Immutable audit trail
|
|
858
|
+
011_merchant_directory.sql — Merchant directory, sync log, protocol manifests
|
|
859
|
+
```
|
|
860
|
+
|
|
861
|
+
## Architecture
|
|
862
|
+
|
|
863
|
+
### System Overview
|
|
864
|
+
|
|
865
|
+
```
|
|
866
|
+
┌─────────────────────────────────────────────────────────────────────────┐
|
|
867
|
+
│ AI Agent Layer │
|
|
868
|
+
│ Claude · Cursor · Custom Agents │
|
|
869
|
+
├──────────────────┬────────────────────────┬──────────────────────────────┤
|
|
870
|
+
│ MCP Server │ SDK Client Library │ CLI │
|
|
871
|
+
│ (stdio/HTTP) │ (TypeScript/JS) │ (16 commands) │
|
|
872
|
+
│ │ │ │
|
|
873
|
+
│ 14 tools │ 17 resource classes │ login · pay · balance │
|
|
874
|
+
│ Zod validation │ Lazy initialization │ checkout · set-budget │
|
|
875
|
+
│ JSON responses │ Type-safe methods │ setup-mcp · vendor │
|
|
876
|
+
├──────────────────┴────────────────────────┴──────────────────────────────┤
|
|
877
|
+
│ HTTP Client (src/client.ts) │
|
|
878
|
+
│ │
|
|
879
|
+
│ HMAC-SHA256 signing Exponential backoff Circuit breaker │
|
|
880
|
+
│ Idempotency keys Retry on 5xx/429 (3 failures → 30s open) │
|
|
881
|
+
│ Request ID tracking Rate limit awareness Event emitter │
|
|
882
|
+
├──────────────────────────────────────────────────────────────────────────┤
|
|
883
|
+
│ │
|
|
884
|
+
│ Express Server (port 3001) │
|
|
885
|
+
│ │
|
|
886
|
+
│ ┌────────┐ ┌───────────┐ ┌────────────┐ ┌─────────┐ ┌───────────┐ │
|
|
887
|
+
│ │JSON │─▶│ API Key │─▶│ Rate Limit │─▶│ HMAC │─▶│ Audit │ │
|
|
888
|
+
│ │Parser │ │ Auth │ │ │ │ Verify │ │ Logger │ │
|
|
889
|
+
│ └────────┘ └───────────┘ └────────────┘ └─────────┘ └─────┬─────┘ │
|
|
890
|
+
│ │ │
|
|
891
|
+
│ ┌───────────────────────────────────────────────────────────────┘ │
|
|
892
|
+
│ │ │
|
|
893
|
+
│ ▼ Routes │
|
|
894
|
+
│ ┌──────────┬──────────┬──────────┬──────────┬────────────────┐ │
|
|
895
|
+
│ │ /auth │ /wallets │ /pay │ /admin │ /merchants │ │
|
|
896
|
+
│ │ │ │ │ │ │ │
|
|
897
|
+
│ │ login │ create │ tokens │ budgets │ list/search │ │
|
|
898
|
+
│ │ exchange │ cards │ execute │ spending │ get by id/slug │ │
|
|
899
|
+
│ │ rotate │ profiles │ refunds │ members │ capabilities │ │
|
|
900
|
+
│ │ │ accounts │ │ export │ sync/discover │ │
|
|
901
|
+
│ └────┬─────┴────┬─────┴────┬─────┴────┬─────┴───────┬────────┘ │
|
|
902
|
+
│ │ │ │ │ │ │
|
|
903
|
+
│ ─────┴──────────┴──────────┴──────────┴─────────────┴─────────────── │
|
|
904
|
+
│ Service Container (DI) │
|
|
905
|
+
│ │
|
|
906
|
+
│ ┌──────────┬──────────┬──────────┬──────────┬──────────┬──────────────┐ │
|
|
907
|
+
│ │ Wallet │ Card │ Token │ Payment │ Budget │ Merchant │ │
|
|
908
|
+
│ │ Service │ Service │ Service │ Service │ Service │ Directory │ │
|
|
909
|
+
│ ├──────────┼──────────┼──────────┼──────────┼──────────┤ Service │ │
|
|
910
|
+
│ │ Profile │ Merchant │ VGS │ │ │ │ │
|
|
911
|
+
│ │ Service │ Account │ Proxy │ │ │ 30m cache │ │
|
|
912
|
+
│ │ │ Service │ Service │ │ │ auto-sync │ │
|
|
913
|
+
│ └──────────┴──────────┴──────────┴──────────┴──────────┴──────────────┘ │
|
|
914
|
+
│ │
|
|
915
|
+
├──────────────────────────────────────────────────────────────────────────┤
|
|
916
|
+
│ Payment Infrastructure │
|
|
917
|
+
│ │
|
|
918
|
+
│ ┌──────────────────┐ ┌──────────────────┐ ┌────────────────────────┐ │
|
|
919
|
+
│ │ Routing Engine │ │ VGS Integration │ │ PSP Registry │ │
|
|
920
|
+
│ │ │ │ │ │ │ │
|
|
921
|
+
│ │ MerchantRegistry │ │ Outbound Proxy │ │ ┌──────────────────┐ │ │
|
|
922
|
+
│ │ PaymentRouter │ │ Token Manager │ │ │ Stripe (pri: 1) │ │ │
|
|
923
|
+
│ │ │ │ Card Detection │ │ │ Worldpay (pri: 2)│ │ │
|
|
924
|
+
│ │ 4-tier routing: │ │ Luhn Validation │ │ │ CyberSource (3) │ │ │
|
|
925
|
+
│ │ billing_api │ │ Collect Forms │ │ └──────────────────┘ │ │
|
|
926
|
+
│ │ acp │ │ │ │ │ │
|
|
927
|
+
│ │ vic │ │ PCI DSS Level 1 │ │ Priority failover │ │
|
|
928
|
+
│ │ fallback │ │ PAN never │ │ Health checks │ │
|
|
929
|
+
│ │ │ │ touches Lane │ │ │ │
|
|
930
|
+
│ └──────────────────┘ └──────────────────┘ └────────────────────────┘ │
|
|
931
|
+
│ │
|
|
932
|
+
├──────────────────────────────────────────────────────────────────────────┤
|
|
933
|
+
│ Supabase (PostgreSQL + Row Level Security) │
|
|
934
|
+
│ │
|
|
935
|
+
│ developers · api_keys · wallets · cards · tokens · transactions │
|
|
936
|
+
│ budgets · profiles · merchant_accounts · audit_log │
|
|
937
|
+
│ merchant_directory · sync_log · protocol_manifests │
|
|
938
|
+
│ │
|
|
939
|
+
│ 11 migrations · GIN indexes · trigram search · RLS on all tables │
|
|
940
|
+
└──────────────────────────────────────────────────────────────────────────┘
|
|
941
|
+
```
|
|
942
|
+
|
|
943
|
+
### Request Lifecycle
|
|
944
|
+
|
|
945
|
+
```
|
|
946
|
+
Client Lane Server External
|
|
947
|
+
│ │ │
|
|
948
|
+
│ POST /api/sdk/pay │ │
|
|
949
|
+
│ Authorization: Bearer │ │
|
|
950
|
+
│ X-Lane-Signature: sha256 │ │
|
|
951
|
+
│ X-Lane-Timestamp: ... │ │
|
|
952
|
+
│ Idempotency-Key: ... │ │
|
|
953
|
+
│ ─────────────────────────▶│ │
|
|
954
|
+
│ │ │
|
|
955
|
+
│ ┌─────┴─────┐ │
|
|
956
|
+
│ │ API Key │ Verify key in DB │
|
|
957
|
+
│ │ Auth │ │
|
|
958
|
+
│ └─────┬─────┘ │
|
|
959
|
+
│ ┌─────┴─────┐ │
|
|
960
|
+
│ │ Rate │ Check rate limit │
|
|
961
|
+
│ │ Limit │ │
|
|
962
|
+
│ └─────┬─────┘ │
|
|
963
|
+
│ ┌─────┴─────┐ │
|
|
964
|
+
│ │ HMAC │ Verify request signature │
|
|
965
|
+
│ │ Verify │ │
|
|
966
|
+
│ └─────┬─────┘ │
|
|
967
|
+
│ ┌─────┴─────┐ │
|
|
968
|
+
│ │ Audit │ Log request │
|
|
969
|
+
│ │ Logger │ │
|
|
970
|
+
│ └─────┬─────┘ │
|
|
971
|
+
│ │ │
|
|
972
|
+
│ ┌─────┴─────┐ │
|
|
973
|
+
│ │ Budget │ Check daily/weekly/monthly │
|
|
974
|
+
│ │ Service │ limits, merchant allow/deny │
|
|
975
|
+
│ └─────┬─────┘ │
|
|
976
|
+
│ ┌─────┴─────┐ │
|
|
977
|
+
│ │ Payment │ │
|
|
978
|
+
│ │ Router │ Select: billing_api │
|
|
979
|
+
│ └─────┬─────┘ │
|
|
980
|
+
│ ┌─────┴─────┐ │
|
|
981
|
+
│ │ VGS │ Detokenize card ───────────▶│ VGS Vault
|
|
982
|
+
│ │ Proxy │◀──────────── real PAN ──────│
|
|
983
|
+
│ └─────┬─────┘ │
|
|
984
|
+
│ ┌─────┴─────┐ │
|
|
985
|
+
│ │ PSP │ Charge via Worldpay ──────▶│ Worldpay
|
|
986
|
+
│ │ Adapter │◀──────── auth code ────────│
|
|
987
|
+
│ └─────┬─────┘ │
|
|
988
|
+
│ ┌─────┴─────┐ │
|
|
989
|
+
│ │ Record │ Update spend counters │
|
|
990
|
+
│ │ Spend │ Write transaction row │
|
|
991
|
+
│ └─────┬─────┘ │
|
|
992
|
+
│ │ │
|
|
993
|
+
│ 200 OK │ │
|
|
994
|
+
│ { transactionId, │ │
|
|
995
|
+
│ status: "success", │ │
|
|
996
|
+
│ receiptUrl } │ │
|
|
997
|
+
│ ◀─────────────────────────│ │
|
|
998
|
+
│ │ │
|
|
999
|
+
```
|
|
1000
|
+
|
|
1001
|
+
### PSP Adapters
|
|
1002
|
+
|
|
1003
|
+
Three payment processor adapters with priority-based failover:
|
|
1004
|
+
|
|
1005
|
+
```ts
|
|
1006
|
+
import { PSPRegistry, StripeAdapter, WorldpayAdapter, CyberSourceAdapter } from 'lane'
|
|
1007
|
+
|
|
1008
|
+
const registry = new PSPRegistry()
|
|
1009
|
+
registry.register(new StripeAdapter(config), 1) // Primary
|
|
1010
|
+
registry.register(new WorldpayAdapter(config), 2) // Secondary
|
|
1011
|
+
registry.register(new CyberSourceAdapter(config), 3) // Tertiary
|
|
1012
|
+
|
|
1013
|
+
const primary = registry.getPrimary()
|
|
1014
|
+
const result = await primary.charge({
|
|
1015
|
+
amount: 4999,
|
|
1016
|
+
currency: 'USD',
|
|
1017
|
+
token: 'vgs_tok_...',
|
|
1018
|
+
cardholderName: 'AI Agent',
|
|
1019
|
+
})
|
|
1020
|
+
```
|
|
1021
|
+
|
|
1022
|
+
## Development
|
|
1023
|
+
|
|
1024
|
+
```bash
|
|
1025
|
+
# Install dependencies
|
|
1026
|
+
npm install
|
|
1027
|
+
|
|
1028
|
+
# Build (ESM + CJS + CLI + DTS)
|
|
1029
|
+
npm run build
|
|
1030
|
+
|
|
1031
|
+
# Type check
|
|
1032
|
+
npx tsc --noEmit
|
|
1033
|
+
|
|
1034
|
+
# Run tests (110 tests via Vitest)
|
|
1035
|
+
npm test
|
|
1036
|
+
|
|
1037
|
+
# Watch mode
|
|
1038
|
+
npm run dev # Build
|
|
1039
|
+
npm run test:watch # Tests
|
|
1040
|
+
```
|
|
1041
|
+
|
|
1042
|
+
### Test Coverage
|
|
1043
|
+
|
|
1044
|
+
| Suite | Tests | Covers |
|
|
1045
|
+
|---|---|---|
|
|
1046
|
+
| `config.test.ts` | 13 | Config resolution (constructor, env, file) |
|
|
1047
|
+
| `errors.test.ts` | 18 | Error hierarchy, factory, serialization |
|
|
1048
|
+
| `lane.test.ts` | 6 | Lane class initialization, resource accessors |
|
|
1049
|
+
| `lane.phase.test.ts` | 7 | Phase-specific resource availability |
|
|
1050
|
+
| `signature.test.ts` | 11 | HMAC signing, webhook verification |
|
|
1051
|
+
| `token-store.test.ts` | 8 | File credential storage, permissions |
|
|
1052
|
+
| `card-types.test.ts` | 13 | Card brand detection, Luhn check, masking |
|
|
1053
|
+
| `collect.test.ts` | 10 | VGS Collect form generation |
|
|
1054
|
+
| `token.test.ts` | 4 | VGS token management |
|
|
1055
|
+
| `engine.test.ts` | 9 | Payment routing decisions, budget enforcement |
|
|
1056
|
+
| `tool.test.ts` | 4 | MCP tool execution, error formatting |
|
|
1057
|
+
| `registry.test.ts` | 7 | PSP adapter registration, failover |
|
|
1058
|
+
|
|
1059
|
+
## License
|
|
1060
|
+
|
|
1061
|
+
MIT
|