lane-sdk
v0.3.6
Published
Add wallets and payments to your AI agents
Downloads
2,834
Readme
Lane Agent SDK
npm install lane-sdk— Add wallets and payments to your AI agents.
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.
Stack: TypeScript · Express · Supabase (PostgreSQL + RLS) · VGS · Visa Intelligent Commerce
Production: https://api.getonlane.com/sdk
Wallet app: https://agent.getonlane.com
Auth service: https://auth.getonlane.comimport Lane from 'lane-sdk'
const lane = await Lane.create()
// Discover merchants
const { data: merchants } = await lane.merchants.list({ query: 'sneakers' })
// Search products
const { data: products } = await lane.products.search({ query: 'jordan 4' })
// Execute payment
const txn = await lane.pay.execute({
recipient: merchants[0].domain,
amount: 19999, // cents
currency: 'USD',
description: 'Jordan 4 Retro',
})Table of Contents
- Architecture Overview
- Three Ways to Integrate
- Quick Start
- Authentication Flows
- Payment Routing
- Merchant Discovery
- API Reference
- SDK Resources
- MCP Integration
- CLI
- Database Schema
- Token Architecture
- Security & Compliance
- Middleware & Route Protection
- Cross-Service Auth: SDK vs Lane-Auth
- Project Structure
- Environment Variables
- Development
Architecture Overview
graph TB
subgraph Clients
AGENT["AI Agent<br/>(Claude, Cursor, Custom)"]
MCP_CLIENT["MCP Client"]
APP["Application Code"]
end
subgraph "Lane SDK (TypeScript)"
SDK_LIB["SDK Library<br/>Lane.create() · 22 resources"]
MCP_SERVER["MCP Server<br/>28 tools · stdio/HTTP"]
CLI["CLI<br/>npx lane · 26 commands"]
end
subgraph "HTTP Client"
CLIENT["LaneClient<br/>HMAC-SHA256 · Retries<br/>Circuit Breaker · Idempotency"]
end
subgraph "Lane Server (Express)"
MW["Middleware<br/>API Key Auth → Rate Limit<br/>→ HMAC Verify → Audit"]
ROUTES["Routes<br/>/agent/auth · /agent/admin<br/>/agent/wallet · /agent/pay<br/>/agent/merchant · ..."]
SERVICES["Services (23)<br/>Payment · Wallet · Budget<br/>Merchant · VIC · Mandate · ..."]
end
subgraph Infrastructure
VGS["VGS Vault<br/>PCI DSS Level 1"]
PSP["PSP Registry<br/>Stripe · Worldpay<br/>CyberSource"]
end
subgraph "Supabase"
DB["PostgreSQL + RLS<br/>32 migrations"]
end
AGENT --> MCP_CLIENT --> MCP_SERVER
APP --> SDK_LIB
AGENT --> CLI
MCP_SERVER --> CLIENT
SDK_LIB --> CLIENT
CLI --> CLIENT
CLIENT --> MW --> ROUTES --> SERVICES
SERVICES --> DB
SERVICES --> VGS --> PSPThree Ways to Integrate
graph LR
subgraph "MCP Server"
MCP["28 tools<br/>Zod validation<br/>JSON responses<br/><br/>stdio or HTTP transport"]
end
subgraph "SDK (TypeScript)"
SDK["22 resource classes<br/>Lazy initialization<br/>Type-safe methods<br/><br/>Lane.create()"]
end
subgraph "CLI"
CLI_["26 commands<br/>Terse mode (-t)<br/>key=value output<br/><br/>npx lane <cmd>"]
end
MCP --> HTTP["Lane HTTP Client<br/>HMAC · Retries · Circuit Breaker"]
SDK --> HTTP
CLI_ --> HTTP
HTTP --> API["Lane API Server"]| | MCP Server | SDK | CLI |
|---|---|---|---|
| Use case | AI agents that speak MCP | Application code | Developers, scripts, agents via SKILL.md |
| Auth | LANE_API_KEY env or lane_connect tool | Lane.create() or Lane.fromApiKey() | npx lane login → ~/.lane/credentials.json |
| Output | JSON tool responses | TypeScript objects | key=value pairs (terse mode) |
Quick Start
# Install
npm install lane-sdk
# Authenticate (opens browser)
npx lane login
# Verify
npx lane whoami
# Search merchants
npx lane merchant list
# Make a payment
npx lane pay --recipient replicate.com --amount 20.00Programmatic Usage
import Lane from 'lane-sdk'
// Option 1: Async config resolution (constructor > env > credentials file)
const lane = await Lane.create()
// Option 2: Explicit API key
const lane = await Lane.fromApiKey('lane_sk_...')
// Option 3: Test mode (auto-detected from key prefix)
const lane = await Lane.fromApiKey('lane_sk_test_...')Authentication Flows
CLI Login (Device-Code Flow)
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.
sequenceDiagram
box rgb(230,240,255) lane-agent-sdk
actor Dev as Developer
participant CLI as Lane CLI
participant SDK as SDK Server<br/>/agent/auth/*
participant Wallet as Wallet App<br/>/authorize
end
box rgb(255,235,235) lane-auth
participant Auth as Auth Service<br/>auth.getonlane.com
end
participant DB as Supabase
Note over CLI,SDK: Phase 1 — Initiate
CLI->>SDK: POST /agent/auth/login
SDK->>DB: INSERT auth_sessions (pending, 10min TTL)
SDK-->>CLI: { sessionId, authUrl, deviceCode: "LANE-A3B7" }
CLI-->>Dev: "auth_url=... device_code=LANE-A3B7"
Note over Wallet,Auth: Phase 2 — Browser Auth
Dev->>Wallet: Open /authorize?s={sessionId}&redirect_port={port}
Wallet->>SDK: GET /agent/auth/device-status?s={sessionId}
SDK-->>Wallet: { deviceCode: "LANE-A3B7" }
Dev->>Wallet: "Codes match — continue"
rect rgb(255,235,235)
Note over Wallet,Auth: OTP login via lane-auth popup
Wallet->>Auth: window.open("/login?embed=true")
Auth-->>Dev: OTP email
Dev->>Auth: Enter 6-digit code
Auth-->>Wallet: postMessage("lane:auth:complete")
end
Note over Wallet,SDK: Phase 3 — Complete Session
Wallet->>SDK: POST /agent/auth/complete-session<br/>{ sessionId, userId, email }
SDK->>DB: UPSERT developers (sdk_access: true)
SDK->>DB: INSERT api_keys (lane_sk_ key)
SDK->>DB: UPDATE auth_sessions → completed
SDK-->>Wallet: { code }
Wallet-->>CLI: http://127.0.0.1:{port}/callback?code=...
Note over CLI,SDK: Phase 4 — Token Exchange
CLI->>SDK: POST /agent/auth/token { code, sessionId }
SDK->>DB: Verify + UPDATE auth_sessions → consumed
SDK-->>CLI: { apiKey: "lane_sk_...", developerId }
CLI->>CLI: Write ~/.lane/credentials.json
CLI-->>Dev: "ready=true email=..."SDK Access Verification
Every Lane.create() call verifies the developer's SDK access before returning an instance.
sequenceDiagram
participant App as Application Code
participant SDK as Lane.create()
participant Server as SDK Server
participant DB as Supabase
App->>SDK: Lane.create()
SDK->>SDK: resolveConfig()<br/>API key from: args → env → credentials file
SDK->>Server: POST /agent/auth/verify-sdk-access<br/>Authorization: Bearer lane_sk_...
Server->>DB: SHA-256(key) → api_keys JOIN developers
alt sdk_access = true
Server-->>SDK: 200 { access: true }
SDK-->>App: Lane instance ready
else sdk_access = false
Server-->>SDK: 403 { code: "waitlist" }
SDK-->>App: throw Error("Coming Soon")
else Network error / timeout
Note over SDK: Fail open (offline dev)
SDK-->>App: Lane instance ready
endConfig Resolution
API key resolution order (first match wins):
- Constructor argument:
Lane.create({ apiKey: '...' })orLane.fromApiKey('...') - Environment variable:
LANE_API_KEY - Credentials file:
~/.lane/credentials.json(written bynpx lane login)
Config is frozen after resolution — no mutation allowed.
Payment Routing
Lane's routing engine selects the optimal payment path using a 5-tier priority system:
flowchart TD
START([Payment Request]) --> BUDGET{Budget check<br/>within limits?}
BUDGET -->|No| DENIED([DENIED<br/>budget_exceeded])
BUDGET -->|Yes| LOOKUP[Lookup merchant<br/>in registry]
LOOKUP --> T1{Has Billing API?}
T1 -->|Yes| TIER1([Tier 1: Billing API<br/>Direct integration — cheapest])
T1 -->|No| T2{Supports ACP?}
T2 -->|Yes| TIER2([Tier 2: ACP<br/>Agent Commerce Protocol])
T2 -->|No| T3{Supports UCP?}
T3 -->|Yes| TIER3([Tier 3: UCP<br/>Universal Checkout Protocol])
T3 -->|No| T4{Has VIC token<br/>+ Visa card?}
T4 -->|Yes| TIER4([Tier 4: x402<br/>Visa network token])
T4 -->|No| TIER5([Tier 5: Fallback<br/>Browser checkout / Rye])
style DENIED fill:#fee,stroke:#c00
style TIER1 fill:#efe,stroke:#0a0
style TIER2 fill:#efe,stroke:#0a0
style TIER3 fill:#efe,stroke:#0a0
style TIER4 fill:#efe,stroke:#0a0
style TIER5 fill:#ffe,stroke:#aa0Budget Enforcement (Hierarchical)
flowchart TD
REQ([Payment $150]) --> ORG{Org budget<br/>$10,000/mo}
ORG -->|Pass| TEAM{Team budget<br/>$2,000/mo}
TEAM -->|Pass| DEV{Developer budget<br/>$500/day}
DEV -->|Pass| AGENT{Agent policy<br/>$200/txn}
AGENT -->|Pass| MERCHANT{Merchant<br/>allowlist check}
MERCHANT -->|Pass| MCC{MCC category<br/>check}
MCC -->|Pass| ROUTE([Route to payment<br/>effective limit = min of all])
ORG -->|Fail| DENY([DENIED])
TEAM -->|Fail| DENY
DEV -->|Fail| DENY
AGENT -->|Fail| DENY
MERCHANT -->|Fail| DENY
MCC -->|Fail| DENYMerchant Discovery
Two-tier merchant directory with in-memory cache (refreshed every 30 minutes):
graph TB
subgraph "Merchant Directory Service"
CACHE["In-Memory Cache<br/>(30-min refresh)"]
end
subgraph "Tier 1: Lane-Onboarded"
T1["Synced from Lane backend<br/>Full checkout API<br/>Product catalog<br/>Payment routing"]
end
subgraph "Tier 2: Protocol Discovery"
T2["Probe domain:<br/>GET /.well-known/ucp<br/>GET /.well-known/acp<br/><br/>Cached manifests"]
end
CACHE --> T1
CACHE --> T2
T1 --> DB[(merchant_directory<br/>PostgreSQL)]
T2 --> DBTaxonomy
| Type | Verticals | Example Subcategories |
|---|---|---|
| ecommerce | fashion, electronics, beauty, home, food, sports | shoes, sneakers, laptops, skincare |
| software | developer_tools, productivity, ai_ml, security | hosting, databases, ci_cd, auth |
| api | data, communications, payments, infrastructure | enrichment, sms, processing, cdn |
| saas | business, marketing, finance | crm, analytics, accounting |
| skill | agent_tools | web_scraping, code_gen, research |
| service | travel, delivery, professional | flights, food, legal |
API Reference
Public Endpoints (no auth required)
| Endpoint | Method | Description |
|----------|--------|-------------|
| /agent/auth/login | POST | Initiate browser auth session |
| /agent/auth/token | POST | Exchange one-time code for API key |
| /agent/auth/complete-session | POST | Complete CLI auth (called by wallet) |
| /agent/auth/device-status | GET | Poll device code status |
| /agent/auth/verify-sdk-access | POST | Check SDK whitelist (Bearer token) |
| /agent/discovery | GET | Agent discovery metadata |
| /health | GET | Health check |
Protected Endpoints (API key required)
| Prefix | Description |
|--------|-------------|
| /agent/admin | whoami, rotate-key, keys list |
| /agent/wallet | Wallet CRUD, balance, deposit |
| /agent/card | Card management, VGS collect links |
| /agent/pay | Token creation, payment execution, refunds |
| /agent/instruction | VIC instruction lifecycle, credentials, confirmations |
| /agent/token | Agentic token provisioning |
| /agent/transaction | Transaction history, refunds |
| /agent/budget | Budget get/set |
| /agent/merchant | Merchant list, search, discover, verticals |
| /agent/product | Product search, get |
| /agent/checkout | Checkout sessions |
| /agent/subscription | Subscription management |
| /agent/fleet | Agent fleet management |
| /agent/team | Team management |
| /agent/webhook | Webhook CRUD |
| /agent/audit | Audit trail queries |
| /agent/onboarding | Onboarding key generation |
Legacy Endpoints (deprecated)
| Prefix | Description |
|--------|-------------|
| /api/sdk/auth | Login, token exchange, key rotation |
| /api/sdk/wallets | Wallet operations |
| /api/sdk/pay | Payment operations |
| /api/sdk/admin | Admin operations |
| /api/sdk/merchants | Merchant directory |
All /api/sdk/* responses include Deprecation and Sunset headers. Migrate to /agent/*.
Response:
{
"sessionId": "550e8400-e29b-41d4-a716-446655440000",
"authUrl": "https://api.getonlane.com/authorize?s=550e8400...",
"deviceCode": "LANE-A3B7"
}Header: Authorization: Bearer lane_sk_...
Response:
{
"data": {
"id": "uuid",
"email": "[email protected]",
"plan": "free",
"memberSince": "2026-03-20T..."
}
}SDK Resources
The SDK exposes 22 resource classes, all lazily initialized on first access.
Core Resources
| Resource | Description | Key Methods |
|---|---|---|
| lane.auth | Authentication & key management | whoami(), login(), rotateKey() |
| lane.wallets | Wallet lifecycle & cards | create(), list(), balance(), deposit(), listCards() |
| lane.cards | Card management | list(), get(), remove() |
| lane.pay | Payment execution | createToken(), execute(), refund() |
| lane.products | Product discovery | search(), get() |
| lane.checkout | Checkout sessions | create(), complete(), get(), cancel() |
| lane.merchants | Merchant directory | list(), get(), discover(), verticals() |
| lane.admin | Spending & budgets | spending(), setBudget(), getBudget(), exportData() |
| lane.budget | Budget management | get(), set() |
| lane.transactions | Transaction history | list(), get(), refund() |
| lane.tokens | Agentic token lifecycle | provision(), list(), revoke() |
| lane.webhooks | Webhook management | create(), list(), verify() |
| lane.subscriptions | Subscription management | create(), cancel(), upgrade(), pause() |
Commerce Protocol Resources
| Resource | Description | Key Methods |
|---|---|---|
| lane.instructions | VIC instruction lifecycle | create(), getCredential(), confirm() |
| lane.mandates | Spending mandates | create(), list(), evaluate() |
| lane.protocol | Multi-protocol sessions | createSession(), execute() |
| lane.vic | Visa network tokens | issue(), getCryptogram(), revoke() |
| lane.sell | Seller tools | create(), list(), analytics() |
Enterprise Resources
| Resource | Description | Key Methods |
|---|---|---|
| lane.teams | Team management | create(), addMember(), setBudget() |
| lane.agents | Agent fleet management | register(), setPolicy(), suspend() |
| lane.fleet | Fleet operations | list(), getPolicy() |
| lane.audit | SOC 2 audit trail | query(), export(), summary() |
| lane.identity | Agent KYC chain | register(), verify(), getAttestation() |
| lane.delegations | Agent-to-agent delegation | create(), verify(), revoke() |
| lane.users | User management | list(), get() |
| lane.metering | Usage tracking (sellers) | record(), recordBatch(), report() |
| lane.payouts | Seller disbursements | getConfig(), setConfig(), list() |
MCP Integration
Lane ships with 28 MCP tools. 4 work without authentication (discovery mode); 24 require a connected API key.
Setup
# Auto-configure for Claude Desktop / Cursor
npx lane setup-mcpOr add to claude_desktop_config.json:
{
"mcpServers": {
"lane": {
"command": "npx",
"args": ["lane-mcp-server"],
"env": { "LANE_API_KEY": "lane_sk_..." }
}
}
}Pre-Auth Tools (Discovery Mode)
| Tool | Description |
|---|---|
| get_lane_info | Platform overview and capabilities |
| lane_signup | Start signup flow |
| lane_connect | Connect API key to initialize SDK |
| resolve_ucp_merchant | Resolve UCP merchant by domain |
Post-Auth Tools (24)
| Tool | Description |
|---|---|
| whoami | Get developer profile |
| check_balance | Get wallet balance |
| list_cards | List cards in wallet |
| pay | Execute a payment |
| list_transactions | Transaction history |
| search_products | Search product catalog |
| checkout | Purchase a product |
| set_budget | Set spending limits |
| request_refund | Refund a transaction |
| subscribe | Create a subscription |
| list_subscriptions | List subscriptions |
| cancel_subscription | Cancel a subscription |
| discover_merchants | Search merchant directory |
| search_software | Search software products |
| lane_add_card | Add a payment card |
| lane_onboarding_status | Check onboarding progress |
| protocol_pay | Multi-protocol payment |
| create_mandate | Create spending mandate |
| pay_with_mandate | Pay using mandate authorization |
| get_mandate_budget | Check mandate budget |
| get_instruction_budget | Check instruction budget |
| register_agent | Register agent in fleet |
| list_agents | List fleet agents |
| provision_vic_payment | Provision VIC credentials |
| confirm_instruction | Biometric confirmation |
CLI
26 commands plus 6 deprecated aliases.
lane <command>
Authentication:
login Authenticate (opens browser)
logout Clear local credentials
whoami Developer profile
status Readiness check (wallet, card, budget)
Wallet & Cards:
wallet Wallet management (list, create, deposit, balance)
card Card management (list, add, remove, get)
Payments:
pay Execute a payment
checkout Purchase from catalog
checkout-bridge Browser checkout with VIC credentials
budget Budget management (get, set)
token Token management (provision, list, revoke)
transaction Transaction history
Commerce:
merchant Merchant discovery (list, discover, verticals)
product Product search (search, get)
instruction VIC instruction lifecycle (create, credential, confirm)
session Shopping session management
batch Parallel merchant discovery
Enterprise:
fleet Agent fleet management
team Team management
user User management
webhook Webhook management
audit Audit trail queries
vendor Seller tools
Setup:
setup-mcp Configure MCP for Claude/Cursor
install-skill Register Lane skill for auto-activation
schema Display API schemaAll commands support -t / --terse flag for machine-readable key=value output on stdout.
Database Schema
32 migrations on Supabase (PostgreSQL) with Row Level Security on all tables.
erDiagram
developers ||--o{ api_keys : "has"
developers ||--o{ wallets : "owns"
developers ||--o{ auth_sessions : "authenticates"
wallets ||--o{ cards : "has"
wallets ||--o{ agentic_tokens : "issues"
wallets ||--o{ transactions : "records"
wallets ||--o{ checkout_profiles : "has"
wallets ||--o{ merchant_accounts : "stores"
developers ||--o{ budgets : "sets"
developers ||--o{ audit_log : "audited"
developers ||--o{ agents : "manages"
developers ||--o{ mandates : "creates"
agents ||--o{ delegations : "delegates"
agents ||--o{ agentic_tokens : "uses"
mandates ||--o{ agentic_tokens : "authorizes"
developers {
uuid id PK
uuid auth_user_id FK,UK
text email UK
text name
text plan "free | pro | team | enterprise"
text status "active | suspended | closed"
boolean sdk_access "whitelist gate"
}
api_keys {
uuid id PK
uuid developer_id FK
text key_hash UK "SHA-256"
text key_prefix "lane_sk_..."
text environment "test | live"
timestamptz revoked_at
}
wallets {
uuid id PK
uuid developer_id FK
text label
integer balance_cents
text currency "USD"
}
cards {
uuid id PK
uuid wallet_id FK
text vgs_alias "VGS token"
text last4
text brand "visa | mastercard | ..."
text status "active | inactive"
}
agentic_tokens {
uuid id PK
uuid wallet_id FK
integer amount_cents
text status "active | consumed | expired | revoked"
text merchant
timestamptz expires_at
}
transactions {
uuid id PK
uuid wallet_id FK
integer amount_cents
text status "success | failed | refunded"
text recipient
text psp_reference
}
budgets {
uuid id PK
uuid developer_id FK
integer daily_limit
integer weekly_limit
integer monthly_limit
integer per_task_limit
}
auth_sessions {
uuid id PK
text device_code
text status "pending | completed | consumed | expired"
text auth_code
text api_key
timestamptz expires_at
}
merchant_directory {
uuid id PK
text name
text domain UK
text slug UK
text tier "lane_onboarded | protocol"
text vertical
jsonb product_attributes
}
audit_log {
uuid id PK
uuid developer_id FK
text action
text resource_type
text resource_id
jsonb metadata
}Token Architecture
Prefixes
| Prefix | Type | TTL | Storage |
|--------|------|-----|---------|
| lane_sk_ | API key (live) | None | SHA-256 hash in api_keys.key_hash |
| lane_sk_test_ | API key (test) | None | SHA-256 hash in api_keys.key_hash |
Key Lifecycle
flowchart LR
subgraph Issuance
LOGIN["CLI login<br/>complete-session"]
ROTATE["Key rotation<br/>/admin/rotate-key"]
ONBOARD["Onboarding<br/>/generate-key"]
end
LOGIN --> KEY["API Key<br/>lane_sk_...<br/>stored as SHA-256"]
ROTATE --> KEY
ONBOARD --> KEY
KEY --> USE["Used for API calls<br/>Authorization: Bearer"]
KEY --> REVOKE["Revoked<br/>(15-min grace on rotation)"]
style REVOKE fill:#fee,stroke:#c00Credential Storage
- Stored at
~/.lane/credentials.jsonwith0600file permissions - Directory
~/.lane/has0700permissions - Contains:
apiKey,developerId,environment - Plaintext key only available at creation time; server stores SHA-256 hash
Security & Compliance
Card Data Flow
sequenceDiagram
participant Agent as AI Agent
participant VGS_C as VGS Collect<br/>(iframe)
participant VGS_V as VGS Vault<br/>(PCI DSS L1)
participant Lane as Lane Server
participant VGS_P as VGS Outbound<br/>Proxy
participant PSP as PSP<br/>(Stripe/Worldpay)
Agent->>Lane: GET /card/add-link
Lane-->>Agent: VGS Collect URL
Agent->>VGS_C: User enters card PAN
Note over VGS_C: PAN never touches Lane
VGS_C->>VGS_V: Store PAN → token
VGS_V-->>Lane: tok_4111...1234 + last4 + brand
Note over Lane,PSP: At payment time
Lane->>VGS_P: Charge with token
VGS_P->>VGS_V: Detokenize
VGS_P->>PSP: Real PAN
PSP-->>Lane: AuthorizationSecurity Controls
| Control | Implementation |
|---------|---------------|
| PCI DSS | Card PANs never touch Lane — VGS vault tokenization |
| HMAC signing | Every SDK request signed with HMAC-SHA256 |
| Idempotency | All mutations accept idempotencyKey to prevent duplicate charges |
| API key hashing | Keys stored as SHA-256; plaintext returned only at creation |
| Key rotation | Old key valid for 15-minute grace period |
| Rate limiting | Per-developer RPM limits enforced server-side |
| Circuit breaker | 3 consecutive failures opens circuit for 30 seconds |
| Retries | Exponential backoff (1s, 3s) on 5xx and 429 |
| Credential storage | ~/.lane/credentials.json with 0600 permissions |
| Budget enforcement | Hierarchical: org > team > developer > agent > merchant > MCC |
| Audit trail | Append-only audit_log table for SOC 2 |
| Biometric confirmation | Touch ID / passkey for high-value instructions |
Middleware & Route Protection
flowchart TD
REQ([Incoming Request]) --> PATH{Route path?}
PATH -->|"/health<br/>/agent/auth/*<br/>/agent/discovery"| PUBLIC([No auth — public])
PATH -->|"/agent/*"| CHAIN["API Key Auth<br/>↓<br/>Rate Limit<br/>↓<br/>HMAC Verify<br/>↓<br/>Audit Logger<br/>↓<br/>Route Handler"]
PATH -->|"/api/sdk/*"| LEGACY["Deprecation Header<br/>↓<br/>Same middleware chain"]
PATH -->|"Unknown"| E404([404 Not Found])
CHAIN --> HANDLER([Route Handler])
LEGACY --> HANDLERRequest Lifecycle
sequenceDiagram
participant Client as SDK Client
participant Auth as API Key Auth
participant RL as Rate Limit
participant HMAC as HMAC Verify
participant Audit as Audit Logger
participant Service as Service Layer
participant DB as Supabase
participant VGS as VGS / PSP
Client->>Auth: Bearer lane_sk_...<br/>X-Lane-Signature: sha256<br/>Idempotency-Key: ...
Auth->>DB: SHA-256(key) → api_keys
Auth->>Auth: Check not revoked
Auth->>RL: req.developer set
RL->>RL: Check RPM limit
RL->>HMAC: Pass
HMAC->>HMAC: Verify signature
HMAC->>Audit: Pass
Audit->>DB: Log request
Audit->>Service: Route handler
Service->>DB: Business logic
Service->>VGS: Card operations (if payment)
Service-->>Client: JSON responseCross-Service Auth: SDK vs Lane-Auth
The Lane platform has two separate auth systems in different repos:
| | SDK Server (lane-agent-sdk) | Auth Service (lane-auth) |
|---|---|---|
| Base URL | api.getonlane.com/sdk | auth.getonlane.com |
| Purpose | Developer onboarding, SDK access gating | Identity, sessions, compliance |
| DB access | Service role key (bypasses RLS) | Anon key (subject to RLS) |
| Token type | lane_sk_ API keys | lane_cli_ + lane_rt_ token pairs |
| Anti-phishing | 4-char device code (LANE-XXXX) | 8-char code + 2-digit number match |
graph TB
subgraph "lane-agent-sdk repo"
SDK_SERVER["SDK Server (Express)<br/>api.getonlane.com/sdk"]
WALLET["Wallet App (Next.js)<br/>agent.getonlane.com"]
CLI["Lane CLI<br/>npx lane ..."]
SDK_LIB["SDK Library<br/>Lane.create()"]
end
subgraph "lane-auth repo"
AUTH["Auth Service (Next.js)<br/>auth.getonlane.com"]
end
subgraph Supabase
DB["PostgreSQL<br/>developers · api_keys<br/>auth_sessions · wallets"]
end
CLI -->|"/agent/auth/*"| SDK_SERVER
WALLET -->|"popup for OTP"| AUTH
WALLET -->|"/agent/auth/complete-session"| SDK_SERVER
SDK_LIB -->|"/agent/auth/verify-sdk-access"| SDK_SERVER
SDK_SERVER -->|"service role key"| DB
AUTH -->|"anon key + RLS"| DB
style SDK_SERVER fill:#e6f0ff,stroke:#4a90d9
style WALLET fill:#e6f0ff,stroke:#4a90d9
style CLI fill:#e6f0ff,stroke:#4a90d9
style SDK_LIB fill:#e6f0ff,stroke:#4a90d9
style AUTH fill:#ffebeb,stroke:#d94a4aProject Structure
lane-agent-sdk/
├── src/
│ ├── lane.ts # SDK entry point (Lane class)
│ ├── client.ts # HTTP client (HMAC, retries, circuit breaker)
│ ├── config.ts # Config resolution
│ ├── errors.ts # Typed error hierarchy
│ ├── types.ts # Shared types
│ ├── index.ts # Public exports
│ ├── resources/ # 22 resource classes
│ │ ├── base.ts # Base resource with _get/_post/_put/_delete
│ │ ├── auth.ts # Authentication
│ │ ├── wallets.ts # Wallets
│ │ ├── pay.ts # Payments
│ │ ├── merchants.ts # Merchant directory
│ │ ├── instructions.ts # VIC instructions
│ │ ├── mandates.ts # Spending mandates
│ │ └── ... # 15 more resource files
│ ├── auth/
│ │ ├── browser-flow.ts # Local callback server for login
│ │ ├── token-store.ts # ~/.lane/credentials.json I/O
│ │ ├── biometric.ts # Touch ID / passkey confirmation
│ │ └── confirmation.ts # Payment confirmation flow
│ ├── cli/
│ │ ├── index.ts # CLI entry point (Commander)
│ │ ├── terse.ts # Terse output helpers
│ │ ├── branding.ts # CLI logo and colors
│ │ └── commands/ # 26 command files
│ ├── mcp/
│ │ ├── server.ts # MCP server (discovery + auth modes)
│ │ ├── tool.ts # Base tool class (LaneTool<T>)
│ │ └── tools/ # 28 tool files
│ ├── vgs/
│ │ ├── proxy.ts # VGS outbound proxy
│ │ ├── token.ts # VGS token management
│ │ ├── card-types.ts # Card brand detection, Luhn
│ │ └── collect.ts # VGS Collect form generation
│ ├── psp/
│ │ ├── registry.ts # PSP adapter registry
│ │ ├── types.ts # PSP interfaces
│ │ └── adapters/ # Stripe, Worldpay, CyberSource
│ ├── routing/
│ │ └── engine.ts # 5-tier payment routing
│ └── adapters/ # Framework adapters
│ ├── openai/ # OpenAI function calling
│ ├── langchain/ # LangChain tools
│ ├── crewai/ # CrewAI tools
│ └── vercel-ai/ # Vercel AI SDK
├── server/
│ ├── index.ts # Express entry point
│ ├── middleware/
│ │ └── api-key-auth.ts # API key validation
│ ├── routes/
│ │ ├── agent/ # /agent/* routes
│ │ │ ├── auth.ts # Login, token, complete-session
│ │ │ ├── admin.ts # Whoami, rotate-key, keys
│ │ │ └── instruction.ts # Instruction routes
│ │ └── auth.ts # Legacy auth routes
│ ├── services/ # 23 service classes
│ │ ├── wallet-service.ts
│ │ ├── payment-service.ts
│ │ ├── budget-service.ts
│ │ ├── instruction-service.ts
│ │ ├── mandate-service.ts
│ │ └── ...
│ ├── lib/
│ │ ├── service-container.ts # DI container
│ │ ├── errors.ts # Server error types
│ │ └── logger.ts # Structured logger
│ └── db/
│ └── migrations/ # Legacy migration scripts
├── wallet/ # Next.js wallet app (agent.getonlane.com)
│ ├── src/app/
│ │ ├── authorize/page.tsx # Device code verification
│ │ ├── dashboard/ # Developer dashboard
│ │ └── onboarding/ # Onboarding flow
│ └── public/
│ └── SKILL.md # Agent skill documentation
├── supabase/
│ └── migrations/ # 32 SQL migrations
├── poc/ # End-to-end proof of concept
├── tsup.config.ts # Build config (ESM + CJS + CLI)
└── vitest.config.ts # Test configEnvironment Variables
SDK (Client)
| Variable | Description | Default |
|----------|-------------|---------|
| LANE_API_KEY | API key for authentication | — |
| LANE_BASE_URL | SDK server base URL | https://api.getonlane.com/sdk |
| LANE_API_URL | API URL for sell-side operations | https://api.getonlane.com |
| LANE_TEST_MODE | Force test mode | false (auto-detected from key prefix) |
| LANE_TIMEOUT | Request timeout (ms) | 30000 |
| LANE_MAX_RETRIES | Max retry attempts | 2 |
Server
| Variable | Description | Default |
|----------|-------------|---------|
| SUPABASE_URL | Supabase project URL | — (required) |
| SUPABASE_SERVICE_KEY | Supabase service role key | — (required) |
| PORT | Express server port | 3001 |
| LOG_LEVEL | Logger level | INFO |
| WALLET_APP_URL | Wallet app URL (for auth redirects) | https://api.getonlane.com |
Development
# Install dependencies
npm install
# Build (ESM + CJS + CLI + server + DTS)
npm run build
# Type check
npm run lint
# Run tests (651 tests via Vitest)
npm test
# Watch mode
npm run devTest Suite
651 tests across 48 test files:
| Category | Files | Tests | Coverage |
|---|---|---|---|
| SDK core | config, errors, lane, signature | ~50 | Config resolution, error hierarchy, initialization |
| Agent UX | sdk-accessibility, mcp-accessibility, cli-accessibility, error-consistency, scorecard | ~200 | Agent-facing API quality, error messages, competitive analysis |
| Compliance | budget-enforcement, input-validation, pci-compliance, soc2-audit | ~110 | Budget limits, PCI controls, audit trail |
| Server | instruction-service, mandate-service, state-machines, mandate-edge-cases | ~100 | Service logic, state transitions, edge cases |
| CLI | login, pay, status, terse | ~40 | Command output, terse formatting |
| MCP | pay, pay-with-mandate, provision-vic, confirm-instruction, budget-tools | ~50 | Tool execution, error handling |
| Auth | biometric, confirmation | ~20 | Biometric flows, confirmation lifecycle |
| Infrastructure | routing/engine, merchants/ucp-directory, mcp/tool, mcp/server | ~40 | Routing decisions, merchant resolution, MCP lifecycle |
License
Copyright (c) 2026 Lane Technologies Inc. All rights reserved. This software is proprietary and confidential.
