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