@nevermined-io/payments 1.1.18 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/README.md +5 -3
  2. package/dist/a2a/clientRegistry.d.ts.map +1 -1
  3. package/dist/a2a/clientRegistry.js +2 -2
  4. package/dist/a2a/clientRegistry.js.map +1 -1
  5. package/dist/a2a/paymentsClient.d.ts +2 -2
  6. package/dist/a2a/paymentsClient.d.ts.map +1 -1
  7. package/dist/a2a/paymentsClient.js +10 -6
  8. package/dist/a2a/paymentsClient.js.map +1 -1
  9. package/dist/a2a/server.d.ts.map +1 -1
  10. package/dist/a2a/server.js +3 -1
  11. package/dist/a2a/server.js.map +1 -1
  12. package/dist/a2a/types.d.ts +1 -0
  13. package/dist/a2a/types.d.ts.map +1 -1
  14. package/dist/a2a/types.js.map +1 -1
  15. package/dist/api/base-payments.d.ts.map +1 -1
  16. package/dist/api/base-payments.js +12 -10
  17. package/dist/api/base-payments.js.map +1 -1
  18. package/dist/api/nvm-api.d.ts +0 -1
  19. package/dist/api/nvm-api.d.ts.map +1 -1
  20. package/dist/api/nvm-api.js +0 -1
  21. package/dist/api/nvm-api.js.map +1 -1
  22. package/dist/api/plans-api.d.ts +21 -32
  23. package/dist/api/plans-api.d.ts.map +1 -1
  24. package/dist/api/plans-api.js +27 -49
  25. package/dist/api/plans-api.js.map +1 -1
  26. package/dist/common/types.d.ts +90 -19
  27. package/dist/common/types.d.ts.map +1 -1
  28. package/dist/common/types.js +16 -0
  29. package/dist/common/types.js.map +1 -1
  30. package/dist/environments.d.ts +0 -7
  31. package/dist/environments.d.ts.map +1 -1
  32. package/dist/environments.js +0 -13
  33. package/dist/environments.js.map +1 -1
  34. package/dist/index.d.ts +2 -5
  35. package/dist/index.d.ts.map +1 -1
  36. package/dist/index.js +1 -3
  37. package/dist/index.js.map +1 -1
  38. package/dist/mcp/http/session-manager.d.ts.map +1 -1
  39. package/dist/mcp/http/session-manager.js +15 -1
  40. package/dist/mcp/http/session-manager.js.map +1 -1
  41. package/dist/payments.d.ts +17 -1
  42. package/dist/payments.d.ts.map +1 -1
  43. package/dist/payments.js +2 -10
  44. package/dist/payments.js.map +1 -1
  45. package/dist/plans.d.ts +14 -3
  46. package/dist/plans.d.ts.map +1 -1
  47. package/dist/plans.js +25 -8
  48. package/dist/plans.js.map +1 -1
  49. package/dist/x402/delegation-api.d.ts +119 -19
  50. package/dist/x402/delegation-api.d.ts.map +1 -1
  51. package/dist/x402/delegation-api.js +77 -23
  52. package/dist/x402/delegation-api.js.map +1 -1
  53. package/dist/x402/express/middleware.d.ts +4 -0
  54. package/dist/x402/express/middleware.d.ts.map +1 -1
  55. package/dist/x402/express/middleware.js +7 -4
  56. package/dist/x402/express/middleware.js.map +1 -1
  57. package/dist/x402/facilitator-api.d.ts +13 -5
  58. package/dist/x402/facilitator-api.d.ts.map +1 -1
  59. package/dist/x402/facilitator-api.js +41 -15
  60. package/dist/x402/facilitator-api.js.map +1 -1
  61. package/dist/x402/index.d.ts +3 -7
  62. package/dist/x402/index.d.ts.map +1 -1
  63. package/dist/x402/index.js +2 -5
  64. package/dist/x402/index.js.map +1 -1
  65. package/dist/x402/token.d.ts +17 -17
  66. package/dist/x402/token.d.ts.map +1 -1
  67. package/dist/x402/token.js +27 -37
  68. package/dist/x402/token.js.map +1 -1
  69. package/package.json +23 -21
  70. package/dist/x402/visa-facilitator-api.d.ts +0 -150
  71. package/dist/x402/visa-facilitator-api.d.ts.map +0 -1
  72. package/dist/x402/visa-facilitator-api.js +0 -206
  73. package/dist/x402/visa-facilitator-api.js.map +0 -1
  74. package/dist/x402/visa-token-api.d.ts +0 -60
  75. package/dist/x402/visa-token-api.d.ts.map +0 -1
  76. package/dist/x402/visa-token-api.js +0 -99
  77. package/dist/x402/visa-token-api.js.map +0 -1
@@ -25,41 +25,47 @@ export class X402TokenAPI extends BasePaymentsAPI {
25
25
  return new X402TokenAPI(options);
26
26
  }
27
27
  /**
28
- * Create a permission and get an X402 access token for the given plan.
28
+ * Create a delegation and get an X402 access token for the given plan.
29
29
  *
30
- * This token allows the agent to verify and settle permissions on behalf
31
- * of the subscriber. The token contains cryptographically signed session keys
32
- * that delegate specific permissions (order, burn) to the agent.
30
+ * This token allows the agent to verify and settle delegations on behalf
31
+ * of the subscriber.
32
+ *
33
+ * For erc4337 scheme, you must pass `tokenOptions.delegationConfig` with either:
34
+ * - `delegationId` to reuse an existing delegation, or
35
+ * - `spendingLimitCents` + `durationSecs` to auto-create a new one.
33
36
  *
34
37
  * @param planId - The unique identifier of the payment plan
35
- * @param agentId - The unique identifier of the AI agent (optional). If provided, permissions are restricted to that specific agent.
36
- * @param redemptionLimit - Maximum number of interactions/redemptions allowed (optional)
37
- * @param orderLimit - Maximum spend limit in token units (wei) for ordering (optional)
38
- * @param expiration - Expiration date in ISO 8601 format, e.g. "2025-02-01T10:00:00Z" (optional)
38
+ * @param agentId - The unique identifier of the AI agent (optional)
39
+ * @param tokenOptions - Options controlling scheme and delegation behavior (optional)
39
40
  * @returns A promise that resolves to an object containing:
40
41
  * - accessToken: The X402 access token string
41
- * - Additional metadata about the token
42
42
  *
43
43
  * @throws PaymentsError if the request fails
44
44
  *
45
45
  * @example
46
46
  * ```typescript
47
- * import { Payments } from '@nevermined-io/payments'
48
- *
49
- * const payments = Payments.getInstance({
50
- * nvmApiKey: 'nvm:subscriber-key',
51
- * environment: 'sandbox'
47
+ * // Pattern A auto-create delegation
48
+ * const result = await payments.x402.getX402AccessToken(planId, agentId, {
49
+ * delegationConfig: { spendingLimitCents: 10000, durationSecs: 604800 }
52
50
  * })
53
51
  *
54
- * const result = await payments.x402.getX402AccessToken(planId, agentId)
55
- * const token = result.accessToken
52
+ * // Pattern B reuse existing delegation
53
+ * const result = await payments.x402.getX402AccessToken(planId, agentId, {
54
+ * delegationConfig: { delegationId: 'existing-delegation-uuid' }
55
+ * })
56
56
  * ```
57
57
  */
