lane-sdk 0.3.11 → 0.3.12

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 (47) hide show
  1. package/dist/adapters/crewai/index.cjs +12 -14
  2. package/dist/adapters/crewai/index.d.cts +1 -1
  3. package/dist/adapters/crewai/index.d.ts +1 -1
  4. package/dist/adapters/crewai/index.js +12 -14
  5. package/dist/adapters/langchain/index.cjs +12 -14
  6. package/dist/adapters/langchain/index.d.cts +1 -1
  7. package/dist/adapters/langchain/index.d.ts +1 -1
  8. package/dist/adapters/langchain/index.js +12 -14
  9. package/dist/adapters/openai/index.cjs +12 -14
  10. package/dist/adapters/openai/index.d.cts +1 -1
  11. package/dist/adapters/openai/index.d.ts +1 -1
  12. package/dist/adapters/openai/index.js +12 -14
  13. package/dist/adapters/vercel-ai/index.cjs +12 -14
  14. package/dist/adapters/vercel-ai/index.d.cts +1 -1
  15. package/dist/adapters/vercel-ai/index.d.ts +1 -1
  16. package/dist/adapters/vercel-ai/index.js +12 -14
  17. package/dist/cli/index.js +6 -7
  18. package/dist/cli/postinstall.js +0 -1
  19. package/dist/index.cjs +12 -936
  20. package/dist/index.d.cts +3 -354
  21. package/dist/index.d.ts +3 -354
  22. package/dist/index.js +13 -928
  23. package/dist/{lane-CATn69s2.d.cts → lane-BgdqOeXo.d.cts} +5 -5
  24. package/dist/{lane-CATn69s2.d.ts → lane-BgdqOeXo.d.ts} +5 -5
  25. package/dist/server-http.cjs +12 -14
  26. package/dist/server-http.js +12 -14
  27. package/dist/server-stdio.cjs +12 -14
  28. package/dist/server-stdio.js +12 -14
  29. package/dist/skills/lane.md +5 -5
  30. package/package.json +5 -2
  31. package/plugin/skills/commerce-agent/SKILL.md +2 -2
  32. package/dist/adapters/crewai/index.cjs.map +0 -1
  33. package/dist/adapters/crewai/index.js.map +0 -1
  34. package/dist/adapters/langchain/index.cjs.map +0 -1
  35. package/dist/adapters/langchain/index.js.map +0 -1
  36. package/dist/adapters/openai/index.cjs.map +0 -1
  37. package/dist/adapters/openai/index.js.map +0 -1
  38. package/dist/adapters/vercel-ai/index.cjs.map +0 -1
  39. package/dist/adapters/vercel-ai/index.js.map +0 -1
  40. package/dist/cli/index.js.map +0 -1
  41. package/dist/cli/postinstall.js.map +0 -1
  42. package/dist/index.cjs.map +0 -1
  43. package/dist/index.js.map +0 -1
  44. package/dist/server-http.cjs.map +0 -1
  45. package/dist/server-http.js.map +0 -1
  46. package/dist/server-stdio.cjs.map +0 -1
  47. package/dist/server-stdio.js.map +0 -1
package/dist/index.js CHANGED
@@ -5138,7 +5138,7 @@ var ConfirmInstructionTool = class extends LaneTool {
5138
5138
  }
5139
5139
  };
5140
5140
  var inputSchema27 = z.object({
5141
- platform: z.enum(["thanx", "doordash"]).describe("Commerce platform to query.")
5141
+ platform: z.string().describe("Commerce platform to query. The server resolves available platforms.")
5142
5142
  });
