lane-sdk 0.1.11 → 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.
Files changed (56) hide show
  1. package/README.md +839 -835
  2. package/SKILL.md +9 -3
  3. package/dist/adapters/crewai/index.cjs +52 -30
  4. package/dist/adapters/crewai/index.cjs.map +1 -1
  5. package/dist/adapters/crewai/index.d.cts +1 -1
  6. package/dist/adapters/crewai/index.d.ts +1 -1
  7. package/dist/adapters/crewai/index.js +52 -30
  8. package/dist/adapters/crewai/index.js.map +1 -1
  9. package/dist/adapters/langchain/index.cjs +52 -30
  10. package/dist/adapters/langchain/index.cjs.map +1 -1
  11. package/dist/adapters/langchain/index.d.cts +1 -1
  12. package/dist/adapters/langchain/index.d.ts +1 -1
  13. package/dist/adapters/langchain/index.js +52 -30
  14. package/dist/adapters/langchain/index.js.map +1 -1
  15. package/dist/adapters/openai/index.cjs +52 -30
  16. package/dist/adapters/openai/index.cjs.map +1 -1
  17. package/dist/adapters/openai/index.d.cts +1 -1
  18. package/dist/adapters/openai/index.d.ts +1 -1
  19. package/dist/adapters/openai/index.js +52 -30
  20. package/dist/adapters/openai/index.js.map +1 -1
  21. package/dist/adapters/vercel-ai/index.cjs +52 -30
  22. package/dist/adapters/vercel-ai/index.cjs.map +1 -1
  23. package/dist/adapters/vercel-ai/index.d.cts +1 -1
  24. package/dist/adapters/vercel-ai/index.d.ts +1 -1
  25. package/dist/adapters/vercel-ai/index.js +52 -30
  26. package/dist/adapters/vercel-ai/index.js.map +1 -1
  27. package/dist/cli/index.js +23737 -2480
  28. package/dist/cli/index.js.map +1 -1
  29. package/dist/cli/postinstall.js +2897 -20
  30. package/dist/cli/postinstall.js.map +1 -1
  31. package/dist/index.cjs +52 -30
  32. package/dist/index.cjs.map +1 -1
  33. package/dist/index.d.cts +2 -2
  34. package/dist/index.d.ts +2 -2
  35. package/dist/index.js +52 -30
  36. package/dist/index.js.map +1 -1
  37. package/dist/{lane-mwQvHTgq.d.cts → lane-C09tKwCV.d.cts} +14 -4
  38. package/dist/{lane-mwQvHTgq.d.ts → lane-C09tKwCV.d.ts} +14 -4
  39. package/dist/server/index.js +495 -165
  40. package/dist/server/index.js.map +1 -1
  41. package/dist/server/routes/export.cjs +249 -113
  42. package/dist/server/routes/export.cjs.map +1 -1
  43. package/dist/server/routes/export.js +244 -108
  44. package/dist/server/routes/export.js.map +1 -1
  45. package/dist/server-http.cjs +52 -30
  46. package/dist/server-http.cjs.map +1 -1
  47. package/dist/server-http.js +52 -30
  48. package/dist/server-http.js.map +1 -1
  49. package/dist/server-stdio.cjs +52 -30
  50. package/dist/server-stdio.cjs.map +1 -1
  51. package/dist/server-stdio.js +52 -30
  52. package/dist/server-stdio.js.map +1 -1
  53. package/package.json +17 -6
  54. package/dist/server/index.cjs +0 -8188
  55. package/dist/server/index.cjs.map +0 -1
  56. package/server/routes/export.d.ts +0 -9
package/README.md CHANGED
@@ -2,295 +2,143 @@
2
2
 
3
3
  > `npm install lane-sdk` — Add wallets and payments to your AI agents.
4
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.
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, 28 MCP tools, and a CLI.
6
+
7
+ **Stack:** TypeScript · Express · Supabase (PostgreSQL + RLS) · VGS · Visa Intelligent Commerce
8
+
9
+ ```
10
+ Production: https://api.getonlane.com/sdk
11
+ Wallet app: https://agent.getonlane.com
12
+ Auth service: https://auth.getonlane.com
13
+ ```
6
14
 
7
15
  ```ts
8
16
  import Lane from 'lane-sdk'
9
17
 
10
- const lane = Lane.fromApiKey(process.env.LANE_KEY!)
18
+ const lane = await Lane.create()
11
19
 
12
20
  // Discover merchants
13
21
  const { data: merchants } = await lane.merchants.list({ query: 'sneakers' })
14
- const merchant = merchants[0]
15
22
 
16
23
  // Search products
17
24
  const { data: products } = await lane.products.search({ query: 'jordan 4' })
18
25
 
19
26
  // Execute payment
20
27
  const txn = await lane.pay.execute({
21
- recipient: merchant.domain,
28
+ recipient: merchants[0].domain,
22
29
  amount: 19999, // cents
23
30
  currency: 'USD',
24
31
  description: 'Jordan 4 Retro',
25
32
  })
26
-
27
- console.log(txn.status) // 'success'
28
- console.log(txn.receiptUrl) // 'https://...'
29
33
  ```
30
34
 
35
+ ---
36
+
31
37
  ## Table of Contents
32
38
 