58
- async getX402AccessToken(planId, agentId, redemptionLimit, orderLimit, expiration, tokenOptions) {
58
+ async getX402AccessToken(planId, agentId, tokenOptions) {
59
59
  const urlPath = API_URL_CREATE_PERMISSION;
60
60
  const url = new URL(urlPath, this.environment.backend);
61
61
  const scheme = tokenOptions?.scheme ?? 'nvm:erc4337';
62
62
  const network = tokenOptions?.network ?? getDefaultNetwork(scheme, this.environmentName);
63
+ // Validate delegationConfig is provided — the backend requires it for token generation
64
+ if (!tokenOptions?.delegationConfig) {
65
+ throw PaymentsError.validation(`delegationConfig is required for ${scheme} token generation. ` +
66
+ 'Provide delegationConfig.delegationId to reuse an existing delegation, ' +
67
+ 'or delegationConfig.spendingLimitCents + durationSecs to auto-create one.');
68
+ }
63
69
  // Build x402-aligned request body
64
70
  const body = {
65
71
  accepted: {
@@ -71,31 +77,15 @@ export class X402TokenAPI extends BasePaymentsAPI {
71
77
  },
72
78
  },
73
79
  };
74
- // Add delegation config for card-delegation scheme
75
- if (scheme === 'nvm:card-delegation' && tokenOptions?.delegationConfig) {
80
+ // Add delegation config for both erc4337 and card-delegation schemes
81
+ if (tokenOptions?.delegationConfig) {
76
82
  body.delegationConfig = tokenOptions.delegationConfig;
77
83
  }
78
- // Add session key config if any options are provided (erc4337 only)
79
- if (scheme === 'nvm:erc4337') {
80
- const sessionKeyConfig = {};
81
- if (redemptionLimit !== undefined) {
82
- sessionKeyConfig.redemptionLimit = redemptionLimit;
83
- }
84
- if (orderLimit !== undefined) {
85
- sessionKeyConfig.orderLimit = orderLimit;
86
- }
87
- if (expiration !== undefined) {
88
- sessionKeyConfig.expiration = expiration;
89
- }
90
- if (Object.keys(sessionKeyConfig).length > 0) {
91
- body.sessionKeyConfig = sessionKeyConfig;
92
- }
93
- }
94
84
  const options = this.getBackendHTTPOptions('POST', body);
95
85
  try {
96
86
  const response = await fetch(url, options);
97
87
  if (!response.ok) {
98
- let errorMessage = 'Failed to create X402 permission';
88
+ let errorMessage = 'Failed to create X402 delegation token';
99
89
  try {
100
90
  const errorData = await response.json();
101
91
  errorMessage = errorData.message || errorMessage;
@@ -111,7 +101,7 @@ export class X402TokenAPI extends BasePaymentsAPI {
111
101
  if (error instanceof PaymentsError) {
112
102
  throw error;
113
103
  }
114
- throw PaymentsError.internal(`Network error while creating X402 permission: ${error instanceof Error ? error.message : String(error)}`);
104
+ throw PaymentsError.internal(`Network error while creating X402 delegation token: ${error instanceof Error ? error.message : String(error)}`);
115
105
  }
116
106
  }
117
107
  }
@@ -1 +1 @@
1
- {"version":3,"file":"token.js","sourceRoot":"","sources":["../../src/x402/token.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * X402 Token Generation API.\n *\n * Provides X402 access token generation functionality for subscribers.\n * Tokens are used to authorize payment verification and settlement.\n */\n\nimport { BasePaymentsAPI } from '../api/base-payments.js'\nimport { API_URL_CREATE_PERMISSION } from '../api/nvm-api.js'\nimport { PaymentsError } from '../common/payments.error.js'\nimport { PaymentOptions, X402TokenOptions, getDefaultNetwork } from '../common/types.js'\n\n/**\n * X402 Token API for generating access tokens.\n *\n * Handles X402 access token generation for subscribers to authorize\n * payment operations with AI agents.\n */\nexport class X402TokenAPI extends BasePaymentsAPI {\n /**\n * Get a singleton instance of the X402TokenAPI class.\n *\n * @param options - The options to initialize the API\n * @returns The instance of the X402TokenAPI class\n */\n static getInstance(options: PaymentOptions): X402TokenAPI {\n return new X402TokenAPI(options)\n }\n\n /**\n * Create a permission and get an X402 access token for the given plan.\n *\n * This token allows the agent to verify and settle permissions on behalf\n * of the subscriber. The token contains cryptographically signed session keys\n * that delegate specific permissions (order, burn) to the agent.\n *\n * @param planId - The unique identifier of the payment plan\n * @param agentId - The unique identifier of the AI agent (optional). If provided, permissions are restricted to that specific agent.\n * @param redemptionLimit - Maximum number of interactions/redemptions allowed (optional)\n * @param orderLimit - Maximum spend limit in token units (wei) for ordering (optional)\n * @param expiration - Expiration date in ISO 8601 format, e.g. \"2025-02-01T10:00:00Z\" (optional)\n * @returns A promise that resolves to an object containing:\n * - accessToken: The X402 access token string\n * - Additional metadata about the token\n *\n * @throws PaymentsError if the request fails\n *\n * @example\n * ```typescript\n * import { Payments } from '@nevermined-io/payments'\n *\n * const payments = Payments.getInstance({\n * nvmApiKey: 'nvm:subscriber-key',\n * environment: 'sandbox'\n * })\n *\n * const result = await payments.x402.getX402AccessToken(planId, agentId)\n * const token = result.accessToken\n * ```\n */\n async getX402AccessToken(\n planId: string,\n agentId?: string,\n redemptionLimit?: number,\n orderLimit?: string,\n expiration?: string,\n tokenOptions?: X402TokenOptions,\n ): Promise<{ accessToken: string;[key: string]: any }> {\n const urlPath = API_URL_CREATE_PERMISSION\n const url = new URL(urlPath, this.environment.backend)\n\n const scheme = tokenOptions?.scheme ?? 'nvm:erc4337'\n const network = tokenOptions?.network ?? getDefaultNetwork(scheme, this.environmentName)\n\n // Build x402-aligned request body\n const body: Record<string, any> = {\n accepted: {\n scheme,\n network,\n planId,\n extra: {\n ...(agentId && { agentId }),\n },\n },\n }\n\n // Add delegation config for card-delegation scheme\n if (scheme === 'nvm:card-delegation' && tokenOptions?.delegationConfig) {\n body.delegationConfig = tokenOptions.delegationConfig\n }\n\n // Add session key config if any options are provided (erc4337 only)\n if (scheme === 'nvm:erc4337') {\n const sessionKeyConfig: Record<string, any> = {}\n if (redemptionLimit !== undefined) {\n sessionKeyConfig.redemptionLimit = redemptionLimit\n }\n if (orderLimit !== undefined) {\n sessionKeyConfig.orderLimit = orderLimit\n }\n if (expiration !== undefined) {\n sessionKeyConfig.expiration = expiration\n }\n if (Object.keys(sessionKeyConfig).length > 0) {\n body.sessionKeyConfig = sessionKeyConfig\n }\n }\n\n const options = this.getBackendHTTPOptions('POST', body)\n\n try {\n const response = await fetch(url, options)\n if (!response.ok) {\n let errorMessage = 'Failed to create X402 permission'\n try {\n const errorData = await response.json()\n errorMessage = errorData.message || errorMessage\n } catch {\n // Use default error message\n }\n throw PaymentsError.internal(`${errorMessage} (HTTP ${response.status})`)\n }\n return await response.json()\n } catch (error) {\n if (error instanceof PaymentsError) {\n throw error\n }\n throw PaymentsError.internal(\n `Network error while creating X402 permission: ${error instanceof Error ? error.message : String(error)}`,\n )\n }\n }\n}\n"]}
1
+ {"version":3,"file":"token.js","sourceRoot":"","sources":["../../src/x402/token.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AACzD,OAAO,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAA;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAA;AAC3D,OAAO,EAAoC,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AAExF;;;;;GAKG;AACH,MAAM,OAAO,YAAa,SAAQ,eAAe;IAC/C;;;;;OAKG;IACH,MAAM,CAAC,WAAW,CAAC,OAAuB;QACxC,OAAO,IAAI,YAAY,CAAC,OAAO,CAAC,CAAA;IAClC,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA8BG;IACH,KAAK,CAAC,kBAAkB,CACtB,MAAc,EACd,OAAgB,EAChB,YAA+B;QAE/B,MAAM,OAAO,GAAG,yBAAyB,CAAA;QACzC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAA;QAEtD,MAAM,MAAM,GAAG,YAAY,EAAE,MAAM,IAAI,aAAa,CAAA;QACpD,MAAM,OAAO,GAAG,YAAY,EAAE,OAAO,IAAI,iBAAiB,CAAC,MAAM,EAAE,IAAI,CAAC,eAAe,CAAC,CAAA;QAExF,uFAAuF;QACvF,IAAI,CAAC,YAAY,EAAE,gBAAgB,EAAE,CAAC;YACpC,MAAM,aAAa,CAAC,UAAU,CAC5B,oCAAoC,MAAM,qBAAqB;gBAC7D,yEAAyE;gBACzE,2EAA2E,CAC9E,CAAA;QACH,CAAC;QAED,kCAAkC;QAClC,MAAM,IAAI,GAAwB;YAChC,QAAQ,EAAE;gBACR,MAAM;gBACN,OAAO;gBACP,MAAM;gBACN,KAAK,EAAE;oBACL,GAAG,CAAC,OAAO,IAAI,EAAE,OAAO,EAAE,CAAC;iBAC5B;aACF;SACF,CAAA;QAED,qEAAqE;QACrE,IAAI,YAAY,EAAE,gBAAgB,EAAE,CAAC;YACnC,IAAI,CAAC,gBAAgB,GAAG,YAAY,CAAC,gBAAgB,CAAA;QACvD,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,qBAAqB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;QAExD,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;YAC1C,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,IAAI,YAAY,GAAG,wCAAwC,CAAA;gBAC3D,IAAI,CAAC;oBACH,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAA;oBACvC,YAAY,GAAG,SAAS,CAAC,OAAO,IAAI,YAAY,CAAA;gBAClD,CAAC;gBAAC,MAAM,CAAC;oBACP,4BAA4B;gBAC9B,CAAC;gBACD,MAAM,aAAa,CAAC,QAAQ,CAAC,GAAG,YAAY,UAAU,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAA;YAC3E,CAAC;YACD,OAAO,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAA;QAC9B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,aAAa,EAAE,CAAC;gBACnC,MAAM,KAAK,CAAA;YACb,CAAC;YACD,MAAM,aAAa,CAAC,QAAQ,CAC1B,uDAAuD,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAChH,CAAA;QACH,CAAC;IACH,CAAC;CACF","sourcesContent":["/**\n * X402 Token Generation API.\n *\n * Provides X402 access token generation functionality for subscribers.\n * Tokens are used to authorize payment verification and settlement.\n */\n\nimport { BasePaymentsAPI } from '../api/base-payments.js'\nimport { API_URL_CREATE_PERMISSION } from '../api/nvm-api.js'\nimport { PaymentsError } from '../common/payments.error.js'\nimport { PaymentOptions, X402TokenOptions, getDefaultNetwork } from '../common/types.js'\n\n/**\n * X402 Token API for generating access tokens.\n *\n * Handles X402 access token generation for subscribers to authorize\n * payment operations with AI agents.\n */\nexport class X402TokenAPI extends BasePaymentsAPI {\n /**\n * Get a singleton instance of the X402TokenAPI class.\n *\n * @param options - The options to initialize the API\n * @returns The instance of the X402TokenAPI class\n */\n static getInstance(options: PaymentOptions): X402TokenAPI {\n return new X402TokenAPI(options)\n }\n\n /**\n * Create a delegation and get an X402 access token for the given plan.\n *\n * This token allows the agent to verify and settle delegations on behalf\n * of the subscriber.\n *\n * For erc4337 scheme, you must pass `tokenOptions.delegationConfig` with either:\n * - `delegationId` to reuse an existing delegation, or\n * - `spendingLimitCents` + `durationSecs` to auto-create a new one.\n *\n * @param planId - The unique identifier of the payment plan\n * @param agentId - The unique identifier of the AI agent (optional)\n * @param tokenOptions - Options controlling scheme and delegation behavior (optional)\n * @returns A promise that resolves to an object containing:\n * - accessToken: The X402 access token string\n *\n * @throws PaymentsError if the request fails\n *\n * @example\n * ```typescript\n * // Pattern A auto-create delegation\n * const result = await payments.x402.getX402AccessToken(planId, agentId, {\n * delegationConfig: { spendingLimitCents: 10000, durationSecs: 604800 }\n * })\n *\n * // Pattern B — reuse existing delegation\n * const result = await payments.x402.getX402AccessToken(planId, agentId, {\n * delegationConfig: { delegationId: 'existing-delegation-uuid' }\n * })\n * ```\n */\n async getX402AccessToken(\n planId: string,\n agentId?: string,\n tokenOptions?: X402TokenOptions,\n ): Promise<{ accessToken: string; [key: string]: any }> {\n const urlPath = API_URL_CREATE_PERMISSION\n const url = new URL(urlPath, this.environment.backend)\n\n const scheme = tokenOptions?.scheme ?? 'nvm:erc4337'\n const network = tokenOptions?.network ?? getDefaultNetwork(scheme, this.environmentName)\n\n // Validate delegationConfig is provided — the backend requires it for token generation\n if (!tokenOptions?.delegationConfig) {\n throw PaymentsError.validation(\n `delegationConfig is required for ${scheme} token generation. ` +\n 'Provide delegationConfig.delegationId to reuse an existing delegation, ' +\n 'or delegationConfig.spendingLimitCents + durationSecs to auto-create one.',\n )\n }\n\n // Build x402-aligned request body\n const body: Record<string, any> = {\n accepted: {\n scheme,\n network,\n planId,\n extra: {\n ...(agentId && { agentId }),\n },\n },\n }\n\n // Add delegation config for both erc4337 and card-delegation schemes\n if (tokenOptions?.delegationConfig) {\n body.delegationConfig = tokenOptions.delegationConfig\n }\n\n const options = this.getBackendHTTPOptions('POST', body)\n\n try {\n const response = await fetch(url, options)\n if (!response.ok) {\n let errorMessage = 'Failed to create X402 delegation token'\n try {\n const errorData = await response.json()\n errorMessage = errorData.message || errorMessage\n } catch {\n // Use default error message\n }\n throw PaymentsError.internal(`${errorMessage} (HTTP ${response.status})`)\n }\n return await response.json()\n } catch (error) {\n if (error instanceof PaymentsError) {\n throw error\n }\n throw PaymentsError.internal(\n `Network error while creating X402 delegation token: ${error instanceof Error ? error.message : String(error)}`,\n )\n }\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nevermined-io/payments",
3
- "version": "1.1.18",
3
+ "version": "1.4.0",
4
4
  "description": "Typescript SDK to interact with the Nevermined Payments Protocol",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -40,22 +40,22 @@
40
40
  "scripts": {
41
41
  "clean": "rm -rf ./dist/ ./doc/ ./.nyc_output",
42
42
  "build": "tsc",
43
- "build:all": "yarn build && yarn cli:build",
43
+ "build:all": "pnpm build && pnpm cli:build",
44
44
  "lint": "eslint ./src",
45
45
  "test": "jest --verbose --config ./tests/jest.config.json",
46
46
  "test:unit": "jest --verbose --config ./tests/jest.config.json --testPathPattern=tests/unit",
47
47
  "test:integration": "jest --verbose --config ./tests/jest.config.json --testPathPattern=tests/integration",
48
- "test:e2e": "jest --verbose --config ./tests/jest.config.json --testPathPattern=tests/e2e --runInBand",
48
+ "test:e2e": "jest --verbose --config ./tests/jest.e2e.config.cjs --testPathPattern=tests/e2e --runInBand",
49
49
  "format": "prettier --check ./src",
50
- "prepublishOnly": "yarn build",
50
+ "prepublishOnly": "pnpm build",
51
51
  "doc": "typedoc --out docs ./src",
52
- "cli:build": "cd cli && yarn build",
53
- "cli:dev": "cd cli && yarn dev",
54
- "cli:test": "cd cli && yarn test",
55
- "cli:install": "cd cli && yarn install"
52
+ "cli:build": "cd cli && pnpm build",
53
+ "cli:dev": "cd cli && pnpm dev",
54
+ "cli:test": "cd cli && pnpm test",
55
+ "cli:install": "cd cli && pnpm install"
56
56
  },
57
57
  "devDependencies": {
58
- "@anthropic-ai/sdk": "^0.65.0",
58
+ "@anthropic-ai/sdk": "^0.91.1",
59
59
  "@aws-sdk/client-bedrock-runtime": "^3.972.0",
60
60
  "@babel/core": "^7.27.4",
61
61
  "@babel/preset-env": "^7.27.2",
@@ -76,19 +76,19 @@
76
76
  "eslint-config-nevermined": "^0.3.0",
77
77
  "eslint-config-next": "^15.1.5",
78
78
  "eslint-config-prettier": "^9.1.0",
79
- "eslint-plugin-tsdoc": "^0.2.17",
79
+ "eslint-plugin-tsdoc": "^0.5.2",
80
80
  "jest": "^29.7.0",
81
81
  "langchain": "^0.3.37",
82
82
  "openai": "^6.2.0",
83
83
  "prettier": "^3.2.5",
84
84
  "source-map-support": "^0.5.21",
85
85
  "supertest": "^7.1.4",
86
- "together-ai": "^0.22.0",
86
+ "together-ai": "^0.39.0",
87
87
  "ts-jest": "^29.2.5",
88
88
  "ts-node": "^10.9.2",
89
89
  "tsconfig-paths": "^4.2.0",
90
90
  "tslib": "^2.6.2",
91
- "typedoc": "0.25.13",
91
+ "typedoc": "0.28.19",
92
92
  "typescript": "^5.3.3"
93
93
  },
94
94
  "peerDependencies": {
@@ -111,8 +111,8 @@
111
111
  "@a2a-js/sdk": "^0.3.4",
112
112
  "@helicone/helpers": "^1.6.0",
113
113
  "@opentelemetry/api": "^1.9.0",
114
- "@opentelemetry/exporter-trace-otlp-http": "^0.203.0",
115
- "@traceloop/node-server-sdk": "^0.14.6",
114
+ "@opentelemetry/exporter-trace-otlp-http": "^0.215.0",
115
+ "@traceloop/node-server-sdk": "^0.26.0",
116
116
  "axios": "^1.13.1",
117
117
  "express": "4.21.2",
118
118
  "jose": "^5.2.4",
@@ -121,12 +121,14 @@
121
121
  "zod": "^4.0.17",
122
122
  "zod-to-json-schema": "^3.25.0"
123
123
  },
124
- "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e",
125
- "resolutions": {
126
- "qs": ">=6.14.1",
127
- "jws": ">=4.0.1",
128
- "js-yaml": ">=4.1.1",
129
- "@langchain/core": ">=0.3.80",
130
- "@smithy/config-resolver": ">=4.4.0"
124
+ "packageManager": "pnpm@10.33.0",
125
+ "pnpm": {
126
+ "overrides": {
127
+ "qs": ">=6.14.1",
128
+ "jws": ">=4.0.1",
129
+ "js-yaml": ">=4.1.1",
130
+ "@langchain/core": ">=0.3.80",
131
+ "@smithy/config-resolver": ">=4.4.0"
132
+ }
131
133
  }
132
134
  }
@@ -1,150 +0,0 @@
1
- /**
2
- * Visa Facilitator API — verifies and settles payments via the Visa x402 backend.
3
- *
4
- * Unlike the base FacilitatorAPI (which sends JSON bodies to the NVM backend),
5
- * the Visa flow uses the PAYMENT-SIGNATURE HTTP header to transport a base64-encoded
6
- * PaymentPayload to the Visa backend's /verify and /settle endpoints.
7
- *
8
- * @example
9
- * ```typescript
10
- * import { Payments } from '@nevermined-io/payments'
11
- *
12
- * const payments = Payments.getInstance({
13
- * nvmApiKey: 'your-nvm-api-key',
14
- * environment: 'sandbox',
15
- * scheme: 'visa',
16
- * })
17
- *
18
- * const paymentRequired = buildVisaPaymentRequired({
19
- * amount: '2.00',
20
- * asset: 'USD',
21
- * payTo: 'merchant-id',
22
- * endpoint: '/tools/random-article',
23
- * })
24
- *
25
- * // The PAYMENT-SIGNATURE header from the client request
26
- * const paymentSignature = req.headers['payment-signature'] as string
27
- *
28
- * const verification = await payments.facilitator.verifyPermissions({
29
- * paymentRequired,
30
- * x402AccessToken: paymentSignature,
31
- * })
32
- *
33
- * if (verification.isValid) {
34
- * const settlement = await payments.facilitator.settlePermissions({
35
- * paymentRequired,
36
- * x402AccessToken: paymentSignature,
37
- * })
38
- * }
39
- * ```
40
- */
41
- import { FacilitatorAPI } from './facilitator-api.js';
42
- import type { VerifyPermissionsParams, VerifyPermissionsResult, SettlePermissionsParams, SettlePermissionsResult, X402Resource } from './facilitator-api.js';
43
- import { PaymentOptions } from '../common/types.js';
44
- /**
45
- * Visa-specific extra fields in PaymentRequirements
46
- */
47
- export interface VisaPaymentExtra {
48
- /** Visa Token Service provisioned token ID */
49
- vProvisionedTokenID: string;
50
- /** VIC instruction ID from mandate creation */
51
- instructionId: string;
52
- /** Maximum number of times this payment can be used */
53
- maxUsage: number;
54
- /** Merchant name */
55
- merchantName?: string;
56
- /** Merchant URL */
57
- merchantUrl?: string;
58
- /** Merchant country code */
59
- merchantCountryCode?: string;
60
- }
61
- /**
62
- * Visa payment requirements (x402 v2 with scheme: "visa")
63
- */
64
- export interface VisaPaymentRequirements {
65
- scheme: 'visa';
66
- network: 'visa:vts';
67
- amount: string;
68
- asset: string;
69
- payTo: string;
70
- maxTimeoutSeconds: number;
71
- extra: VisaPaymentExtra;
72
- }
73
- /**
74
- * Visa-specific PaymentRequired response
75
- */
76
- export interface VisaPaymentRequired {
77
- x402Version: 2;
78
- error?: string;
79
- resource: X402Resource;
80
- accepts: VisaPaymentRequirements[];
81
- extensions?: Record<string, unknown>;
82
- }
83
- /**
84
- * Visa verify response
85
- */
86
- export interface VisaVerifyResponse {
87
- isValid: boolean;
88
- payer?: string;
89
- invalidReason?: string;
90
- remainingUsage?: number;
91
- }
92
- /**
93
- * Visa settlement response
94
- */
95
- export interface VisaSettlementResponse {
96
- success: boolean;
97
- transaction: string;
98
- network: 'visa:vts';
99
- payer?: string;
100
- errorReason?: string;
101
- }
102
- export declare const VISA_X402_HEADERS: {
103
- readonly PAYMENT_REQUIRED: "PAYMENT-REQUIRED";
104
- readonly PAYMENT_SIGNATURE: "PAYMENT-SIGNATURE";
105
- readonly PAYMENT_RESPONSE: "PAYMENT-RESPONSE";
106
- };
107
- /**
108
- * Build a Visa-flavored X402PaymentRequired object.
109
- *
110
- * This is the Visa counterpart of `buildPaymentRequired` (which builds NVM-flavored ones).
111
- */
112
- export declare function buildVisaPaymentRequired(options: {
113
- amount: string;
114
- asset?: string;
115
- payTo: string;
116
- endpoint?: string;
117
- description?: string;
118
- maxTimeoutSeconds?: number;
119
- merchantName?: string;
120
- merchantUrl?: string;
121
- merchantCountryCode?: string;
122
- }): VisaPaymentRequired;
123
- /**
124
- * Visa Facilitator API — sends PAYMENT-SIGNATURE header to the Visa backend
125
- * for verify and settle operations.
126
- */
127
- export declare class VisaFacilitatorAPI extends FacilitatorAPI {
128
- protected visaBackendUrl: string;
129
- constructor(options: PaymentOptions);
130
- static getInstance(options: PaymentOptions): VisaFacilitatorAPI;
131
- /**
132
- * Verify a Visa payment authorization.
133
- *
134
- * Sends the base64-encoded PaymentPayload as a PAYMENT-SIGNATURE header
135
- * to the Visa backend's POST /verify endpoint.
136
- *
137
- * @param params - contains x402AccessToken, the base64-encoded PaymentPayload from the client
138
- */
139
- verifyPermissions(params: VerifyPermissionsParams): Promise<VerifyPermissionsResult>;
140
- /**
141
- * Settle a Visa payment transaction.
142
- *
143
- * Sends the base64-encoded PaymentPayload as a PAYMENT-SIGNATURE header
144
- * to the Visa backend's POST /settle endpoint.
145
- *
146
- * @param params - contains x402AccessToken, the base64-encoded PaymentPayload from the client
147
- */
148
- settlePermissions(params: SettlePermissionsParams): Promise<SettlePermissionsResult>;
149
- }
150
- //# sourceMappingURL=visa-facilitator-api.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"visa-facilitator-api.d.ts","sourceRoot":"","sources":["../../src/x402/visa-facilitator-api.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AACrD,OAAO,KAAK,EACV,uBAAuB,EACvB,uBAAuB,EACvB,uBAAuB,EACvB,uBAAuB,EACvB,YAAY,EACb,MAAM,sBAAsB,CAAA;AAE7B,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AAOnD;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,8CAA8C;IAC9C,mBAAmB,EAAE,MAAM,CAAA;IAC3B,+CAA+C;IAC/C,aAAa,EAAE,MAAM,CAAA;IACrB,uDAAuD;IACvD,QAAQ,EAAE,MAAM,CAAA;IAChB,oBAAoB;IACpB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,mBAAmB;IACnB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,4BAA4B;IAC5B,mBAAmB,CAAC,EAAE,MAAM,CAAA;CAC7B;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,UAAU,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,iBAAiB,EAAE,MAAM,CAAA;IACzB,KAAK,EAAE,gBAAgB,CAAA;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,CAAC,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,YAAY,CAAA;IACtB,OAAO,EAAE,uBAAuB,EAAE,CAAA;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACrC;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,OAAO,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,UAAU,CAAA;IACnB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAMD,eAAO,MAAM,iBAAiB;;;;CAIpB,CAAA;AAMV;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE;IAChD,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,mBAAmB,CAAC,EAAE,MAAM,CAAA;CAC7B,GAAG,mBAAmB,CAsCtB;AAMD;;;GAGG;AACH,qBAAa,kBAAmB,SAAQ,cAAc;IACpD,SAAS,CAAC,cAAc,EAAE,MAAM,CAAA;gBAEpB,OAAO,EAAE,cAAc;WAKnB,WAAW,CAAC,OAAO,EAAE,cAAc,GAAG,kBAAkB;IAIxE;;;;;;;OAOG;IACY,iBAAiB,CAC9B,MAAM,EAAE,uBAAuB,GAC9B,OAAO,CAAC,uBAAuB,CAAC;IA6CnC;;;;;;;OAOG;IACY,iBAAiB,CAC9B,MAAM,EAAE,uBAAuB,GAC9B,OAAO,CAAC,uBAAuB,CAAC;CA8CpC"}
@@ -1,206 +0,0 @@
1
- /**
2
- * Visa Facilitator API — verifies and settles payments via the Visa x402 backend.
3
- *
4
- * Unlike the base FacilitatorAPI (which sends JSON bodies to the NVM backend),
5
- * the Visa flow uses the PAYMENT-SIGNATURE HTTP header to transport a base64-encoded
6
- * PaymentPayload to the Visa backend's /verify and /settle endpoints.
7
- *
8
- * @example
9
- * ```typescript
10
- * import { Payments } from '@nevermined-io/payments'
11
- *
12
- * const payments = Payments.getInstance({
13
- * nvmApiKey: 'your-nvm-api-key',
14
- * environment: 'sandbox',
15
- * scheme: 'visa',
16
- * })
17
- *
18
- * const paymentRequired = buildVisaPaymentRequired({
19
- * amount: '2.00',
20
- * asset: 'USD',
21
- * payTo: 'merchant-id',
22
- * endpoint: '/tools/random-article',
23
- * })
24
- *
25
- * // The PAYMENT-SIGNATURE header from the client request
26
- * const paymentSignature = req.headers['payment-signature'] as string
27
- *
28
- * const verification = await payments.facilitator.verifyPermissions({
29
- * paymentRequired,
30
- * x402AccessToken: paymentSignature,
31
- * })
32
- *
33
- * if (verification.isValid) {
34
- * const settlement = await payments.facilitator.settlePermissions({
35
- * paymentRequired,
36
- * x402AccessToken: paymentSignature,
37
- * })
38
- * }
39
- * ```
40
- */
41
- import { FacilitatorAPI } from './facilitator-api.js';
42
- import { PaymentsError } from '../common/payments.error.js';
43
- import { VisaBackendUrls } from '../environments.js';
44
- // ---------------------------------------------------------------------------
45
- // Visa x402 header names
46
- // ---------------------------------------------------------------------------
47
- export const VISA_X402_HEADERS = {
48
- PAYMENT_REQUIRED: 'PAYMENT-REQUIRED',
49
- PAYMENT_SIGNATURE: 'PAYMENT-SIGNATURE',
50
- PAYMENT_RESPONSE: 'PAYMENT-RESPONSE',
51
- };
52
- // ---------------------------------------------------------------------------
53
- // Helper: build a Visa PaymentRequired
54
- // ---------------------------------------------------------------------------
55
- /**
56
- * Build a Visa-flavored X402PaymentRequired object.
57
- *
58
- * This is the Visa counterpart of `buildPaymentRequired` (which builds NVM-flavored ones).
59
- */
60
- export function buildVisaPaymentRequired(options) {
61
- const { amount, asset = 'USD', payTo, endpoint = '', description, maxTimeoutSeconds = 3600, merchantName, merchantUrl, merchantCountryCode, } = options;
62
- return {
63
- x402Version: 2,
64
- resource: {
65
- url: endpoint,
66
- ...(description && { description }),
67
- },
68
- accepts: [
69
- {
70
- scheme: 'visa',
71
- network: 'visa:vts',
72
- amount,
73
- asset,
74
- payTo,
75
- maxTimeoutSeconds,
76
- extra: {
77
- vProvisionedTokenID: '',
78
- instructionId: '',
79
- maxUsage: 1,
80
- ...(merchantName && { merchantName }),
81
- ...(merchantUrl && { merchantUrl }),
82
- ...(merchantCountryCode && { merchantCountryCode }),
83
- },
84
- },
85
- ],
86
- };
87
- }
88
- // ---------------------------------------------------------------------------
89
- // VisaFacilitatorAPI
90
- // ---------------------------------------------------------------------------
91
- /**
92
- * Visa Facilitator API — sends PAYMENT-SIGNATURE header to the Visa backend
93
- * for verify and settle operations.
94
- */
95
- export class VisaFacilitatorAPI extends FacilitatorAPI {
96
- constructor(options) {
97
- super(options);
98
- this.visaBackendUrl = VisaBackendUrls[this.environmentName];
99
- }
100
- static getInstance(options) {
101
- return new VisaFacilitatorAPI(options);
102
- }
103
- /**
104
- * Verify a Visa payment authorization.
105
- *
106
- * Sends the base64-encoded PaymentPayload as a PAYMENT-SIGNATURE header
107
- * to the Visa backend's POST /verify endpoint.
108
- *
109
- * @param params - contains x402AccessToken, the base64-encoded PaymentPayload from the client
110
- */
111
- async verifyPermissions(params) {
112
- const { x402AccessToken } = params;
113
- const url = new URL('verify', this.visaBackendUrl);
114
- try {
115
- const response = await fetch(url, {
116
- method: 'POST',
117
- headers: {
118
- [VISA_X402_HEADERS.PAYMENT_SIGNATURE]: x402AccessToken,
119
- },
120
- });
121
- if (!response.ok) {
122
- let errorMessage = 'Visa payment verification failed';
123
- try {
124
- const errorData = await response.json();
125
- errorMessage = errorData.invalidReason || errorData.message || errorMessage;
126
- }
127
- catch {
128
- // Use default error message
129
- }
130
- throw PaymentsError.fromBackend(errorMessage, {
131
- message: errorMessage,
132
- code: `HTTP ${response.status}`,
133
- });
134
- }
135
- const visaResult = await response.json();
136
- // Map Visa response to the standard VerifyPermissionsResult shape
137
- return {
138
- isValid: visaResult.isValid,
139
- payer: visaResult.payer,
140
- invalidReason: visaResult.invalidReason,
141
- };
142
- }
143
- catch (error) {
144
- if (error instanceof PaymentsError) {
145
- throw error;
146
- }
147
- throw PaymentsError.fromBackend('Network error during Visa payment verification', {
148
- message: error instanceof Error ? error.message : String(error),
149
- code: 'network_error',
150
- });
151
- }
152
- }
153
- /**
154
- * Settle a Visa payment transaction.
155
- *
156
- * Sends the base64-encoded PaymentPayload as a PAYMENT-SIGNATURE header
157
- * to the Visa backend's POST /settle endpoint.
158
- *
159
- * @param params - contains x402AccessToken, the base64-encoded PaymentPayload from the client
160
- */
161
- async settlePermissions(params) {
162
- const { x402AccessToken } = params;
163
- const url = new URL('settle', this.visaBackendUrl);
164
- try {
165
- const response = await fetch(url, {
166
- method: 'POST',
167
- headers: {
168
- [VISA_X402_HEADERS.PAYMENT_SIGNATURE]: x402AccessToken,
169
- },
170
- });
171
- if (!response.ok) {
172
- let errorMessage = 'Visa payment settlement failed';
173
- try {
174
- const errorData = await response.json();
175
- errorMessage = errorData.errorReason || errorData.message || errorMessage;
176
- }
177
- catch {
178
- // Use default error message
179
- }
180
- throw PaymentsError.fromBackend(errorMessage, {
181
- message: errorMessage,
182
- code: `HTTP ${response.status}`,
183
- });
184
- }
185
- const visaResult = await response.json();
186
- // Map Visa response to the standard SettlePermissionsResult shape
187
- return {
188
- success: visaResult.success,
189
- transaction: visaResult.transaction,
190
- network: visaResult.network,
191
- payer: visaResult.payer,
192
- errorReason: visaResult.errorReason,
193
- };
194
- }
195
- catch (error) {
196
- if (error instanceof PaymentsError) {
197
- throw error;
198
- }
199
- throw PaymentsError.fromBackend('Network error during Visa payment settlement', {
200
- message: error instanceof Error ? error.message : String(error),
201
- code: 'network_error',
202
- });
203
- }
204
- }
205
- }
206
- //# sourceMappingURL=visa-facilitator-api.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"visa-facilitator-api.js","sourceRoot":"","sources":["../../src/x402/visa-facilitator-api.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Visa Facilitator API — verifies and settles payments via the Visa x402 backend.\n *\n * Unlike the base FacilitatorAPI (which sends JSON bodies to the NVM backend),\n * the Visa flow uses the PAYMENT-SIGNATURE HTTP header to transport a base64-encoded\n * PaymentPayload to the Visa backend's /verify and /settle endpoints.\n *\n * @example\n * ```typescript\n * import { Payments } from '@nevermined-io/payments'\n *\n * const payments = Payments.getInstance({\n * nvmApiKey: 'your-nvm-api-key',\n * environment: 'sandbox',\n * scheme: 'visa',\n * })\n *\n * const paymentRequired = buildVisaPaymentRequired({\n * amount: '2.00',\n * asset: 'USD',\n * payTo: 'merchant-id',\n * endpoint: '/tools/random-article',\n * })\n *\n * // The PAYMENT-SIGNATURE header from the client request\n * const paymentSignature = req.headers['payment-signature'] as string\n *\n * const verification = await payments.facilitator.verifyPermissions({\n * paymentRequired,\n * x402AccessToken: paymentSignature,\n * })\n *\n * if (verification.isValid) {\n * const settlement = await payments.facilitator.settlePermissions({\n * paymentRequired,\n * x402AccessToken: paymentSignature,\n * })\n * }\n * ```\n */\n\nimport { FacilitatorAPI } from './facilitator-api.js'\nimport type {\n VerifyPermissionsParams,\n VerifyPermissionsResult,\n SettlePermissionsParams,\n SettlePermissionsResult,\n X402Resource,\n} from './facilitator-api.js'\nimport { PaymentsError } from '../common/payments.error.js'\nimport { PaymentOptions } from '../common/types.js'\nimport { VisaBackendUrls } from '../environments.js'\n\n// ---------------------------------------------------------------------------\n// Visa-specific x402 types\n// ---------------------------------------------------------------------------\n\n/**\n * Visa-specific extra fields in PaymentRequirements\n */\nexport interface VisaPaymentExtra {\n /** Visa Token Service provisioned token ID */\n vProvisionedTokenID: string\n /** VIC instruction ID from mandate creation */\n instructionId: string\n /** Maximum number of times this payment can be used */\n maxUsage: number\n /** Merchant name */\n merchantName?: string\n /** Merchant URL */\n merchantUrl?: string\n /** Merchant country code */\n merchantCountryCode?: string\n}\n\n/**\n * Visa payment requirements (x402 v2 with scheme: \"visa\")\n */\nexport interface VisaPaymentRequirements {\n scheme: 'visa'\n network: 'visa:vts'\n amount: string\n asset: string\n payTo: string\n maxTimeoutSeconds: number\n extra: VisaPaymentExtra\n}\n\n/**\n * Visa-specific PaymentRequired response\n */\nexport interface VisaPaymentRequired {\n x402Version: 2\n error?: string\n resource: X402Resource\n accepts: VisaPaymentRequirements[]\n extensions?: Record<string, unknown>\n}\n\n/**\n * Visa verify response\n */\nexport interface VisaVerifyResponse {\n isValid: boolean\n payer?: string\n invalidReason?: string\n remainingUsage?: number\n}\n\n/**\n * Visa settlement response\n */\nexport interface VisaSettlementResponse {\n success: boolean\n transaction: string\n network: 'visa:vts'\n payer?: string\n errorReason?: string\n}\n\n// ---------------------------------------------------------------------------\n// Visa x402 header names\n// ---------------------------------------------------------------------------\n\nexport const VISA_X402_HEADERS = {\n PAYMENT_REQUIRED: 'PAYMENT-REQUIRED',\n PAYMENT_SIGNATURE: 'PAYMENT-SIGNATURE',\n PAYMENT_RESPONSE: 'PAYMENT-RESPONSE',\n} as const\n\n// ---------------------------------------------------------------------------\n// Helper: build a Visa PaymentRequired\n// ---------------------------------------------------------------------------\n\n/**\n * Build a Visa-flavored X402PaymentRequired object.\n *\n * This is the Visa counterpart of `buildPaymentRequired` (which builds NVM-flavored ones).\n */\nexport function buildVisaPaymentRequired(options: {\n amount: string\n asset?: string\n payTo: string\n endpoint?: string\n description?: string\n maxTimeoutSeconds?: number\n merchantName?: string\n merchantUrl?: string\n merchantCountryCode?: string\n}): VisaPaymentRequired {\n const {\n amount,\n asset = 'USD',\n payTo,\n endpoint = '',\n description,\n maxTimeoutSeconds = 3600,\n merchantName,\n merchantUrl,\n merchantCountryCode,\n } = options\n\n return {\n x402Version: 2,\n resource: {\n url: endpoint,\n ...(description && { description }),\n },\n accepts: [\n {\n scheme: 'visa',\n network: 'visa:vts',\n amount,\n asset,\n payTo,\n maxTimeoutSeconds,\n extra: {\n vProvisionedTokenID: '',\n instructionId: '',\n maxUsage: 1,\n ...(merchantName && { merchantName }),\n ...(merchantUrl && { merchantUrl }),\n ...(merchantCountryCode && { merchantCountryCode }),\n },\n },\n ],\n }\n}\n\n// ---------------------------------------------------------------------------\n// VisaFacilitatorAPI\n// ---------------------------------------------------------------------------\n\n/**\n * Visa Facilitator API — sends PAYMENT-SIGNATURE header to the Visa backend\n * for verify and settle operations.\n */\nexport class VisaFacilitatorAPI extends FacilitatorAPI {\n protected visaBackendUrl: string\n\n constructor(options: PaymentOptions) {\n super(options)\n this.visaBackendUrl = VisaBackendUrls[this.environmentName]\n }\n\n static override getInstance(options: PaymentOptions): VisaFacilitatorAPI {\n return new VisaFacilitatorAPI(options)\n }\n\n /**\n * Verify a Visa payment authorization.\n *\n * Sends the base64-encoded PaymentPayload as a PAYMENT-SIGNATURE header\n * to the Visa backend's POST /verify endpoint.\n *\n * @param params - contains x402AccessToken, the base64-encoded PaymentPayload from the client\n */\n override async verifyPermissions(\n params: VerifyPermissionsParams,\n ): Promise<VerifyPermissionsResult> {\n const { x402AccessToken } = params\n const url = new URL('verify', this.visaBackendUrl)\n\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n [VISA_X402_HEADERS.PAYMENT_SIGNATURE]: x402AccessToken,\n },\n })\n\n if (!response.ok) {\n let errorMessage = 'Visa payment verification failed'\n try {\n const errorData = await response.json()\n errorMessage = errorData.invalidReason || errorData.message || errorMessage\n } catch {\n // Use default error message\n }\n throw PaymentsError.fromBackend(errorMessage, {\n message: errorMessage,\n code: `HTTP ${response.status}`,\n })\n }\n\n const visaResult: VisaVerifyResponse = await response.json()\n\n // Map Visa response to the standard VerifyPermissionsResult shape\n return {\n isValid: visaResult.isValid,\n payer: visaResult.payer,\n invalidReason: visaResult.invalidReason,\n }\n } catch (error) {\n if (error instanceof PaymentsError) {\n throw error\n }\n throw PaymentsError.fromBackend('Network error during Visa payment verification', {\n message: error instanceof Error ? error.message : String(error),\n code: 'network_error',\n })\n }\n }\n\n /**\n * Settle a Visa payment transaction.\n *\n * Sends the base64-encoded PaymentPayload as a PAYMENT-SIGNATURE header\n * to the Visa backend's POST /settle endpoint.\n *\n * @param params - contains x402AccessToken, the base64-encoded PaymentPayload from the client\n */\n override async settlePermissions(\n params: SettlePermissionsParams,\n ): Promise<SettlePermissionsResult> {\n const { x402AccessToken } = params\n const url = new URL('settle', this.visaBackendUrl)\n\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n [VISA_X402_HEADERS.PAYMENT_SIGNATURE]: x402AccessToken,\n },\n })\n\n if (!response.ok) {\n let errorMessage = 'Visa payment settlement failed'\n try {\n const errorData = await response.json()\n errorMessage = errorData.errorReason || errorData.message || errorMessage\n } catch {\n // Use default error message\n }\n throw PaymentsError.fromBackend(errorMessage, {\n message: errorMessage,\n code: `HTTP ${response.status}`,\n })\n }\n\n const visaResult: VisaSettlementResponse = await response.json()\n\n // Map Visa response to the standard SettlePermissionsResult shape\n return {\n success: visaResult.success,\n transaction: visaResult.transaction,\n network: visaResult.network,\n payer: visaResult.payer,\n errorReason: visaResult.errorReason,\n }\n } catch (error) {\n if (error instanceof PaymentsError) {\n throw error\n }\n throw PaymentsError.fromBackend('Network error during Visa payment settlement', {\n message: error instanceof Error ? error.message : String(error),\n code: 'network_error',\n })\n }\n }\n}\n"]}