5143
5143
  var CommerceGetLocationsTool = class extends LaneTool {
5144
5144
  get definition() {
@@ -5153,7 +5153,7 @@ var CommerceGetLocationsTool = class extends LaneTool {
5153
5153
  }
5154
5154
  };
5155
5155
  var inputSchema28 = z.object({
5156
- platform: z.enum(["thanx", "doordash"]).describe("Commerce platform."),
5156
+ platform: z.string().describe("Commerce platform. The server resolves available platforms."),
5157
5157
  locationId: z.string().describe("Location ID to fetch the menu for.")
5158
5158
  });
5159
5159
  var CommerceGetMenuTool = class extends LaneTool {
@@ -5169,7 +5169,7 @@ var CommerceGetMenuTool = class extends LaneTool {
5169
5169
  }
5170
5170
  };
5171
5171
  var inputSchema29 = z.object({
5172
- platform: z.enum(["thanx", "doordash"]).describe("Commerce platform."),
5172
+ platform: z.string().describe("Commerce platform. The server resolves available platforms."),
5173
5173
  itemId: z.string().describe("Item ID to fetch modifiers for.")
5174
5174
  });
5175
5175
  var CommerceGetModifiersTool = class extends LaneTool {
@@ -5196,7 +5196,7 @@ var inputSchema30 = z.object({
5196
5196
  text: z.string().optional().describe('Natural language order request (e.g., "4 cold brews for pickup at Equator tomorrow 2pm"). If provided, server auto-resolves item, quantity, location, time, and modifiers.'),
5197
5197
  // Option B: structured params (agent already resolved from menu)
5198
5198
  description: z.string().optional().describe("Order summary (required if text not provided)."),
5199
- platform: z.enum(["thanx", "doordash"]).optional().describe("Auto-detected from fulfillmentType if omitted."),
5199
+ platform: z.string().optional().describe("Auto-detected by the server if omitted."),
5200
5200
  merchant: z.string().optional().describe("Merchant name (auto-detected from text if provided)."),
5201
5201
  walletId: z.string().default("default").describe("Wallet ID."),
5202
5202
  locationId: z.string().optional().describe("Location ID (auto-resolved from text if provided)."),
@@ -5229,7 +5229,7 @@ var CommerceOrderIntentTool = class extends LaneTool {
5229
5229
  };
5230
5230
  }
5231
5231
  async run(input) {
5232
- const platform2 = input.platform ?? (input.fulfillmentType === "delivery" ? "doordash" : "thanx");
5232
+ const platform2 = input.platform ?? "auto";
5233
5233
  return this.getLane().commerce.orders.createIntent(platform2, {
5234
5234
  ...input,
5235
5235
  description: input.description ?? input.text ?? "",
@@ -5240,7 +5240,7 @@ var CommerceOrderIntentTool = class extends LaneTool {
5240
5240
  }
5241
5241
  };
5242
5242
  var inputSchema31 = z.object({
5243
- platform: z.enum(["thanx", "doordash"]).optional().describe("Auto-detected from instruction if omitted."),
5243
+ platform: z.string().optional().describe("Auto-detected from instruction if omitted."),
5244
5244
  instructionId: z.string().describe("Instruction ID from order intent."),
5245
5245
  mandateId: z.string().describe("Mandate ID from order intent.")
5246
5246
  });
@@ -5253,7 +5253,7 @@ var CommerceExecuteOrderTool = class extends LaneTool {
5253
5253
  };
5254
5254
  }
5255
5255
  async run(input) {
5256
- const platform2 = input.platform ?? "thanx";
5256
+ const platform2 = input.platform ?? "auto";
5257
5257
  return this.getLane().commerce.orders.executeIntent(
5258
5258
  platform2,
5259
5259
  input.instructionId,
@@ -5262,7 +5262,7 @@ var CommerceExecuteOrderTool = class extends LaneTool {
5262
5262
  }
5263
5263
  };
5264
5264
  var inputSchema32 = z.object({
5265
- platform: z.enum(["thanx", "doordash"]).describe("Commerce platform to connect."),
5265
+ platform: z.string().describe("Commerce platform to connect. The server resolves available platforms."),
5266
5266
  walletId: z.string().optional().describe("Wallet ID to associate."),
5267
5267
  userEmail: z.string().optional().describe("User email for the platform."),
5268
5268
  displayName: z.string().optional().describe("Display name for the connection.")
@@ -5295,7 +5295,7 @@ var CommerceProviderStatusTool = class extends LaneTool {
5295
5295
  }
5296
5296
  };
5297
5297
  var inputSchema34 = z.object({
5298
- platform: z.enum(["thanx", "doordash"]).optional().describe("Auto-detected from instruction if omitted."),
5298
+ platform: z.string().optional().describe("Auto-detected from instruction if omitted."),
5299
5299
  orderId: z.string().describe("Order ID from the create order step."),
5300
5300
  instructionId: z.string().describe("Instruction ID from order intent."),
5301
5301
  cardId: z.string().optional().describe("Payment card ID. If omitted, server resolves first saved card."),
@@ -5311,7 +5311,7 @@ var CommerceCheckoutConfigTool = class extends LaneTool {
5311
5311
  };
5312
5312
  }
5313
5313
  async run(input) {
5314
- const platform2 = input.platform ?? "thanx";
5314
+ const platform2 = input.platform ?? "auto";
5315
5315
  return this.getLane().commerce.orders.configureCheckout(platform2, input.orderId, {
5316
5316
  instructionId: input.instructionId,
5317
5317
  cardId: input.cardId,
@@ -5321,7 +5321,7 @@ var CommerceCheckoutConfigTool = class extends LaneTool {
5321
5321
  }
5322
5322
  };
5323
5323
  var inputSchema35 = z.object({
5324
- platform: z.enum(["thanx", "doordash"]).optional().describe("Auto-detected from instruction if omitted."),
5324
+ platform: z.string().optional().describe("Auto-detected from instruction if omitted."),
5325
5325
  orderId: z.string().describe("Order ID to submit."),
5326
5326
  instructionId: z.string().describe("Instruction ID from order intent."),
5327
5327
  mandateId: z.string().describe("Mandate ID from order intent.")
@@ -5335,7 +5335,7 @@ var CommerceSubmitOrderTool = class extends LaneTool {
5335
5335
  };
5336
5336
  }
5337
5337
  async run(input) {
5338
- const platform2 = input.platform ?? "thanx";
5338
+ const platform2 = input.platform ?? "auto";
5339
5339
  return this.getLane().commerce.orders.submit(platform2, input.orderId, {
5340
5340
  instructionId: input.instructionId,
5341
5341
  mandateId: input.mandateId
@@ -5462,139 +5462,6 @@ var LaneMCPServer = class {
5462
5462
  }
5463
5463
  };
5464
5464
 
5465
- // src/vgs/token.ts
5466
- var TOKEN_REFRESH_MARGIN_MS = 6e4;
5467
- var VGSTokenManager = class {
5468
- constructor(config) {
5469
- this.config = config;
5470
- }
5471
- cached = null;
5472
- clearTimer = null;
5473
- /**
5474
- * Get a valid access token, refreshing if expired or near-expiry.
5475
- */
5476
- async getAccessToken() {
5477
- if (this.cached && Date.now() < this.cached.expiresAt - TOKEN_REFRESH_MARGIN_MS) {
5478
- return this.cached.accessToken;
5479
- }
5480
- return this.refresh();
5481
- }
5482
- /**
5483
- * Force-refresh the token.
5484
- */
5485
- async refresh() {
5486
- const tokenUrl = this.getTokenUrl();
5487
- const body = new URLSearchParams({
5488
- grant_type: "client_credentials",
5489
- client_id: this.config.clientId,
5490
- client_secret: this.config.clientSecret
5491
- });
5492
- const response = await fetch(tokenUrl, {
5493
- method: "POST",
5494
- headers: { "Content-Type": "application/x-www-form-urlencoded" },
5495
- body: body.toString()
5496
- });
5497
- if (!response.ok) {
5498
- throw LaneAuthError.invalidApiKey(
5499
- `VGS token exchange failed: ${response.status} ${response.statusText}`
5500
- );
5501
- }
5502
- const data = await response.json();
5503
- this.clearCachedToken();
5504
- this.cached = {
5505
- accessToken: data.access_token,
5506
- expiresAt: Date.now() + data.expires_in * 1e3
5507
- };
5508
- this.clearTimer = setTimeout(() => {
5509
- this.clearCachedToken();
5510
- }, data.expires_in * 1e3);
5511
- this.clearTimer.unref();
5512
- return this.cached.accessToken;
5513
- }
5514
- /**
5515
- * Invalidate the cached token.
5516
- */
5517
- invalidate() {
5518
- this.clearCachedToken();
5519
- }
5520
- /**
5521
- * Overwrite and release the cached token from memory.
5522
- */
5523
- clearCachedToken() {
5524
- if (this.clearTimer) {
5525
- clearTimeout(this.clearTimer);
5526
- this.clearTimer = null;
5527
- }
5528
- if (this.cached) {
5529
- this.cached.accessToken = "";
5530
- this.cached = null;
5531
- }
5532
- }
5533
- getTokenUrl() {
5534
- const env = this.config.environment === "live" ? "live" : "sandbox";
5535
- return `https://auth.verygoodsecurity.com/vaults/${this.config.vaultId}/tokens?env=${env}`;
5536
- }
5537
- };
5538
-
5539
- // src/vgs/proxy.ts
5540
- var VGSOutboundProxy = class {
5541
- constructor(config) {
5542
- this.config = config;
5543
- this.tokenManager = new VGSTokenManager(config);
5544
- }
5545
- tokenManager;
5546
- /**
5547
- * Send a request through the VGS outbound proxy.
5548
- * VGS aliases in the body are de-tokenized and revealed to the target PSP.
5549
- */
5550
- async forward(request) {
5551
- const accessToken = await this.tokenManager.getAccessToken();
5552
- const proxyUrl = this.getProxyUrl();
5553
- const response = await fetch(proxyUrl, {
5554
- method: request.method,
5555
- headers: {
5556
- ...request.headers,
5557
- "Authorization": `Bearer ${accessToken}`,
5558
- "X-VGS-Route-Id": this.config.routeId,
5559
- "X-VGS-Upstream-Url": request.url,
5560
- "Content-Type": "application/json"
5561
- },
5562
- body: JSON.stringify(request.body)
5563
- });
5564
- const responseBody = await response.json().catch(() => null);
5565
- if (!response.ok) {
5566
- throw new LanePaymentError(
5567
- `VGS proxy request failed: ${response.status}`,
5568
- {
5569
- code: "vgs_proxy_error",
5570
- statusCode: response.status,
5571
- retryable: response.status >= 500,
5572
- suggestedAction: "Check VGS vault configuration and PSP endpoint whitelist."
5573
- }
5574
- );
5575
- }
5576
- const responseHeaders = {};
5577
- response.headers.forEach((value, key) => {
5578
- responseHeaders[key] = value;
5579
- });
5580
- return {
5581
- status: response.status,
5582
- headers: responseHeaders,
5583
- body: responseBody
5584
- };
5585
- }
5586
- /**
5587
- * Invalidate the cached VGS access token.
5588
- */
5589
- invalidateToken() {
5590
- this.tokenManager.invalidate();
5591
- }
5592
- getProxyUrl() {
5593
- const env = this.config.environment === "live" ? "live" : "sandbox";
5594
- return `https://${this.config.vaultId}.${env}.verygoodproxy.com`;
5595
- }
5596
- };
5597
-
5598
5465
  // src/vgs/card-types.ts
5599
5466
  var BIN_RANGES = [
5600
5467
  { brand: "visa", prefixes: ["4"], lengths: [13, 16, 19] },
@@ -5638,638 +5505,6 @@ function maskCardNumber(cardNumber) {
5638
5505
  return `****${digits.slice(-4)}`;
5639
5506
  }
5640
5507
 
5641
- // src/vgs/collect.ts
5642
- function generateCollectPage(config) {
5643
- const vgsEnv = config.environment === "live" ? "live" : "sandbox";
5644
- `https://${config.vaultId}.${vgsEnv}.verygoodproxy.com`;
5645
- return `<!DOCTYPE html>
5646
- <html lang="en">
5647
- <head>
5648
- <meta charset="UTF-8">
5649
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
5650
- <title>Lane \u2014 Add Payment Method</title>
5651
- <script src="https://js.verygoodvault.com/vgs-collect/2.18.0/vgs-collect.js"></script>
5652
- <style>
5653
- * { box-sizing: border-box; margin: 0; padding: 0; }
5654
- body {
5655
- font-family: 'At Aero', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
5656
- background: #0A0A0A;
5657
- color: #FFFFFF;
5658
- display: flex;
5659
- justify-content: center;
5660
- align-items: center;
5661
- min-height: 100vh;
5662
- }
5663
- .container {
5664
- width: 100%;
5665
- max-width: 440px;
5666
- padding: 40px 32px;
5667
- background: #141414;
5668
- border: 1px solid #2A2A2A;
5669
- border-radius: 16px;
5670
- }
5671
- .logo {
5672
- font-size: 24px;
5673
- font-weight: 700;
5674
- color: #1201FF;
5675
- letter-spacing: -0.5px;
5676
- margin-bottom: 8px;
5677
- }
5678
- .subtitle {
5679
- color: #888;
5680
- font-size: 14px;
5681
- margin-bottom: 32px;
5682
- }
5683
- .field-group {
5684
- margin-bottom: 20px;
5685
- }
5686
- .field-group label {
5687
- display: block;
5688
- font-size: 12px;
5689
- font-weight: 600;
5690
- color: #888;
5691
- text-transform: uppercase;
5692
- letter-spacing: 0.5px;
5693
- margin-bottom: 8px;
5694
- }
5695
- .field-wrapper {
5696
- background: #1A1A1A;
5697
- border: 1px solid #333;
5698
- border-radius: 8px;
5699
- padding: 0;
5700
- height: 48px;
5701
- transition: border-color 0.2s;
5702
- }
5703
- .field-wrapper:focus-within {
5704
- border-color: #1201FF;
5705
- }
5706
- .field-wrapper iframe {
5707
- height: 48px !important;
5708
- }
5709
- .row {
5710
- display: flex;
5711
- gap: 12px;
5712
- }
5713
- .row .field-group {
5714
- flex: 1;
5715
- }
5716
- .submit-btn {
5717
- width: 100%;
5718
- height: 48px;
5719
- background: #1201FF;
5720
- color: #FFFFFF;
5721
- border: none;
5722
- border-radius: 8px;
5723
- font-size: 16px;
5724
- font-weight: 600;
5725
- cursor: pointer;
5726
- margin-top: 24px;
5727
- transition: background 0.2s;
5728
- }
5729
- .submit-btn:hover { background: #0E01CC; }
5730
- .submit-btn:disabled {
5731
- background: #333;
5732
- cursor: not-allowed;
5733
- }
5734
- .security-note {
5735
- text-align: center;
5736
- margin-top: 16px;
5737
- font-size: 12px;
5738
- color: #555;
5739
- }
5740
- .security-note svg {
5741
- vertical-align: middle;
5742
- margin-right: 4px;
5743
- }
5744
- .error-msg {
5745
- color: #FF4444;
5746
- font-size: 13px;
5747
- margin-top: 8px;
5748
- display: none;
5749
- }
5750
- .success-container {
5751
- text-align: center;
5752
- display: none;
5753
- }
5754
- .success-container .check {
5755
- font-size: 48px;
5756
- margin-bottom: 16px;
5757
- }
5758
- </style>
5759
- </head>
5760
- <body>
5761
- <div class="container">
5762
- <div id="form-view">
5763
- <div class="logo">Lane</div>
5764
- <div class="subtitle">Add a payment method. Your card data goes directly to our PCI Level 1 vault.</div>
5765
-
5766
- <form id="card-form">
5767
- <div class="field-group">
5768
- <label>Card Number</label>
5769
- <div id="cc-number" class="field-wrapper"></div>
5770
- </div>
5771
-
5772
- <div class="row">
5773
- <div class="field-group">
5774
- <label>Expiry</label>
5775
- <div id="cc-expiry" class="field-wrapper"></div>
5776
- </div>
5777
- <div class="field-group">
5778
- <label>CVC</label>
5779
- <div id="cc-cvc" class="field-wrapper"></div>
5780
- </div>
5781
- </div>
5782
-
5783
- <div class="field-group">
5784
- <label>Cardholder Name</label>
5785
- <div id="cc-name" class="field-wrapper"></div>
5786
- </div>
5787
-
5788
- <div id="error-msg" class="error-msg"></div>
5789
-
5790
- <button type="submit" id="submit-btn" class="submit-btn" disabled>
5791
- Add Card
5792
- </button>
5793
- </form>
5794
-
5795
- <div class="security-note">
5796
- <svg width="12" height="12" viewBox="0 0 12 12" fill="#555"><path d="M6 1a3 3 0 0 0-3 3v1H2.5A.5.5 0 0 0 2 5.5v5a.5.5 0 0 0 .5.5h7a.5.5 0 0 0 .5-.5v-5A.5.5 0 0 0 9.5 5H9V4a3 3 0 0 0-3-3zm2 4H4V4a2 2 0 1 1 4 0v1z"/></svg>
5797
- Secured by VGS. Lane never sees your card number.
5798
- </div>
5799
- </div>
5800
-
5801
- <div id="success-view" class="success-container">
5802
- <div class="check">&#10003;</div>
5803
- <div class="logo">Card Added</div>
5804
- <div class="subtitle">You can close this window and return to your terminal.</div>
5805
- </div>
5806
- </div>
5807
-
5808
- <script>
5809
- const form = VGSCollect.create('${config.vaultId}', '${vgsEnv}', function(state) {});
5810
- const css = {
5811
- 'font-family': '"JetBrains Mono", monospace',
5812
- 'font-size': '16px',
5813
- 'color': '#FFFFFF',
5814
- 'padding': '12px 16px',
5815
- '&::placeholder': { color: '#555' },
5816
- };
5817
-
5818
- form.field('#cc-number', {
5819
- type: 'card-number',
5820
- name: 'card_number',
5821
- placeholder: '4242 4242 4242 4242',
5822
- validations: ['required', 'validCardNumber'],
5823
- css: css,
5824
- });
5825
-
5826
- form.field('#cc-expiry', {
5827
- type: 'card-expiration-date',
5828
- name: 'card_exp',
5829
- placeholder: 'MM / YY',
5830
- validations: ['required', 'validCardExpirationDate'],
5831
- css: css,
5832
- });
5833
-
5834
- form.field('#cc-cvc', {
5835
- type: 'card-security-code',
5836
- name: 'card_cvc',
5837
- placeholder: 'CVC',
5838
- validations: ['required', 'validCardSecurityCode'],
5839
- css: css,
5840
- });
5841
-
5842
- form.field('#cc-name', {
5843
- type: 'text',
5844
- name: 'card_name',
5845
- placeholder: 'Name on card',
5846
- validations: ['required'],
5847
- css: css,
5848
- });
5849
-
5850
- // Enable submit when all fields are valid
5851
- let fieldStates = {};
5852
- form.on('change', function(state) {
5853
- fieldStates = state;
5854
- const allValid = Object.values(state).every(function(f) { return f.isValid; });
5855
- document.getElementById('submit-btn').disabled = !allValid;
5856
- });
5857
-
5858
- document.getElementById('card-form').addEventListener('submit', function(e) {
5859
- e.preventDefault();
5860
- var btn = document.getElementById('submit-btn');
5861
- btn.disabled = true;
5862
- btn.textContent = 'Processing...';
5863
- document.getElementById('error-msg').style.display = 'none';
5864
-
5865
- form.submit(
5866
- '/post',
5867
- {
5868
- headers: { 'Content-Type': 'application/json' },
5869
- data: function(fields) {
5870
- return {
5871
- card_number: fields.card_number,
5872
- card_exp: fields.card_exp,
5873
- card_cvc: fields.card_cvc,
5874
- card_name: fields.card_name,
5875
- developer_id: '${config.developerId}',
5876
- };
5877
- },
5878
- },
5879
- function(status, data) {
5880
- if (status >= 200 && status < 300) {
5881
- document.getElementById('form-view').style.display = 'none';
5882
- document.getElementById('success-view').style.display = 'block';
5883
- // Notify callback
5884
- fetch('${config.callbackUrl}', {
5885
- method: 'POST',
5886
- headers: { 'Content-Type': 'application/json' },
5887
- body: JSON.stringify({
5888
- alias: data.card_number,
5889
- last4: data.last4 || 'xxxx',
5890
- brand: data.brand || 'unknown',
5891
- }),
5892
- });
5893
- } else {
5894
- var errEl = document.getElementById('error-msg');
5895
- errEl.textContent = 'Card could not be saved. Please check your details and try again.';
5896
- errEl.style.display = 'block';
5897
- btn.disabled = false;
5898
- btn.textContent = 'Add Card';
5899
- }
5900
- },
5901
- function(errors) {
5902
- var errEl = document.getElementById('error-msg');
5903
- errEl.textContent = 'Validation failed. Please check all fields.';
5904
- errEl.style.display = 'block';
5905
- btn.disabled = false;
5906
- btn.textContent = 'Add Card';
5907
- }
5908
- );
5909
- });
5910
- </script>
5911
- </body>
5912
- </html>`;
5913
- }
5914
-
5915
- // src/psp/registry.ts
5916
- var PSPRegistry = class {
5917
- adapters = /* @__PURE__ */ new Map();
5918
- /**
5919
- * Register an adapter with a priority (lower = higher priority).
5920
- */
5921
- register(adapter, priority = 100) {
5922
- this.adapters.set(adapter.name, { adapter, priority });
5923
- }
5924
- /**
5925
- * Remove an adapter from the registry.
5926
- */
5927
- unregister(name) {
5928
- this.adapters.delete(name);
5929
- }
5930
- /**
5931
- * Get a specific adapter by name.
5932
- */
5933
- get(name) {
5934
- return this.adapters.get(name)?.adapter;
5935
- }
5936
- /**
5937
- * Get the highest-priority adapter (lowest priority number).
5938
- * Optionally exclude specific adapters (e.g., after a failure).
5939
- */
5940
- getPrimary(exclude) {
5941
- let best;
5942
- for (const [name, entry] of this.adapters) {
5943
- if (exclude?.has(name)) continue;
5944
- if (!best || entry.priority < best.priority) {
5945
- best = entry;
5946
- }
5947
- }
5948
- return best?.adapter;
5949
- }
5950
- /**
5951
- * Get all registered adapters sorted by priority.
5952
- */
5953
- getAll() {
5954
- return Array.from(this.adapters.values()).sort((a, b) => a.priority - b.priority).map((entry) => entry.adapter);
5955
- }
5956
- /**
5957
- * Run health checks on all adapters. Returns names of healthy adapters.
5958
- */
5959
- async healthCheckAll() {
5960
- const results = await Promise.allSettled(
5961
- Array.from(this.adapters.entries()).map(async ([name, { adapter }]) => {
5962
- const ok = await adapter.healthCheck();
5963
- return ok ? name : null;
5964
- })
5965
- );
5966
- return results.filter((r) => r.status === "fulfilled" && r.value !== null).map((r) => r.value);
5967
- }
5968
- };
5969
-
5970
- // src/psp/adapters/stripe.ts
5971
- var StripeAdapter = class {
5972
- name = "stripe";
5973
- config;
5974
- constructor(config) {
5975
- this.config = config;
5976
- }
5977
- async charge(params) {
5978
- const now = /* @__PURE__ */ new Date();
5979
- const expiryDate = new Date(params.expYear, params.expMonth);
5980
- if (expiryDate <= now) {
5981
- return {
5982
- pspTransactionId: "",
5983
- status: "failed",
5984
- declineReason: "Card has expired",
5985
- rawResponse: { error: "card_expired", expMonth: params.expMonth, expYear: params.expYear }
5986
- };
5987
- }
5988
- const body = {
5989
- amount: params.amount,
5990
- currency: params.currency.toLowerCase(),
5991
- source: {
5992
- object: "card",
5993
- number: params.cardAlias,
5994
- // VGS reveals this to Stripe
5995
- exp_month: params.expMonth,
5996
- exp_year: params.expYear,
5997
- cvc: params.cvvAlias
5998
- },
5999
- description: params.merchantDescriptor,
6000
- metadata: params.metadata ?? {}
6001
- };
6002
- const response = await this.config.proxy.forward({
6003
- url: "https://api.stripe.com/v1/charges",
6004
- method: "POST",
6005
- headers: {
6006
- "Authorization": `Bearer ${this.config.secretKey}`,
6007
- "Stripe-Version": this.config.apiVersion ?? "2024-12-18.acacia",
6008
- ...params.idempotencyKey ? { "Idempotency-Key": params.idempotencyKey } : {}
6009
- },
6010
- body
6011
- });
6012
- const data = response.body;
6013
- const status = data["status"] === "succeeded" ? "succeeded" : data["status"] === "pending" ? "pending" : "failed";
6014
- return {
6015
- pspTransactionId: String(data["id"] ?? ""),
6016
- status,
6017
- authorizationCode: data["authorization_code"],
6018
- declineReason: status === "failed" ? String(data["failure_message"] ?? "unknown") : void 0,
6019
- rawResponse: data
6020
- };
6021
- }
6022
- async refund(params) {
6023
- const body = {
6024
- charge: params.pspTransactionId,
6025
- ...params.amount !== void 0 ? { amount: params.amount } : {},
6026
- ...params.reason ? { reason: params.reason } : {}
6027
- };
6028
- const response = await this.config.proxy.forward({
6029
- url: "https://api.stripe.com/v1/refunds",
6030
- method: "POST",
6031
- headers: {
6032
- "Authorization": `Bearer ${this.config.secretKey}`,
6033
- "Stripe-Version": this.config.apiVersion ?? "2024-12-18.acacia",
6034
- ...params.idempotencyKey ? { "Idempotency-Key": params.idempotencyKey } : {}
6035
- },
6036
- body
6037
- });
6038
- const data = response.body;
6039
- const status = data["status"] === "succeeded" ? "succeeded" : data["status"] === "pending" ? "pending" : "failed";
6040
- return {
6041
- pspRefundId: String(data["id"] ?? ""),
6042
- status,
6043
- amount: Number(data["amount"] ?? 0),
6044
- rawResponse: data
6045
- };
6046
- }
6047
- async healthCheck() {
6048
- try {
6049
- const response = await fetch("https://api.stripe.com/v1/balance", {
6050
- headers: { "Authorization": `Bearer ${this.config.secretKey}` }
6051
- });
6052
- return response.ok;
6053
- } catch {
6054
- return false;
6055
- }
6056
- }
6057
- };
6058
-
6059
- // src/psp/adapters/worldpay.ts
6060
- var WorldpayAdapter = class {
6061
- name = "worldpay";
6062
- config;
6063
- constructor(config) {
6064
- this.config = config;
6065
- }
6066
- async charge(params) {
6067
- const now = /* @__PURE__ */ new Date();
6068
- const expiryDate = new Date(params.expYear, params.expMonth);
6069
- if (expiryDate <= now) {
6070
- return {
6071
- pspTransactionId: "",
6072
- status: "failed",
6073
- declineReason: "Card has expired",
6074
- rawResponse: { error: "card_expired", expMonth: params.expMonth, expYear: params.expYear }
6075
- };
6076
- }
6077
- const body = {
6078
- transactionType: "sale",
6079
- amount: {
6080
- value: params.amount,
6081
- currencyCode: params.currency.toUpperCase()
6082
- },
6083
- paymentInstrument: {
6084
- type: "card/plain",
6085
- cardNumber: params.cardAlias,
6086
- // VGS reveals to Worldpay
6087
- expiryDate: {
6088
- month: params.expMonth,
6089
- year: params.expYear
6090
- },
6091
- cvc: params.cvvAlias
6092
- },
6093
- merchant: {
6094
- entity: this.config.merchantId
6095
- },
6096
- narrative: {
6097
- line1: params.merchantDescriptor
6098
- }
6099
- };
6100
- const response = await this.config.proxy.forward({
6101
- url: `${this.config.baseUrl}/payments/authorizations`,
6102
- method: "POST",
6103
- headers: {
6104
- "Authorization": `Bearer ${this.config.apiKey}`,
6105
- ...params.idempotencyKey ? { "Idempotency-Key": params.idempotencyKey } : {}
6106
- },
6107
- body
6108
- });
6109
- const data = response.body;
6110
- const outcome = data["outcome"];
6111
- const status = outcome === "approved" ? "succeeded" : outcome === "pending" ? "pending" : "failed";
6112
- return {
6113
- pspTransactionId: String(data["_links"] && data["_links"]["self"] || ""),
6114
- status,
6115
- authorizationCode: data["authorizationCode"],
6116
- declineReason: status === "failed" ? String(data["description"] ?? "declined") : void 0,
6117
- rawResponse: data
6118
- };
6119
- }
6120
- async refund(params) {
6121
- const body = {
6122
- ...params.amount !== void 0 ? { value: { amount: params.amount, currencyCode: "USD" } } : {},
6123
- ...params.reason ? { reference: params.reason } : {}
6124
- };
6125
- const response = await this.config.proxy.forward({
6126
- url: `${this.config.baseUrl}/payments/${params.pspTransactionId}/refunds`,
6127
- method: "POST",
6128
- headers: {
6129
- "Authorization": `Bearer ${this.config.apiKey}`,
6130
- ...params.idempotencyKey ? { "Idempotency-Key": params.idempotencyKey } : {}
6131
- },
6132
- body
6133
- });
6134
- const data = response.body;
6135
- const outcome = data["outcome"];
6136
- const refundStatus = outcome === "failed" ? "failed" : outcome === "pending" ? "pending" : "succeeded";
6137
- return {
6138
- pspRefundId: String(data["refundId"] ?? ""),
6139
- status: refundStatus,
6140
- amount: params.amount ?? 0,
6141
- rawResponse: data
6142
- };
6143
- }
6144
- async healthCheck() {
6145
- try {
6146
- const response = await fetch(`${this.config.baseUrl}/health`, {
6147
- headers: { "Authorization": `Bearer ${this.config.apiKey}` }
6148
- });
6149
- return response.ok;
6150
- } catch {
6151
- return false;
6152
- }
6153
- }
6154
- };
6155
-
6156
- // src/psp/adapters/cybersource.ts
6157
- var CyberSourceAdapter = class {
6158
- name = "cybersource";
6159
- config;
6160
- constructor(config) {
6161
- this.config = config;
6162
- }
6163
- async charge(params) {
6164
- const now = /* @__PURE__ */ new Date();
6165
- const expiryDate = new Date(params.expYear, params.expMonth);
6166
- if (expiryDate <= now) {
6167
- return {
6168
- pspTransactionId: "",
6169
- status: "failed",
6170
- declineReason: "Card has expired",
6171
- rawResponse: { error: "card_expired", expMonth: params.expMonth, expYear: params.expYear }
6172
- };
6173
- }
6174
- const csParams = params;
6175
- const paymentInformation = csParams.isNetworkToken ? {
6176
- tokenizedCard: {
6177
- number: params.cardAlias,
6178
- // VGS reveals to CyberSource
6179
- expirationMonth: String(params.expMonth).padStart(2, "0"),
6180
- expirationYear: String(params.expYear),
6181
- cryptogram: csParams.cryptogram,
6182
- type: "001"
6183
- // Visa network token
6184
- }
6185
- } : {
6186
- card: {
6187
- number: params.cardAlias,
6188
- // VGS reveals to CyberSource
6189
- expirationMonth: String(params.expMonth).padStart(2, "0"),
6190
- expirationYear: String(params.expYear),
6191
- securityCode: params.cvvAlias
6192
- }
6193
- };
6194
- const body = {
6195
- clientReferenceInformation: {
6196
- code: params.idempotencyKey ?? `lane_${Date.now()}_${Math.random().toString(36).slice(2, 10)}`
6197
- },
6198
- processingInformation: {
6199
- capture: true,
6200
- ...csParams.isNetworkToken ? { paymentSolution: "015" } : {},
6201
- ...csParams.eci ? { commerceIndicator: csParams.eci } : {}
6202
- },
6203
- orderInformation: {
6204
- amountDetails: {
6205
- totalAmount: (params.amount / 100).toFixed(2),
6206
- currency: params.currency.toUpperCase()
6207
- }
6208
- },
6209
- paymentInformation
6210
- };
6211
- const response = await this.config.proxy.forward({
6212
- url: `${this.config.baseUrl}/pts/v2/payments`,
6213
- method: "POST",
6214
- headers: {
6215
- "v-c-merchant-id": this.config.merchantId,
6216
- "Content-Type": "application/json"
6217
- },
6218
- body
6219
- });
6220
- const data = response.body;
6221
- const csStatus = data["status"];
6222
- const status = csStatus === "AUTHORIZED" || csStatus === "PENDING" ? csStatus === "AUTHORIZED" ? "succeeded" : "pending" : "failed";
6223
- return {
6224
- pspTransactionId: String(data["id"] ?? ""),
6225
- status,
6226
- authorizationCode: data["processorInformation"]?.["approvalCode"],
6227
- declineReason: status === "failed" ? String(data["errorInformation"]?.["message"] ?? "declined") : void 0,
6228
- rawResponse: data
6229
- };
6230
- }
6231
- async refund(params) {
6232
- const body = {
6233
- clientReferenceInformation: {
6234
- code: params.idempotencyKey ?? `lane_ref_${Date.now()}_${Math.random().toString(36).slice(2, 10)}`
6235
- },
6236
- orderInformation: {
6237
- amountDetails: {
6238
- ...params.amount !== void 0 ? { totalAmount: (params.amount / 100).toFixed(2) } : {},
6239
- currency: "USD"
6240
- }
6241
- }
6242
- };
6243
- const response = await this.config.proxy.forward({
6244
- url: `${this.config.baseUrl}/pts/v2/payments/${params.pspTransactionId}/refunds`,
6245
- method: "POST",
6246
- headers: {
6247
- "v-c-merchant-id": this.config.merchantId,
6248
- "Content-Type": "application/json"
6249
- },
6250
- body
6251
- });
6252
- const data = response.body;
6253
- const csStatus = data["status"];
6254
- return {
6255
- pspRefundId: String(data["id"] ?? ""),
6256
- status: csStatus === "PENDING" ? "pending" : "succeeded",
6257
- amount: params.amount ?? 0,
6258
- rawResponse: data
6259
- };
6260
- }
6261
- async healthCheck() {
6262
- try {
6263
- const response = await fetch(`${this.config.baseUrl}/reporting/v3/report-definitions`, {
6264
- headers: { "v-c-merchant-id": this.config.merchantId }
6265
- });
6266
- return response.status !== 500;
6267
- } catch {
6268
- return false;
6269
- }
6270
- }
6271
- };
6272
-
6273
5508
  // src/merchants/billing-api-directory.ts
6274
5509
  var BILLING_API_MERCHANTS = Object.freeze([
6275
5510
  {
@@ -6309,158 +5544,8 @@ new Map(
6309
5544
  ...m.aliases.map((a) => [a.toLowerCase(), m])
6310
5545
  ])
6311
5546
  );
6312
- function toBillingAPICapabilities() {
6313
- return BILLING_API_MERCHANTS.map((m) => ({
6314
- merchantId: m.domain,
6315
- hasBillingAPI: true,
6316
- supportsACP: false,
6317
- supportsUCP: false,
6318
- supportsX402: false,
6319
- supportsVIC: true,
6320
- supportsRye: false,
6321
- acceptsVisa: true,
6322
- acceptsMastercard: true,
6323
- mccs: m.mccs
6324
- }));
6325
- }
6326
-
6327
- // src/routing/engine.ts
6328
- var MerchantRegistry = class _MerchantRegistry {
6329
- merchants = /* @__PURE__ */ new Map();
6330
- register(capabilities) {
6331
- this.merchants.set(capabilities.merchantId, capabilities);
6332
- }
6333
- get(merchantId) {
6334
- return this.merchants.get(merchantId);
6335
- }
6336
- registerBatch(merchants) {
6337
- for (const m of merchants) {
6338
- this.merchants.set(m.merchantId, m);
6339
- }
6340
- }
6341
- /** Create a registry pre-populated from directory capabilities. */
6342
- static fromDirectory(capabilities) {
6343
- const registry = new _MerchantRegistry();
6344
- registry.registerBatch(capabilities);
6345
- return registry;
6346
- }
6347
- /** Clear and repopulate with new capabilities. */
6348
- reload(capabilities) {
6349
- this.merchants.clear();
6350
- this.registerBatch(capabilities);
6351
- }
6352
- /** Number of registered merchants. */
6353
- get size() {
6354
- return this.merchants.size;
6355
- }
6356
- /** List all registered merchant IDs. */
6357
- listIds() {
6358
- return Array.from(this.merchants.keys());
6359
- }
6360
- /**
6361
- * Create a registry pre-seeded with the built-in UCP merchant directory.
6362
- *
6363
- * These merchants have verified `/.well-known/ucp` endpoints, so the
6364
- * routing engine can immediately route to Tier 3 (UCP) without a server
6365
- * round-trip for discovery. Additional merchants from the Lane backend
6366
- * can be merged in later via `register()` or `registerBatch()`.
6367
- */
6368
- static withUCPDirectory() {
6369
- return _MerchantRegistry.fromDirectory(toMerchantCapabilities());
6370
- }
6371
- /**
6372
- * Create a registry pre-seeded with ALL built-in merchant directories:
6373
- * - Billing API merchants (Tier 1) — SaaS/API merchants with direct endpoints
6374
- * - UCP merchants (Tier 3) — ecommerce merchants with /.well-known/ucp
6375
- *
6376
- * This gives agents instant routing for known merchants without any server
6377
- * round-trip. Use this for the best out-of-the-box experience.
6378
- */
6379
- static withBuiltinDirectory() {
6380
- return _MerchantRegistry.fromDirectory([
6381
- ...toBillingAPICapabilities(),
6382
- ...toMerchantCapabilities()
6383
- ]);
6384
- }
6385
- };
6386
- var PaymentRouter = class {
6387
- constructor(registry) {
6388
- this.registry = registry;
6389
- }
6390
- /**
6391
- * Decide the payment route for a transaction.
6392
- */
6393
- route(context) {
6394
- const merchant = this.registry.get(context.merchantId);
6395
- const fallbacks = [];
6396
- if (context.budget && context.currentSpend !== void 0) {
6397
- const limit = context.budget.perTaskLimit ?? context.budget.dailyLimit;
6398
- if (limit !== void 0 && context.amount > limit - context.currentSpend) {
6399
- return {
6400
- route: "fallback",
6401
- merchantId: context.merchantId,
6402
- reason: "Transaction would exceed budget limits.",
6403
- fallbacks: []
6404
- };
6405
- }
6406
- }
6407
- if (merchant?.hasBillingAPI) {
6408
- fallbacks.push("acp", "ucp", "x402", "fallback");
6409
- return {
6410
- route: "billing_api",
6411
- merchantId: context.merchantId,
6412
- reason: "Merchant has direct billing API integration (cheapest path).",
6413
- fallbacks: this.filterFallbacks(fallbacks, merchant)
6414
- };
6415
- }
6416
- if (merchant?.supportsACP) {
6417
- fallbacks.push("ucp", "x402", "fallback");
6418
- return {
6419
- route: "acp",
6420
- merchantId: context.merchantId,
6421
- reason: "Merchant supports Agent Commerce Protocol checkout.",
6422
- fallbacks: this.filterFallbacks(fallbacks, merchant)
6423
- };
6424
- }
6425
- if (merchant?.supportsUCP) {
6426
- fallbacks.push("x402", "fallback");
6427
- return {
6428
- route: "ucp",
6429
- merchantId: context.merchantId,
6430
- reason: "Merchant supports Universal Checkout Protocol.",
6431
- fallbacks: this.filterFallbacks(fallbacks, merchant)
6432
- };
6433
- }
6434
- if (merchant?.supportsX402) {
6435
- fallbacks.push("fallback");
6436
- return {
6437
- route: "x402",
6438
- merchantId: context.merchantId,
6439
- reason: "Merchant supports x402 HTTP payment protocol.",
6440
- fallbacks
6441
- };
6442
- }
6443
- const fallbackStrategies = ["rye", "browser_use", "vgs_proxy"];
6444
- return {
6445
- route: "fallback",
6446
- merchantId: context.merchantId,
6447
- reason: merchant ? "No preferred protocol available; using fallback strategies (Rye \u2192 browser use \u2192 VGS proxy)." : "Unknown merchant; using fallback strategies (Rye \u2192 browser use \u2192 VGS proxy).",
6448
- fallbacks: fallbackStrategies
6449
- };
6450
- }
6451
- filterFallbacks(routes, merchant) {
6452
- return routes.filter((r) => {
6453
- if (r === "acp") return merchant.supportsACP;
6454
- if (r === "ucp") return merchant.supportsUCP;
6455
- if (r === "x402") return merchant.supportsX402;
6456
- return true;
6457
- });
6458
- }
6459
- };
6460
5547
 
6461
5548
  // src/index.ts
6462
5549
  var index_default = Lane;
6463
5550
 
6464
- export { Admin, Agents, Audit, Auth, BiometricVerifier, Budgets, Cards, Checkout, Commerce, CommerceCatalog, CommerceOrders, CommerceProviders, CyberSourceAdapter, FileTokenStore, Fleet, HMACSignature, Identity, Instructions, Lane, LaneAuthError, LaneBudgetError, LaneClient, LaneConfirmationError, LaneError, LaneMCPServer, LaneNotFoundError, LanePaymentError, LaneRateLimitError, LaneValidationError, MerchantRegistry, Merchants, Metering, PSPRegistry, Pay, PaymentRouter, Payouts, Products, Resource, Sell, StripeAdapter, Subscriptions, Teams, Tokens, Transactions, Users, VGSOutboundProxy, VGSTokenManager, VIC, Wallets, Webhooks, WorldpayAdapter, createErrorFromResponse, index_default as default, detectCardBrand, generateCollectPage, getLaneInstructions, listUCPByVertical, listUCPMerchants, luhnCheck, maskCardNumber, requireBiometricConfirmation, resolveConfig, resolveUCPByBrand, resolveUCPByDomain, toUCPEndpoint, toMerchantCapabilities as toUCPMerchantCapabilities, verifyWebhookSignature };
6465
- //# sourceMappingURL=index.js.map
6466
- //# sourceMappingURL=index.js.map
5551
+ export { Admin, Agents, Audit, Auth, BiometricVerifier, Budgets, Cards, Checkout, Commerce, CommerceCatalog, CommerceOrders, CommerceProviders, FileTokenStore, Fleet, HMACSignature, Identity, Instructions, Lane, LaneAuthError, LaneBudgetError, LaneClient, LaneConfirmationError, LaneError, LaneMCPServer, LaneNotFoundError, LanePaymentError, LaneRateLimitError, LaneValidationError, Merchants, Metering, Pay, Payouts, Products, Resource, Sell, Subscriptions, Teams, Tokens, Transactions, Users, VIC, Wallets, Webhooks, createErrorFromResponse, index_default as default, detectCardBrand, getLaneInstructions, listUCPByVertical, listUCPMerchants, luhnCheck, maskCardNumber, requireBiometricConfirmation, resolveConfig, resolveUCPByBrand, resolveUCPByDomain, toUCPEndpoint, toMerchantCapabilities as toUCPMerchantCapabilities, verifyWebhookSignature };