33
- - [How It Works](#how-it-works)
39
+ - [Architecture Overview](#architecture-overview)
40
+ - [Three Ways to Integrate](#three-ways-to-integrate)
34
41
  - [Quick Start](#quick-start)
35
- - [Authentication](#authentication)
42
+ - [Authentication Flows](#authentication-flows)
43
+ - [CLI Login (Device-Code Flow)](#cli-login-device-code-flow)
44
+ - [SDK Access Verification](#sdk-access-verification)
45
+ - [Config Resolution](#config-resolution)
46
+ - [Payment Routing](#payment-routing)
47
+ - [Merchant Discovery](#merchant-discovery)
48
+ - [API Reference](#api-reference)
36
49
  - [SDK Resources](#sdk-resources)
37
50
  - [MCP Integration](#mcp-integration)
38
51
  - [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)
52
+ - [Database Schema](#database-schema)
53
+ - [Token Architecture](#token-architecture)
54
+ - [Security & Compliance](#security--compliance)
55
+ - [Middleware & Route Protection](#middleware--route-protection)
56
+ - [Cross-Service Auth: SDK vs Lane-Auth](#cross-service-auth-sdk-vs-lane-auth)
57
+ - [Project Structure](#project-structure)
58
+ - [Environment Variables](#environment-variables)
45
59
  - [Development](#development)
46
60
 
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
- └───────────────────┘ └───────────────────┘ └────────────────────────────┘
61
+ ---
62
+
63
+ ## Architecture Overview
64
+
65
+ ```mermaid
66
+ graph TB
67
+ subgraph Clients
68
+ AGENT["AI Agent<br/>(Claude, Cursor, Custom)"]
69
+ MCP_CLIENT["MCP Client"]
70
+ APP["Application Code"]
71
+ end
72
+
73
+ subgraph "Lane SDK (TypeScript)"
74
+ SDK_LIB["SDK Library<br/>Lane.create() · 22 resources"]
75
+ MCP_SERVER["MCP Server<br/>28 tools · stdio/HTTP"]
76
+ CLI["CLI<br/>npx lane · 26 commands"]
77
+ end
78
+
79
+ subgraph "HTTP Client"
80
+ CLIENT["LaneClient<br/>HMAC-SHA256 · Retries<br/>Circuit Breaker · Idempotency"]
81
+ end
82
+
83
+ subgraph "Lane Server (Express)"
84
+ MW["Middleware<br/>API Key Auth → Rate Limit<br/>→ HMAC Verify → Audit"]
85
+ ROUTES["Routes<br/>/agent/auth · /agent/admin<br/>/agent/wallet · /agent/pay<br/>/agent/merchant · ..."]
86
+ SERVICES["Services (23)<br/>Payment · Wallet · Budget<br/>Merchant · VIC · Mandate · ..."]
87
+ end
88
+
89
+ subgraph Infrastructure
90
+ VGS["VGS Vault<br/>PCI DSS Level 1"]
91
+ PSP["PSP Registry<br/>Stripe · Worldpay<br/>CyberSource"]
92
+ end
93
+
94
+ subgraph "Supabase"
95
+ DB["PostgreSQL + RLS<br/>32 migrations"]
96
+ end
97
+
98
+ AGENT --> MCP_CLIENT --> MCP_SERVER
99
+ APP --> SDK_LIB
100
+ AGENT --> CLI
101
+
102
+ MCP_SERVER --> CLIENT
103
+ SDK_LIB --> CLIENT
104
+ CLI --> CLIENT
105
+
106
+ CLIENT --> MW --> ROUTES --> SERVICES
107
+ SERVICES --> DB
108
+ SERVICES --> VGS --> PSP
84
109
  ```
85
110
 
86
- ### Three Ways to Integrate
111
+ ---
87
112
 
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
- ```
113
+ ## Three Ways to Integrate
120
114
 
121
- ### Payment Routing Decision Tree
115
+ ```mermaid
116
+ graph LR
117
+ subgraph "MCP Server"
118
+ MCP["28 tools<br/>Zod validation<br/>JSON responses<br/><br/>stdio or HTTP transport"]
119
+ end
122
120
 
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
- ```
121
+ subgraph "SDK (TypeScript)"
122
+ SDK["22 resource classes<br/>Lazy initialization<br/>Type-safe methods<br/><br/>Lane.create()"]
123
+ end
170
124
 
171
- ### Merchant Discovery Flow
125
+ subgraph "CLI"
126
+ CLI_["26 commands<br/>Terse mode (-t)<br/>key=value output<br/><br/>npx lane &lt;cmd&gt;"]
127
+ end
172
128
 
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
- └──────────────────────────────────────────────────────────────────────┘
129
+ MCP --> HTTP["Lane HTTP Client<br/>HMAC · Retries · Circuit Breaker"]
130
+ SDK --> HTTP
131
+ CLI_ --> HTTP
132
+ HTTP --> API["Lane API Server"]
213
133
  ```
214
134
 
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
- ```
135
+ | | MCP Server | SDK | CLI |
136
+ |---|---|---|---|
137
+ | **Use case** | AI agents that speak MCP | Application code | Developers, scripts, agents via SKILL.md |
138
+ | **Auth** | `LANE_API_KEY` env or `lane_connect` tool | `Lane.create()` or `Lane.fromApiKey()` | `npx lane login` → `~/.lane/credentials.json` |
139
+ | **Output** | JSON tool responses | TypeScript objects | `key=value` pairs (terse mode) |
258
140
 
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
- ```
141
+ ---
294
142
 
295
143
  ## Quick Start
296
144
 
@@ -304,8 +152,8 @@ npx lane login
304
152
  # Verify
305
153
  npx lane whoami
306
154
 
307
- # Check balance
308
- npx lane balance
155
+ # Search merchants
156
+ npx lane merchant list
309
157
 
310
158
  # Make a payment
311
159
  npx lane pay --recipient replicate.com --amount 20.00
@@ -320,704 +168,861 @@ import Lane from 'lane-sdk'
320
168
  const lane = await Lane.create()
321
169
 
322
170
  // Option 2: Explicit API key
323
- const lane = Lane.fromApiKey('lane_sk_...')
171
+ const lane = await Lane.fromApiKey('lane_sk_...')
324
172
 
325
- // Option 3: Test mode
326
- const lane = Lane.fromApiKey('lane_sk_test_...', { testMode: true })
173
+ // Option 3: Test mode (auto-detected from key prefix)
174
+ const lane = await Lane.fromApiKey('lane_sk_test_...')
327
175
  ```
328
176
 
329
- ## Authentication
177
+ ---
178
+
179
+ ## Authentication Flows
180
+
181
+ ### CLI Login (Device-Code Flow)
182
+
183
+ The primary flow for authenticating via `npx lane login -t`. The SDK server orchestrates the flow; lane-auth is used only as an OTP popup.
184
+
185
+ ```mermaid
186
+ sequenceDiagram
187
+ box rgb(230,240,255) lane-agent-sdk
188
+ actor Dev as Developer
189
+ participant CLI as Lane CLI
190
+ participant SDK as SDK Server<br/>/agent/auth/*
191
+ participant Wallet as Wallet App<br/>/authorize
192
+ end
193
+ box rgb(255,235,235) lane-auth
194
+ participant Auth as Auth Service<br/>auth.getonlane.com
195
+ end
196
+ participant DB as Supabase
197
+
198
+ Note over CLI,SDK: Phase 1 — Initiate
199
+ CLI->>SDK: POST /agent/auth/login
200
+ SDK->>DB: INSERT auth_sessions (pending, 10min TTL)
201
+ SDK-->>CLI: { sessionId, authUrl, deviceCode: "LANE-A3B7" }
202
+ CLI-->>Dev: "auth_url=... device_code=LANE-A3B7"
203
+
204
+ Note over Wallet,Auth: Phase 2 — Browser Auth
205
+ Dev->>Wallet: Open /authorize?s={sessionId}&redirect_port={port}
206
+ Wallet->>SDK: GET /agent/auth/device-status?s={sessionId}
207
+ SDK-->>Wallet: { deviceCode: "LANE-A3B7" }
208
+ Dev->>Wallet: "Codes match — continue"
209
+
210
+ rect rgb(255,235,235)
211
+ Note over Wallet,Auth: OTP login via lane-auth popup
212
+ Wallet->>Auth: window.open("/login?embed=true")
213
+ Auth-->>Dev: OTP email
214
+ Dev->>Auth: Enter 6-digit code
215
+ Auth-->>Wallet: postMessage("lane:auth:complete")
216
+ end
217
+
218
+ Note over Wallet,SDK: Phase 3 — Complete Session
219
+ Wallet->>SDK: POST /agent/auth/complete-session<br/>{ sessionId, userId, email }
220
+ SDK->>DB: UPSERT developers (sdk_access: true)
221
+ SDK->>DB: INSERT api_keys (lane_sk_ key)
222
+ SDK->>DB: UPDATE auth_sessions → completed
223
+ SDK-->>Wallet: { code }
224
+ Wallet-->>CLI: http://127.0.0.1:{port}/callback?code=...
225
+
226
+ Note over CLI,SDK: Phase 4 — Token Exchange
227
+ CLI->>SDK: POST /agent/auth/token { code, sessionId }
228
+ SDK->>DB: Verify + UPDATE auth_sessions → consumed
229
+ SDK-->>CLI: { apiKey: "lane_sk_...", developerId }
230
+ CLI->>CLI: Write ~/.lane/credentials.json
231
+ CLI-->>Dev: "ready=true email=..."
232
+ ```
233
+
234
+ ### SDK Access Verification
235
+
236
+ Every `Lane.create()` call verifies the developer's SDK access before returning an instance.
237
+
238
+ ```mermaid
239
+ sequenceDiagram
240
+ participant App as Application Code
241
+ participant SDK as Lane.create()
242
+ participant Server as SDK Server
243
+ participant DB as Supabase
244
+
245
+ App->>SDK: Lane.create()
246
+ SDK->>SDK: resolveConfig()<br/>API key from: args → env → credentials file
247
+
248
+ SDK->>Server: POST /agent/auth/verify-sdk-access<br/>Authorization: Bearer lane_sk_...
249
+ Server->>DB: SHA-256(key) → api_keys JOIN developers
250
+
251
+ alt sdk_access = true
252
+ Server-->>SDK: 200 { access: true }
253
+ SDK-->>App: Lane instance ready
254
+ else sdk_access = false
255
+ Server-->>SDK: 403 { code: "waitlist" }
256
+ SDK-->>App: throw Error("Coming Soon")
257
+ else Network error / timeout
258
+ Note over SDK: Fail open (offline dev)
259
+ SDK-->>App: Lane instance ready
260
+ end
261
+ ```
330
262
 
331
- Config resolution order (first match wins):
263
+ ### Config Resolution
332
264
 
333
- 1. **Constructor:** `Lane.fromApiKey('lane_sk_...')` or `Lane.create({ apiKey: '...' })`
265
+ API key resolution order (first match wins):
266
+
267
+ 1. **Constructor argument:** `Lane.create({ apiKey: '...' })` or `Lane.fromApiKey('...')`
334
268
  2. **Environment variable:** `LANE_API_KEY`
335
269
  3. **Credentials file:** `~/.lane/credentials.json` (written by `npx lane login`)
336
270
 
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' }
271
+ Config is frozen after resolution — no mutation allowed.
341
272
 
342
- // Rotate API key (old key valid for 15 min)
343
- const { apiKey, expiresOldKeyAt } = await lane.auth.rotateKey()
344
- ```
273
+ ---
345
274
 
346
- ## SDK Resources
275
+ ## Payment Routing
347
276
 
348
- The SDK exposes 17 resource classes, all lazily initialized on first access.
277
+ Lane's routing engine selects the optimal payment path using a 5-tier priority system:
349
278
 
350
- ### Core Resources
279
+ ```mermaid
280
+ flowchart TD
281
+ START([Payment Request]) --> BUDGET{Budget check<br/>within limits?}
351
282
 
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()` |
283
+ BUDGET -->|No| DENIED([DENIED<br/>budget_exceeded])
284
+ BUDGET -->|Yes| LOOKUP[Lookup merchant<br/>in registry]
364
285
 
365
- ### Phase 2 VIC (Visa Intelligent Commerce)
286
+ LOOKUP --> T1{Has Billing API?}
287
+ T1 -->|Yes| TIER1([Tier 1: Billing API<br/>Direct integration — cheapest])
288
+ T1 -->|No| T2{Supports ACP?}
366
289
 
367
- | Resource | Description | Key Methods |
368
- |---|---|---|
369
- | `lane.vic` | Visa network tokens | `issue()`, `getCryptogram()`, `revoke()`, `suspend()` |
290
+ T2 -->|Yes| TIER2([Tier 2: ACP<br/>Agent Commerce Protocol])
291
+ T2 -->|No| T3{Supports UCP?}
370
292
 
371
- ### Phase 4 Make-a-SaaS
293
+ T3 -->|Yes| TIER3([Tier 3: UCP<br/>Universal Checkout Protocol])
294
+ T3 -->|No| T4{Has VIC token<br/>+ Visa card?}
372
295
 
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()` |
296
+ T4 -->|Yes| TIER4([Tier 4: x402<br/>Visa network token])
297
+ T4 -->|No| TIER5([Tier 5: Fallback<br/>Browser checkout / Rye])
377
298
 
378
- ### Phase 5 — Corporate Agent Spend
299
+ style DENIED fill:#fee,stroke:#c00
300
+ style TIER1 fill:#efe,stroke:#0a0
301
+ style TIER2 fill:#efe,stroke:#0a0
302
+ style TIER3 fill:#efe,stroke:#0a0
303
+ style TIER4 fill:#efe,stroke:#0a0
304
+ style TIER5 fill:#ffe,stroke:#aa0
305
+ ```
379
306
 
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()` |
307
+ ### Budget Enforcement (Hierarchical)
308
+
309
+ ```mermaid
310
+ flowchart TD
311
+ REQ([Payment $150]) --> ORG{Org budget<br/>$10,000/mo}
312
+ ORG -->|Pass| TEAM{Team budget<br/>$2,000/mo}
313
+ TEAM -->|Pass| DEV{Developer budget<br/>$500/day}
314
+ DEV -->|Pass| AGENT{Agent policy<br/>$200/txn}
315
+ AGENT -->|Pass| MERCHANT{Merchant<br/>allowlist check}
316
+ MERCHANT -->|Pass| MCC{MCC category<br/>check}
317
+ MCC -->|Pass| ROUTE([Route to payment<br/>effective limit = min of all])
318
+
319
+ ORG -->|Fail| DENY([DENIED])
320
+ TEAM -->|Fail| DENY
321
+ DEV -->|Fail| DENY
322
+ AGENT -->|Fail| DENY
323
+ MERCHANT -->|Fail| DENY
324
+ MCC -->|Fail| DENY
325
+ ```
385
326
 
386
- ### Phase 6 — Agent Identity
327
+ ---
387
328
 
388
- | Resource | Description | Key Methods |
389
- |---|---|---|
390
- | `lane.identity` | Agent KYC chain | `register()`, `verify()`, `getAttestation()`, `refreshAttestation()` |
329
+ ## Merchant Discovery
391
330
 
392
- ### Usage Examples
331
+ Two-tier merchant directory with in-memory cache (refreshed every 30 minutes):
393
332
 
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
- })
333
+ ```mermaid
334
+ graph TB
335
+ subgraph "Merchant Directory Service"
336
+ CACHE["In-Memory Cache<br/>(30-min refresh)"]
337
+ end
412
338
 
413
- // Refunds
414
- const refund = await lane.pay.refund({
415
- transactionId: txn.id,
416
- reason: 'Wrong size',
417
- })
339
+ subgraph "Tier 1: Lane-Onboarded"
340
+ T1["Synced from Lane backend<br/>Full checkout API<br/>Product catalog<br/>Payment routing"]
341
+ end
418
342
 
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
- })
343
+ subgraph "Tier 2: Protocol Discovery"
344
+ T2["Probe domain:<br/>GET /.well-known/ucp<br/>GET /.well-known/acp<br/><br/>Cached manifests"]
345
+ end
429
346
 
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
- })
347
+ CACHE --> T1
348
+ CACHE --> T2
437
349
 
438
- // Budgets
439
- await lane.admin.setBudget({
440
- dailyLimit: 10000, // $100.00
441
- perTaskLimit: 5000, // $50.00
442
- merchantAllowlist: ['legendarysneakers.com'],
443
- })
350
+ T1 --> DB[(merchant_directory<br/>PostgreSQL)]
351
+ T2 --> DB
352
+ ```
444
353
 
445
- // Subscriptions
446
- const sub = await lane.subscriptions.create({
447
- productId: 'prod_...',
448
- plan: 'pro',
449
- paymentSource: 'wallet',
450
- })
354
+ ### Taxonomy
451
355
 
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
- })
356
+ | Type | Verticals | Example Subcategories |
357
+ |---|---|---|
358
+ | `ecommerce` | fashion, electronics, beauty, home, food, sports | shoes, sneakers, laptops, skincare |
359
+ | `software` | developer_tools, productivity, ai_ml, security | hosting, databases, ci_cd, auth |
360
+ | `api` | data, communications, payments, infrastructure | enrichment, sms, processing, cdn |
361
+ | `saas` | business, marketing, finance | crm, analytics, accounting |
362
+ | `skill` | agent_tools | web_scraping, code_gen, research |
363
+ | `service` | travel, delivery, professional | flights, food, legal |
464
364
 
465
- // Webhooks
466
- await lane.webhooks.create({
467
- url: 'https://api.myapp.com/hooks/lane',
468
- events: ['transaction.completed', 'budget.exceeded'],
469
- })
470
- ```
365
+ ---
471
366
 
472
- ## MCP Integration
367
+ ## API Reference
473
368
 
474
- Lane ships with 14 MCP tools that any AI agent (Claude, Cursor, etc.) can use out of the box.
369
+ ### Public Endpoints (no auth required)
475
370
 
476
- ### Setup
371
+ | Endpoint | Method | Description |
372
+ |----------|--------|-------------|
373
+ | `/agent/auth/login` | POST | Initiate browser auth session |
374
+ | `/agent/auth/token` | POST | Exchange one-time code for API key |
375
+ | `/agent/auth/complete-session` | POST | Complete CLI auth (called by wallet) |
376
+ | `/agent/auth/device-status` | GET | Poll device code status |
377
+ | `/agent/auth/verify-sdk-access` | POST | Check SDK whitelist (Bearer token) |
378
+ | `/agent/discovery` | GET | Agent discovery metadata |
379
+ | `/health` | GET | Health check |
477
380
 
478
- ```bash
479
- # Auto-configure for Claude Desktop / Cursor
480
- npx lane setup-mcp
481
- ```
381
+ ### Protected Endpoints (API key required)
382
+
383
+ | Prefix | Description |
384
+ |--------|-------------|
385
+ | `/agent/admin` | `whoami`, `rotate-key`, `keys` list |
386
+ | `/agent/wallet` | Wallet CRUD, balance, deposit |
387
+ | `/agent/card` | Card management, VGS collect links |
388
+ | `/agent/pay` | Token creation, payment execution, refunds |
389
+ | `/agent/instruction` | VIC instruction lifecycle, credentials, confirmations |
390
+ | `/agent/token` | Agentic token provisioning |
391
+ | `/agent/transaction` | Transaction history, refunds |
392
+ | `/agent/budget` | Budget get/set |
393
+ | `/agent/merchant` | Merchant list, search, discover, verticals |
394
+ | `/agent/product` | Product search, get |
395
+ | `/agent/checkout` | Checkout sessions |
396
+ | `/agent/subscription` | Subscription management |
397
+ | `/agent/fleet` | Agent fleet management |
398
+ | `/agent/team` | Team management |
399
+ | `/agent/webhook` | Webhook CRUD |
400
+ | `/agent/audit` | Audit trail queries |
401
+ | `/agent/onboarding` | Onboarding key generation |
402
+
403
+ ### Legacy Endpoints (deprecated)
482
404
 
483
- Or add to your `claude_desktop_config.json`:
405
+ | Prefix | Description |
406
+ |--------|-------------|
407
+ | `/api/sdk/auth` | Login, token exchange, key rotation |
408
+ | `/api/sdk/wallets` | Wallet operations |
409
+ | `/api/sdk/pay` | Payment operations |
410
+ | `/api/sdk/admin` | Admin operations |
411
+ | `/api/sdk/merchants` | Merchant directory |
484
412
 
413
+ All `/api/sdk/*` responses include `Deprecation` and `Sunset` headers. Migrate to `/agent/*`.
414
+
415
+ <details>
416
+ <summary><strong>POST /agent/auth/login</strong></summary>
417
+
418
+ **Response:**
485
419
  ```json
486
420
  {
487
- "mcpServers": {
488
- "lane": {
489
- "command": "npx",
490
- "args": ["lane-mcp-server"],
491
- "env": {
492
- "LANE_API_KEY": "lane_sk_..."
493
- }
494
- }
495
- }
421
+ "sessionId": "550e8400-e29b-41d4-a716-446655440000",
422
+ "authUrl": "https://api.getonlane.com/authorize?s=550e8400...",
423
+ "deviceCode": "LANE-A3B7"
496
424
  }
497
425
  ```
426
+ </details>
498
427
 
499
- ### Programmatic MCP Server
500
-
501
- ```ts
502
- import { Lane, LaneMCPServer } from 'lane-sdk'
503
- import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
428
+ <details>
429
+ <summary><strong>GET /agent/admin/whoami</strong></summary>
504
430
 
505
- const lane = Lane.fromApiKey(process.env.LANE_API_KEY!)
506
- const server = new LaneMCPServer(lane)
431
+ **Header:** `Authorization: Bearer lane_sk_...`
507
432
 
508
- const transport = new StdioServerTransport()
509
- await server.mcp.connect(transport)
433
+ **Response:**
434
+ ```json
435
+ {
436
+ "data": {
437
+ "id": "uuid",
438
+ "email": "dev@example.com",
439
+ "plan": "free",
440
+ "memberSince": "2026-03-20T..."
441
+ }
442
+ }
510
443
  ```
444
+ </details>
511
445
 
512
- ### Available Tools (14)
446
+ ---
513
447
 
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?` |
448
+ ## SDK Resources
530
449
 
531
- ## CLI
450
+ The SDK exposes 22 resource classes, all lazily initialized on first access.
532
451
 
533
- ```
534
- lane <command>
452
+ ### Core Resources
535
453
 
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
454
+ | Resource | Description | Key Methods |
455
+ |---|---|---|
456
+ | `lane.auth` | Authentication & key management | `whoami()`, `login()`, `rotateKey()` |
457
+ | `lane.wallets` | Wallet lifecycle & cards | `create()`, `list()`, `balance()`, `deposit()`, `listCards()` |
458
+ | `lane.cards` | Card management | `list()`, `get()`, `remove()` |
459
+ | `lane.pay` | Payment execution | `createToken()`, `execute()`, `refund()` |
460
+ | `lane.products` | Product discovery | `search()`, `get()` |
461
+ | `lane.checkout` | Checkout sessions | `create()`, `complete()`, `get()`, `cancel()` |
462
+ | `lane.merchants` | Merchant directory | `list()`, `get()`, `discover()`, `verticals()` |
463
+ | `lane.admin` | Spending & budgets | `spending()`, `setBudget()`, `getBudget()`, `exportData()` |
464
+ | `lane.budget` | Budget management | `get()`, `set()` |
465
+ | `lane.transactions` | Transaction history | `list()`, `get()`, `refund()` |
466
+ | `lane.tokens` | Agentic token lifecycle | `provision()`, `list()`, `revoke()` |
467
+ | `lane.webhooks` | Webhook management | `create()`, `list()`, `verify()` |
468
+ | `lane.subscriptions` | Subscription management | `create()`, `cancel()`, `upgrade()`, `pause()` |
548
469
 
549
- Payments:
550
- lane pay Execute a payment
551
- lane checkout Purchase a product from catalog
552
- lane set-budget Set spending limits
470
+ ### Commerce Protocol Resources
553
471
 
554
- Seller:
555
- lane vendor Seller tools (list products, view analytics)
556
- lane schema Display API schema
472
+ | Resource | Description | Key Methods |
473
+ |---|---|---|
474
+ | `lane.instructions` | VIC instruction lifecycle | `create()`, `getCredential()`, `confirm()` |
475
+ | `lane.mandates` | Spending mandates | `create()`, `list()`, `evaluate()` |
476
+ | `lane.protocol` | Multi-protocol sessions | `createSession()`, `execute()` |
477
+ | `lane.vic` | Visa network tokens | `issue()`, `getCryptogram()`, `revoke()` |
478
+ | `lane.sell` | Seller tools | `create()`, `list()`, `analytics()` |
557
479
 
558
- Setup:
559
- lane setup-mcp Configure MCP server for Claude/Cursor
560
- lane wallet open Open Lane wallet in browser
561
- ```
480
+ ### Enterprise Resources
562
481
 
563
- ## Payment Routing
482
+ | Resource | Description | Key Methods |
483
+ |---|---|---|
484
+ | `lane.teams` | Team management | `create()`, `addMember()`, `setBudget()` |
485
+ | `lane.agents` | Agent fleet management | `register()`, `setPolicy()`, `suspend()` |
486
+ | `lane.fleet` | Fleet operations | `list()`, `getPolicy()` |
487
+ | `lane.audit` | SOC 2 audit trail | `query()`, `export()`, `summary()` |
488
+ | `lane.identity` | Agent KYC chain | `register()`, `verify()`, `getAttestation()` |
489
+ | `lane.delegations` | Agent-to-agent delegation | `create()`, `verify()`, `revoke()` |
490
+ | `lane.users` | User management | `list()`, `get()` |
491
+ | `lane.metering` | Usage tracking (sellers) | `record()`, `recordBatch()`, `report()` |
492
+ | `lane.payouts` | Seller disbursements | `getConfig()`, `setConfig()`, `list()` |
564
493
 
565
- Lane's routing engine selects the optimal payment path for each transaction using a 4-tier priority system:
494
+ ---
566
495
 
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
- ```
496
+ ## MCP Integration
573
497
 
574
- The router considers merchant capabilities, card brand, VIC token availability, and budget constraints:
498
+ Lane ships with 28 MCP tools. 4 work without authentication (discovery mode); 24 require a connected API key.
575
499
 
576
- ```ts
577
- import { PaymentRouter, MerchantRegistry } from 'lane-sdk'
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
- })
500
+ ### Setup
589
501
 
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'] }
502
+ ```bash
503
+ # Auto-configure for Claude Desktop / Cursor
504
+ npx lane setup-mcp
599
505
  ```
600
506
 
601
- The `MerchantRegistry` can be populated directly from the merchant directory:
507
+ Or add to `claude_desktop_config.json`:
602
508
 
603
- ```ts
604
- const capabilities = await container.merchantDirectory.populateRegistry()
605
- const registry = MerchantRegistry.fromDirectory(capabilities)
509
+ ```json
510
+ {
511
+ "mcpServers": {
512
+ "lane": {
513
+ "command": "npx",
514
+ "args": ["lane-mcp-server"],
515
+ "env": { "LANE_API_KEY": "lane_sk_..." }
516
+ }
517
+ }
518
+ }
606
519
  ```
607
520
 
608
- ## Merchant Directory
521
+ ### Pre-Auth Tools (Discovery Mode)
609
522
 
610
- The merchant directory is a live, queryable registry of AI-shoppable merchants. Two tiers:
523
+ | Tool | Description |
524
+ |---|---|
525
+ | `get_lane_info` | Platform overview and capabilities |
526
+ | `lane_signup` | Start signup flow |
527
+ | `lane_connect` | Connect API key to initialize SDK |
528
+ | `resolve_ucp_merchant` | Resolve UCP merchant by domain |
611
529
 
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
530
+ ### Post-Auth Tools (24)
614
531
 
615
- ### Taxonomy
532
+ | Tool | Description |
533
+ |---|---|
534
+ | `whoami` | Get developer profile |
535
+ | `check_balance` | Get wallet balance |
536
+ | `list_cards` | List cards in wallet |
537
+ | `pay` | Execute a payment |
538
+ | `list_transactions` | Transaction history |
539
+ | `search_products` | Search product catalog |
540
+ | `checkout` | Purchase a product |
541
+ | `set_budget` | Set spending limits |
542
+ | `request_refund` | Refund a transaction |
543
+ | `subscribe` | Create a subscription |
544
+ | `list_subscriptions` | List subscriptions |
545
+ | `cancel_subscription` | Cancel a subscription |
546
+ | `discover_merchants` | Search merchant directory |
547
+ | `search_software` | Search software products |
548
+ | `lane_add_card` | Add a payment card |
549
+ | `lane_onboarding_status` | Check onboarding progress |
550
+ | `protocol_pay` | Multi-protocol payment |
551
+ | `create_mandate` | Create spending mandate |
552
+ | `pay_with_mandate` | Pay using mandate authorization |
553
+ | `get_mandate_budget` | Check mandate budget |
554
+ | `get_instruction_budget` | Check instruction budget |
555
+ | `register_agent` | Register agent in fleet |
556
+ | `list_agents` | List fleet agents |
557
+ | `provision_vic_payment` | Provision VIC credentials |
558
+ | `confirm_instruction` | Biometric confirmation |
559
+
560
+ ---
616
561
 
617
- Merchants are classified hierarchically:
562
+ ## CLI
618
563
 
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 |
564
+ 26 commands plus 6 deprecated aliases.
627
565
 
628
- ### Vertical-Specific Product Attributes
566
+ ```
567
+ lane <command>
629
568
 
630
- Each merchant stores a `productAttributes` schema tailored to its vertical:
569
+ Authentication:
570
+ login Authenticate (opens browser)
571
+ logout Clear local credentials
572
+ whoami Developer profile
573
+ status Readiness check (wallet, card, budget)
631
574
 
632
- ```ts
633
- // Fashion/shoes merchant
634
- { available_sizes: ['7','8','9'], colors: ['black','white'], brands: ['Nike','Jordan'] }
575
+ Wallet & Cards:
576
+ wallet Wallet management (list, create, deposit, balance)
577
+ card Card management (list, add, remove, get)
635
578
 
636
- // Electronics merchant
637
- { specs: { ram_gb: 16, storage_gb: 512 }, brand: 'Apple', model_year: 2025 }
579
+ Payments:
580
+ pay Execute a payment
581
+ checkout Purchase from catalog
582
+ checkout-bridge Browser checkout with VIC credentials
583
+ budget Budget management (get, set)
584
+ token Token management (provision, list, revoke)
585
+ transaction Transaction history
586
+
587
+ Commerce:
588
+ merchant Merchant discovery (list, discover, verticals)
589
+ product Product search (search, get)
590
+ instruction VIC instruction lifecycle (create, credential, confirm)
591
+ session Shopping session management
592
+ batch Parallel merchant discovery
593
+
594
+ Enterprise:
595
+ fleet Agent fleet management
596
+ team Team management
597
+ user User management
598
+ webhook Webhook management
599
+ audit Audit trail queries
600
+ vendor Seller tools
638
601
 
639
- // Software merchant
640
- { runtime: 'node', sdk_package: '@acme/sdk', docs_url: '...' }
602
+ Setup:
603
+ setup-mcp Configure MCP for Claude/Cursor
604
+ install-skill Register Lane skill for auto-activation
605
+ schema Display API schema
641
606
  ```
642
607
 
643
- ### Usage
608
+ All commands support `-t` / `--terse` flag for machine-readable `key=value` output on stdout.
644
609
 
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')
610
+ ---
654
611
 
655
- // Lane-onboarded only
656
- const onboarded = await lane.merchants.listOnboarded()
612
+ ## Database Schema
657
613
 
658
- // List all verticals and subcategories
659
- const verticals = await lane.merchants.verticals()
614
+ 32 migrations on Supabase (PostgreSQL) with Row Level Security on all tables.
660
615
 
661
- // Discover a protocol-compatible merchant by domain
662
- const result = await lane.merchants.discover('shop.example.com')
663
- ```
616
+ ```mermaid
617
+ erDiagram
618
+ developers ||--o{ api_keys : "has"
619
+ developers ||--o{ wallets : "owns"
620
+ developers ||--o{ auth_sessions : "authenticates"
664
621
 
665
- ### Seeded Merchants
622
+ wallets ||--o{ cards : "has"
623
+ wallets ||--o{ agentic_tokens : "issues"
624
+ wallets ||--o{ transactions : "records"
625
+ wallets ||--o{ checkout_profiles : "has"
626
+ wallets ||--o{ merchant_accounts : "stores"
666
627
 
667
- The directory ships with pre-populated merchants including:
628
+ developers ||--o{ budgets : "sets"
629
+ developers ||--o{ audit_log : "audited"
630
+ developers ||--o{ agents : "manages"
631
+ developers ||--o{ mandates : "creates"
668
632
 
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).
633
+ agents ||--o{ delegations : "delegates"
634
+ agents ||--o{ agentic_tokens : "uses"
670
635
 
671
- Additional merchants are synced from the Lane backend on startup or via the sync API.
636
+ mandates ||--o{ agentic_tokens : "authorizes"
672
637
 
673
- ## Security
638
+ developers {
639
+ uuid id PK
640
+ uuid auth_user_id FK,UK
641
+ text email UK
642
+ text name
643
+ text plan "free | pro | team | enterprise"
644
+ text status "active | suspended | closed"
645
+ boolean sdk_access "whitelist gate"
646
+ }
674
647
 
675
- ### PCI DSS Compliance
648
+ api_keys {
649
+ uuid id PK
650
+ uuid developer_id FK
651
+ text key_hash UK "SHA-256"
652
+ text key_prefix "lane_sk_..."
653
+ text environment "test | live"
654
+ timestamptz revoked_at
655
+ }
676
656
 
677
- Card PANs **never** touch Lane servers. All card data is tokenized through [VGS](https://www.verygoodsecurity.com/) (Very Good Security):
657
+ wallets {
658
+ uuid id PK
659
+ uuid developer_id FK
660
+ text label
661
+ integer balance_cents
662
+ text currency "USD"
663
+ }
678
664
 
679
- ```ts
680
- import { VGSOutboundProxy, detectCardBrand, luhnCheck } from 'lane-sdk'
681
-
682
- // Card utilities
683
- detectCardBrand('4111111111111111') // 'visa'
684
- luhnCheck('4111111111111111') // true
685
-
686
- // Generate secure card collection form
687
- import { generateCollectPage } from 'lane-sdk'
688
- const html = generateCollectPage({
689
- vaultId: 'tnt...',
690
- environment: 'sandbox',
691
- formId: 'card-form',
692
- redirectUrl: 'https://app.example.com/done',
693
- })
694
- ```
665
+ cards {
666
+ uuid id PK
667
+ uuid wallet_id FK
668
+ text vgs_alias "VGS token"
669
+ text last4
670
+ text brand "visa | mastercard | ..."
671
+ text status "active | inactive"
672
+ }
695
673
 
696
- ### HMAC Request Signing
674
+ agentic_tokens {
675
+ uuid id PK
676
+ uuid wallet_id FK
677
+ integer amount_cents
678
+ text status "active | consumed | expired | revoked"
679
+ text merchant
680
+ timestamptz expires_at
681
+ }
697
682
 
698
- Every SDK request is signed with HMAC-SHA256:
683
+ transactions {
684
+ uuid id PK
685
+ uuid wallet_id FK
686
+ integer amount_cents
687
+ text status "success | failed | refunded"
688
+ text recipient
689
+ text psp_reference
690
+ }
699
691
 
700
- ```ts
701
- import { HMACSignature, verifyWebhookSignature } from 'lane-sdk'
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
- ```
692
+ budgets {
693
+ uuid id PK
694
+ uuid developer_id FK
695
+ integer daily_limit
696
+ integer weekly_limit
697
+ integer monthly_limit
698
+ integer per_task_limit
699
+ }
711
700
 
712
- ### Credential Storage
701
+ auth_sessions {
702
+ uuid id PK
703
+ text device_code
704
+ text status "pending | completed | consumed | expired"
705
+ text auth_code
706
+ text api_key
707
+ timestamptz expires_at
708
+ }
713
709
 
714
- Credentials are stored at `~/.lane/credentials.json` with `0600` file permissions (owner read/write only). Directory permissions are set to `0700`.
710
+ merchant_directory {
711
+ uuid id PK
712
+ text name
713
+ text domain UK
714
+ text slug UK
715
+ text tier "lane_onboarded | protocol"
716
+ text vertical
717
+ jsonb product_attributes
718
+ }
715
719
 
716
- ### HTTP Client Resilience
720
+ audit_log {
721
+ uuid id PK
722
+ uuid developer_id FK
723
+ text action
724
+ text resource_type
725
+ text resource_id
726
+ jsonb metadata
727
+ }
728
+ ```
717
729
 
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
730
+ ---
722
731
 
723
- ## Enterprise Features
732
+ ## Token Architecture
724
733
 
725
- ### Hierarchical Budgets
734
+ ### Prefixes
726
735
 
727
- Budget limits cascade: Organization > Team > Developer > Agent. The effective limit is the minimum across all levels.
736
+ | Prefix | Type | TTL | Storage |
737
+ |--------|------|-----|---------|
738
+ | `lane_sk_` | API key (live) | None | SHA-256 hash in `api_keys.key_hash` |
739
+ | `lane_sk_test_` | API key (test) | None | SHA-256 hash in `api_keys.key_hash` |
728
740
 
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
- })
741
+ ### Key Lifecycle
736
742
 
737
- // View effective limits
738
- const budget = await lane.teams.getHierarchicalBudget('team_123')
739
- // { orgBudget, teamBudget, developerBudget, agentBudget, effectiveLimits }
740
- ```
743
+ ```mermaid
744
+ flowchart LR
745
+ subgraph Issuance
746
+ LOGIN["CLI login<br/>complete-session"]
747
+ ROTATE["Key rotation<br/>/admin/rotate-key"]
748
+ ONBOARD["Onboarding<br/>/generate-key"]
749
+ end
741
750
 
742
- ### Agent Policies
751
+ LOGIN --> KEY["API Key<br/>lane_sk_...<br/>stored as SHA-256"]
752
+ ROTATE --> KEY
753
+ ONBOARD --> KEY
743
754
 
744
- Per-agent spending constraints:
755
+ KEY --> USE["Used for API calls<br/>Authorization: Bearer"]
756
+ KEY --> REVOKE["Revoked<br/>(15-min grace on rotation)"]
745
757
 
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
- })
758
+ style REVOKE fill:#fee,stroke:#c00
755
759
  ```
756
760
 
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
- })
761
+ ### Credential Storage
767
762
 
768
- const attestation = await lane.identity.getAttestation(identity.id)
763
+ - Stored at `~/.lane/credentials.json` with `0600` file permissions
764
+ - Directory `~/.lane/` has `0700` permissions
765
+ - Contains: `apiKey`, `developerId`, `environment`
766
+ - Plaintext key only available at creation time; server stores SHA-256 hash
767
+
768
+ ---
769
+
770
+ ## Security & Compliance
771
+
772
+ ### Card Data Flow
773
+
774
+ ```mermaid
775
+ sequenceDiagram
776
+ participant Agent as AI Agent
777
+ participant VGS_C as VGS Collect<br/>(iframe)
778
+ participant VGS_V as VGS Vault<br/>(PCI DSS L1)
779
+ participant Lane as Lane Server
780
+ participant VGS_P as VGS Outbound<br/>Proxy
781
+ participant PSP as PSP<br/>(Stripe/Worldpay)
782
+
783
+ Agent->>Lane: GET /card/add-link
784
+ Lane-->>Agent: VGS Collect URL
785
+ Agent->>VGS_C: User enters card PAN
786
+ Note over VGS_C: PAN never touches Lane
787
+ VGS_C->>VGS_V: Store PAN → token
788
+ VGS_V-->>Lane: tok_4111...1234 + last4 + brand
789
+
790
+ Note over Lane,PSP: At payment time
791
+ Lane->>VGS_P: Charge with token
792
+ VGS_P->>VGS_V: Detokenize
793
+ VGS_P->>PSP: Real PAN
794
+ PSP-->>Lane: Authorization
769
795
  ```
770
796
 
771
- ### Audit Trail
797
+ ### Security Controls
772
798
 
773
- Immutable audit log for SOC 2 compliance:
799
+ | Control | Implementation |
800
+ |---------|---------------|
801
+ | **PCI DSS** | Card PANs never touch Lane — VGS vault tokenization |
802
+ | **HMAC signing** | Every SDK request signed with HMAC-SHA256 |
803
+ | **Idempotency** | All mutations accept `idempotencyKey` to prevent duplicate charges |
804
+ | **API key hashing** | Keys stored as SHA-256; plaintext returned only at creation |
805
+ | **Key rotation** | Old key valid for 15-minute grace period |
806
+ | **Rate limiting** | Per-developer RPM limits enforced server-side |
807
+ | **Circuit breaker** | 3 consecutive failures opens circuit for 30 seconds |
808
+ | **Retries** | Exponential backoff (1s, 3s) on 5xx and 429 |
809
+ | **Credential storage** | `~/.lane/credentials.json` with `0600` permissions |
810
+ | **Budget enforcement** | Hierarchical: org > team > developer > agent > merchant > MCC |
811
+ | **Audit trail** | Append-only `audit_log` table for SOC 2 |
812
+ | **Biometric confirmation** | Touch ID / passkey for high-value instructions |
774
813
 
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
- })
814
+ ---
782
815
 
783
- const summary = await lane.audit.summary({ period: '30d' })
784
- // { totalEntries, byAction, byActorType, topActors }
785
- ```
816
+ ## Middleware & Route Protection
786
817
 
787
- ### GDPR
818
+ ```mermaid
819
+ flowchart TD
820
+ REQ([Incoming Request]) --> PATH{Route path?}
788
821
 
789
- ```ts
790
- const data = await lane.admin.exportData()
791
- const { deletionCompletesAt } = await lane.admin.deleteAccount()
792
- ```
822
+ PATH -->|"/health<br/>/agent/auth/*<br/>/agent/discovery"| PUBLIC([No auth — public])
793
823
 
794
- ## Server
824
+ PATH -->|"/agent/*"| CHAIN["API Key Auth<br/>↓<br/>Rate Limit<br/>↓<br/>HMAC Verify<br/>↓<br/>Audit Logger<br/>↓<br/>Route Handler"]
795
825
 
796
- The SDK includes a full Express backend with OOP service architecture.
826
+ PATH -->|"/api/sdk/*"| LEGACY["Deprecation Header<br/>↓<br/>Same middleware chain"]
797
827
 
798
- ### Environment Variables
828
+ PATH -->|"Unknown"| E404([404 Not Found])
799
829
 
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=...
830
+ CHAIN --> HANDLER([Route Handler])
831
+ LEGACY --> HANDLER
809
832
  ```
810
833
 
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
834
+ ### Request Lifecycle
824
835
 
836
+ ```mermaid
837
+ sequenceDiagram
838
+ participant Client as SDK Client
839
+ participant Auth as API Key Auth
840
+ participant RL as Rate Limit
841
+ participant HMAC as HMAC Verify
842
+ participant Audit as Audit Logger
843
+ participant Service as Service Layer
844
+ participant DB as Supabase
845
+ participant VGS as VGS / PSP
846
+
847
+ Client->>Auth: Bearer lane_sk_...<br/>X-Lane-Signature: sha256<br/>Idempotency-Key: ...
848
+ Auth->>DB: SHA-256(key) → api_keys
849
+ Auth->>Auth: Check not revoked
850
+
851
+ Auth->>RL: req.developer set
852
+ RL->>RL: Check RPM limit
853
+
854
+ RL->>HMAC: Pass
855
+ HMAC->>HMAC: Verify signature
856
+
857
+ HMAC->>Audit: Pass
858
+ Audit->>DB: Log request
859
+
860
+ Audit->>Service: Route handler
861
+ Service->>DB: Business logic
862
+ Service->>VGS: Card operations (if payment)
863
+ Service-->>Client: JSON response
825
864
  ```
826
- Request → JSON Parser → CORS → API Key Auth → Rate Limit → HMAC Verify → Audit → Route → Error Handler
827
- ```
828
-
829
- ### Services (9)
830
865
 
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 |
866
+ ---
842
867
 
843
- ### Database
868
+ ## Cross-Service Auth: SDK vs Lane-Auth
844
869
 
845
- 11 SQL migrations using Supabase (PostgreSQL) with Row Level Security on all tables:
870
+ The Lane platform has two separate auth systems in different repos:
846
871
 
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
872
+ | | SDK Server (`lane-agent-sdk`) | Auth Service (`lane-auth`) |
873
+ |---|---|---|
874
+ | **Base URL** | `api.getonlane.com/sdk` | `auth.getonlane.com` |
875
+ | **Purpose** | Developer onboarding, SDK access gating | Identity, sessions, compliance |
876
+ | **DB access** | Service role key (bypasses RLS) | Anon key (subject to RLS) |
877
+ | **Token type** | `lane_sk_` API keys | `lane_cli_` + `lane_rt_` token pairs |
878
+ | **Anti-phishing** | 4-char device code (`LANE-XXXX`) | 8-char code + 2-digit number match |
879
+
880
+ ```mermaid
881
+ graph TB
882
+ subgraph "lane-agent-sdk repo"
883
+ SDK_SERVER["SDK Server (Express)<br/>api.getonlane.com/sdk"]
884
+ WALLET["Wallet App (Next.js)<br/>agent.getonlane.com"]
885
+ CLI["Lane CLI<br/>npx lane ..."]
886
+ SDK_LIB["SDK Library<br/>Lane.create()"]
887
+ end
888
+
889
+ subgraph "lane-auth repo"
890
+ AUTH["Auth Service (Next.js)<br/>auth.getonlane.com"]
891
+ end
892
+
893
+ subgraph Supabase
894
+ DB["PostgreSQL<br/>developers · api_keys<br/>auth_sessions · wallets"]
895
+ end
896
+
897
+ CLI -->|"/agent/auth/*"| SDK_SERVER
898
+ WALLET -->|"popup for OTP"| AUTH
899
+ WALLET -->|"/agent/auth/complete-session"| SDK_SERVER
900
+ SDK_LIB -->|"/agent/auth/verify-sdk-access"| SDK_SERVER
901
+ SDK_SERVER -->|"service role key"| DB
902
+ AUTH -->|"anon key + RLS"| DB
903
+
904
+ style SDK_SERVER fill:#e6f0ff,stroke:#4a90d9
905
+ style WALLET fill:#e6f0ff,stroke:#4a90d9
906
+ style CLI fill:#e6f0ff,stroke:#4a90d9
907
+ style SDK_LIB fill:#e6f0ff,stroke:#4a90d9
908
+ style AUTH fill:#ffebeb,stroke:#d94a4a
859
909
  ```
860
910
 
861
- ## Architecture
911
+ ---
862
912
 
863
- ### System Overview
913
+ ## Project Structure
864
914
 
865
915
  ```
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
- └──────────────────────────────────────────────────────────────────────────┘
916
+ lane-agent-sdk/
917
+ ├── src/
918
+ ├── lane.ts # SDK entry point (Lane class)
919
+ │ ├── client.ts # HTTP client (HMAC, retries, circuit breaker)
920
+ ├── config.ts # Config resolution
921
+ ├── errors.ts # Typed error hierarchy
922
+ ├── types.ts # Shared types
923
+ ├── index.ts # Public exports
924
+ ├── resources/ # 22 resource classes
925
+ ├── base.ts # Base resource with _get/_post/_put/_delete
926
+ │ │ ├── auth.ts # Authentication
927
+ │ ├── wallets.ts # Wallets
928
+ ├── pay.ts # Payments
929
+ │ ├── merchants.ts # Merchant directory
930
+ │ ├── instructions.ts # VIC instructions
931
+ │ ├── mandates.ts # Spending mandates
932
+ │ │ └── ... # 15 more resource files
933
+ ├── auth/
934
+ │ ├── browser-flow.ts # Local callback server for login
935
+ ├── token-store.ts # ~/.lane/credentials.json I/O
936
+ │ ├── biometric.ts # Touch ID / passkey confirmation
937
+ └── confirmation.ts # Payment confirmation flow
938
+ ├── cli/
939
+ │ ├── index.ts # CLI entry point (Commander)
940
+ ├── terse.ts # Terse output helpers
941
+ ├── branding.ts # CLI logo and colors
942
+ └── commands/ # 26 command files
943
+ ├── mcp/
944
+ ├── server.ts # MCP server (discovery + auth modes)
945
+ ├── tool.ts # Base tool class (LaneTool<T>)
946
+ └── tools/ # 28 tool files
947
+ ├── vgs/
948
+ ├── proxy.ts # VGS outbound proxy
949
+ ├── token.ts # VGS token management
950
+ ├── card-types.ts # Card brand detection, Luhn
951
+ └── collect.ts # VGS Collect form generation
952
+ ├── psp/
953
+ ├── registry.ts # PSP adapter registry
954
+ │ ├── types.ts # PSP interfaces
955
+ └── adapters/ # Stripe, Worldpay, CyberSource
956
+ ├── routing/
957
+ └── engine.ts # 5-tier payment routing
958
+ └── adapters/ # Framework adapters
959
+ ├── openai/ # OpenAI function calling
960
+ ├── langchain/ # LangChain tools
961
+ ├── crewai/ # CrewAI tools
962
+ └── vercel-ai/ # Vercel AI SDK
963
+ ├── server/
964
+ ├── index.ts # Express entry point
965
+ │ ├── middleware/
966
+ │ └── api-key-auth.ts # API key validation
967
+ ├── routes/
968
+ │ ├── agent/ # /agent/* routes
969
+ │ │ ├── auth.ts # Login, token, complete-session
970
+ ├── admin.ts # Whoami, rotate-key, keys
971
+ └── instruction.ts # Instruction routes
972
+ └── auth.ts # Legacy auth routes
973
+ ├── services/ # 23 service classes
974
+ ├── wallet-service.ts
975
+ ├── payment-service.ts
976
+ ├── budget-service.ts
977
+ ├── instruction-service.ts
978
+ ├── mandate-service.ts
979
+ └── ...
980
+ ├── lib/
981
+ ├── service-container.ts # DI container
982
+ │ │ ├── errors.ts # Server error types
983
+ │ └── logger.ts # Structured logger
984
+ └── db/
985
+ └── migrations/ # Legacy migration scripts
986
+ ├── wallet/ # Next.js wallet app (agent.getonlane.com)
987
+ ├── src/app/
988
+ ├── authorize/page.tsx # Device code verification
989
+ │ ├── dashboard/ # Developer dashboard
990
+ │ │ └── onboarding/ # Onboarding flow
991
+ │ └── public/
992
+ │ └── SKILL.md # Agent skill documentation
993
+ ├── supabase/
994
+ │ └── migrations/ # 32 SQL migrations
995
+ ├── poc/ # End-to-end proof of concept
996
+ ├── tsup.config.ts # Build config (ESM + CJS + CLI)
997
+ └── vitest.config.ts # Test config
941
998
  ```
942
999
 
943
- ### Request Lifecycle
1000
+ ---
944
1001
 
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
- ```
1002
+ ## Environment Variables
1000
1003
 
1001
- ### PSP Adapters
1004
+ ### SDK (Client)
1002
1005
 
1003
- Three payment processor adapters with priority-based failover:
1006
+ | Variable | Description | Default |
1007
+ |----------|-------------|---------|
1008
+ | `LANE_API_KEY` | API key for authentication | — |
1009
+ | `LANE_BASE_URL` | SDK server base URL | `https://api.getonlane.com/sdk` |
1010
+ | `LANE_API_URL` | API URL for sell-side operations | `https://api.getonlane.com` |
1011
+ | `LANE_TEST_MODE` | Force test mode | `false` (auto-detected from key prefix) |
1012
+ | `LANE_TIMEOUT` | Request timeout (ms) | `30000` |
1013
+ | `LANE_MAX_RETRIES` | Max retry attempts | `2` |
1004
1014
 
1005
- ```ts
1006
- import { PSPRegistry, StripeAdapter, WorldpayAdapter, CyberSourceAdapter } from 'lane-sdk'
1015
+ ### Server
1007
1016
 
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
1017
+ | Variable | Description | Default |
1018
+ |----------|-------------|---------|
1019
+ | `SUPABASE_URL` | Supabase project URL | — (required) |
1020
+ | `SUPABASE_SERVICE_KEY` | Supabase service role key | — (required) |
1021
+ | `PORT` | Express server port | `3001` |
1022
+ | `LOG_LEVEL` | Logger level | `INFO` |
1023
+ | `WALLET_APP_URL` | Wallet app URL (for auth redirects) | `https://api.getonlane.com` |
1012
1024
 
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
- ```
1025
+ ---
1021
1026
 
1022
1027
  ## Development
1023
1028
 
@@ -1025,36 +1030,35 @@ const result = await primary.charge({
1025
1030
  # Install dependencies
1026
1031
  npm install
1027
1032
 
1028
- # Build (ESM + CJS + CLI + DTS)
1033
+ # Build (ESM + CJS + CLI + server + DTS)
1029
1034
  npm run build
1030
1035
 
1031
1036
  # Type check
1032
- npx tsc --noEmit
1037
+ npm run lint
1033
1038
 
1034
- # Run tests (110 tests via Vitest)
1039
+ # Run tests (651 tests via Vitest)
1035
1040
  npm test
1036
1041
 
1037
1042
  # Watch mode
1038
- npm run dev # Build
1039
- npm run test:watch # Tests
1043
+ npm run dev
1040
1044
  ```
1041
1045
 
1042
- ### Test Coverage
1046
+ ### Test Suite
1043
1047
 
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 |
1048
+ 651 tests across 48 test files:
1049
+
1050
+ | Category | Files | Tests | Coverage |
1051
+ |---|---|---|---|
1052
+ | SDK core | `config`, `errors`, `lane`, `signature` | ~50 | Config resolution, error hierarchy, initialization |
1053
+ | Agent UX | `sdk-accessibility`, `mcp-accessibility`, `cli-accessibility`, `error-consistency`, `scorecard` | ~200 | Agent-facing API quality, error messages, competitive analysis |
1054
+ | Compliance | `budget-enforcement`, `input-validation`, `pci-compliance`, `soc2-audit` | ~110 | Budget limits, PCI controls, audit trail |
1055
+ | Server | `instruction-service`, `mandate-service`, `state-machines`, `mandate-edge-cases` | ~100 | Service logic, state transitions, edge cases |
1056
+ | CLI | `login`, `pay`, `status`, `terse` | ~40 | Command output, terse formatting |
1057
+ | MCP | `pay`, `pay-with-mandate`, `provision-vic`, `confirm-instruction`, `budget-tools` | ~50 | Tool execution, error handling |
1058
+ | Auth | `biometric`, `confirmation` | ~20 | Biometric flows, confirmation lifecycle |
1059
+ | Infrastructure | `routing/engine`, `merchants/ucp-directory`, `mcp/tool`, `mcp/server` | ~40 | Routing decisions, merchant resolution, MCP lifecycle |
1060
+
1061
+ ---
1058
1062
 
1059
1063
  ## License
1060
1064