@nevermined-io/payments 1.0.9 → 1.0.16

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 (69) hide show
  1. package/README.md +7 -14
  2. package/dist/a2a/paymentsClient.d.ts +5 -3
  3. package/dist/a2a/paymentsClient.d.ts.map +1 -1
  4. package/dist/a2a/paymentsClient.js +20 -11
  5. package/dist/a2a/paymentsClient.js.map +1 -1
  6. package/dist/a2a/paymentsRequestHandler.d.ts.map +1 -1
  7. package/dist/a2a/paymentsRequestHandler.js +8 -3
  8. package/dist/a2a/paymentsRequestHandler.js.map +1 -1
  9. package/dist/a2a/server.d.ts.map +1 -1
  10. package/dist/a2a/server.js +48 -27
  11. package/dist/a2a/server.js.map +1 -1
  12. package/dist/a2a/types.d.ts +6 -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 +2 -1
  16. package/dist/api/base-payments.d.ts.map +1 -1
  17. package/dist/api/base-payments.js +11 -3
  18. package/dist/api/base-payments.js.map +1 -1
  19. package/dist/common/types.d.ts +53 -1
  20. package/dist/common/types.d.ts.map +1 -1
  21. package/dist/common/types.js +13 -0
  22. package/dist/common/types.js.map +1 -1
  23. package/dist/environments.d.ts +7 -0
  24. package/dist/environments.d.ts.map +1 -1
  25. package/dist/environments.js +13 -0
  26. package/dist/environments.js.map +1 -1
  27. package/dist/index.d.ts +6 -1
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +4 -1
  30. package/dist/index.js.map +1 -1
  31. package/dist/mcp/core/auth.d.ts.map +1 -1
  32. package/dist/mcp/core/auth.js +3 -0
  33. package/dist/mcp/core/auth.js.map +1 -1
  34. package/dist/mcp/core/paywall.d.ts.map +1 -1
  35. package/dist/mcp/core/paywall.js +13 -4
  36. package/dist/mcp/core/paywall.js.map +1 -1
  37. package/dist/payments.d.ts +7 -0
  38. package/dist/payments.d.ts.map +1 -1
  39. package/dist/payments.js +24 -2
  40. package/dist/payments.js.map +1 -1
  41. package/dist/x402/delegation-api.d.ts +43 -0
  42. package/dist/x402/delegation-api.d.ts.map +1 -0
  43. package/dist/x402/delegation-api.js +54 -0
  44. package/dist/x402/delegation-api.js.map +1 -0
  45. package/dist/x402/express/middleware.d.ts +4 -2
  46. package/dist/x402/express/middleware.d.ts.map +1 -1
  47. package/dist/x402/express/middleware.js +33 -21
  48. package/dist/x402/express/middleware.js.map +1 -1
  49. package/dist/x402/facilitator-api.d.ts +19 -5
  50. package/dist/x402/facilitator-api.d.ts.map +1 -1
  51. package/dist/x402/facilitator-api.js +39 -3
  52. package/dist/x402/facilitator-api.js.map +1 -1
  53. package/dist/x402/index.d.ts +9 -1
  54. package/dist/x402/index.d.ts.map +1 -1
  55. package/dist/x402/index.js +7 -1
  56. package/dist/x402/index.js.map +1 -1
  57. package/dist/x402/token.d.ts +2 -2
  58. package/dist/x402/token.d.ts.map +1 -1
  59. package/dist/x402/token.js +25 -16
  60. package/dist/x402/token.js.map +1 -1
  61. package/dist/x402/visa-facilitator-api.d.ts +150 -0
  62. package/dist/x402/visa-facilitator-api.d.ts.map +1 -0
  63. package/dist/x402/visa-facilitator-api.js +206 -0
  64. package/dist/x402/visa-facilitator-api.js.map +1 -0
  65. package/dist/x402/visa-token-api.d.ts +60 -0
  66. package/dist/x402/visa-token-api.d.ts.map +1 -0
  67. package/dist/x402/visa-token-api.js +99 -0
  68. package/dist/x402/visa-token-api.js.map +1 -0
  69. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"paywall.js","sourceRoot":"","sources":["../../../src/mcp/core/paywall.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Main paywall decorator for MCP handlers (tools, resources, prompts)\n */\nimport { Address } from '../../common/types.js'\nimport type { Payments } from '../../payments.js'\nimport {\n buildPaymentRequired,\n type SettlePermissionsResult,\n type X402PaymentRequired,\n} from '../../x402/facilitator-api.js'\nimport {\n McpConfig,\n PaywallOptions,\n PromptOptions,\n ResourceOptions,\n ToolOptions,\n} from '../types/paywall.types.js'\nimport { ERROR_CODES, createRpcError } from '../utils/errors.js'\nimport { PaywallAuthenticator } from './auth.js'\nimport { CreditsContextProvider } from './credits-context.js'\n\n/**\n * Main class for creating paywall-protected MCP handlers\n */\nexport class PaywallDecorator {\n // Internal config ensures serverName is always a concrete string\n private config: { agentId: string; serverName: string } = {\n agentId: '',\n serverName: 'mcp-server',\n }\n\n constructor(\n private payments: Payments,\n private authenticator: PaywallAuthenticator,\n private creditsContext: CreditsContextProvider,\n ) {}\n\n /**\n * Configure the paywall with agent and server information\n */\n configure(options: McpConfig): void {\n this.config = {\n agentId: options.agentId || this.config.agentId,\n serverName: options.serverName ?? this.config.serverName,\n }\n }\n\n /**\n * Create a paywall-protected handler (uncurried version only)\n */\n // Overloads per kind for stronger typing\n protect<TArgs = any>(\n handler: (args: TArgs, extra?: any) => Promise<any> | any,\n options: ToolOptions | PromptOptions,\n ): (args: TArgs, extra?: any) => Promise<any>\n protect(\n handler: (\n uri: URL,\n variables: Record<string, string | string[]>,\n extra?: any,\n ) => Promise<any> | any,\n options: ResourceOptions,\n ): (uri: URL, variables: Record<string, string | string[]>, extra?: any) => Promise<any>\n protect(handler: any, options: PaywallOptions): any {\n return this.createWrappedHandler(handler, options)\n }\n\n /**\n * Internal method to create the wrapped handler\n */\n private createWrappedHandler<TArgs = any>(\n handler: (args: TArgs, extra?: any) => Promise<any> | any,\n options: PaywallOptions,\n ): (...allArgs: any[]) => Promise<any> {\n return async (...allArgs: any[]): Promise<any> => {\n // Validate configuration\n if (!this.config.agentId) {\n throw createRpcError(\n ERROR_CODES.Misconfiguration,\n 'Server misconfiguration: missing agentId',\n )\n }\n\n const kind = options?.kind ?? 'tool'\n const name = options?.name ?? 'unnamed'\n\n // Detect resource signature: (url, variables, extra)\n const isResource = allArgs.length >= 2 && allArgs[0] instanceof URL\n const extra = isResource ? allArgs[2] : allArgs[1]\n const argsOrVars = isResource ? allArgs[1] : allArgs[0]\n\n // 1. Authenticate request\n const authResult = await this.authenticator.authenticate(\n extra,\n { planId: options?.planId, maxAmount: options?.maxAmount },\n this.config.agentId,\n this.config.serverName,\n name,\n kind,\n argsOrVars,\n )\n\n // 2. Pre-calculate credits if they are fixed (not a function)\n // This allows handlers to access credits during execution\n const creditsOption = options?.credits\n const isFixedCredits = typeof creditsOption === 'bigint' || creditsOption === undefined\n const preCalculatedCredits = isFixedCredits\n ? this.creditsContext.resolve(creditsOption, argsOrVars, null, authResult)\n : undefined\n\n // Determine effective planId: explicit option overrides token-derived value\n const effectivePlanId = options?.planId ?? authResult.planId\n\n // 3. Build PaywallContext for handler (with extra wrapper for backward compatibility)\n const paywallContext = {\n authResult,\n credits: preCalculatedCredits,\n planId: authResult.planId,\n subscriberAddress: authResult.subscriberAddress,\n agentRequest: authResult.agentRequest,\n }\n\n // 4. Execute original handler with context\n const result = await (handler as any)(...allArgs, paywallContext)\n\n // 5. Resolve final credits to burn (may be different if credits are dynamic)\n const credits = isFixedCredits\n ? (preCalculatedCredits ?? 1n)\n : this.creditsContext.resolve(creditsOption, argsOrVars, result, authResult)\n\n // Update context with final resolved credits\n paywallContext.credits = credits\n\n // 6. If the result is an AsyncIterable (stream), redeem on completion\n if (isAsyncIterable(result)) {\n const onFinally = async () => {\n return await this.redeemCredits(\n effectivePlanId,\n authResult.token,\n authResult.subscriberAddress,\n credits,\n options,\n authResult.agentId,\n authResult.logicalUrl,\n authResult.httpUrl,\n 'POST',\n )\n }\n return wrapAsyncIterable(\n result,\n onFinally,\n effectivePlanId,\n authResult.subscriberAddress,\n credits,\n )\n }\n\n // 7. Non-streaming: redeem immediately\n const creditsResult = await this.redeemCredits(\n effectivePlanId,\n authResult.token,\n authResult.subscriberAddress,\n credits,\n options,\n authResult.agentId,\n authResult.logicalUrl,\n 'POST',\n authResult.httpUrl,\n )\n result._meta = {\n ...result._meta,\n ...(creditsResult.transaction && { txHash: creditsResult.transaction }),\n creditsRedeemed: creditsResult.success ? (creditsResult.creditsRedeemed ?? credits.toString()) : '0',\n remainingBalance: creditsResult.remainingBalance,\n planId: authResult.planId,\n subscriberAddress: authResult.subscriberAddress,\n success: creditsResult.success,\n ...(creditsResult.errorReason && { errorReason: creditsResult.errorReason }),\n }\n return result\n }\n }\n\n /**\n * Redeem credits after successful request\n */\n private async redeemCredits(\n planId: string,\n token: string,\n subscriberAddress: Address,\n credits: bigint,\n options: PaywallOptions,\n agentId?: string,\n endpoint?: string,\n fallbackEndpoint?: string,\n httpVerb?: string,\n ): Promise<SettlePermissionsResult> {\n let ret: SettlePermissionsResult = {\n success: true,\n transaction: '',\n network: '',\n }\n try {\n if (credits && credits > 0n && subscriberAddress && planId) {\n const paymentRequired: X402PaymentRequired = buildPaymentRequired(planId, {\n endpoint: endpoint || '',\n agentId,\n httpVerb: httpVerb,\n })\n\n ret = await this.payments.facilitator.settlePermissions({\n paymentRequired,\n x402AccessToken: token,\n maxAmount: credits,\n })\n }\n } catch (primaryError) {\n // If logical URL fails and we have an HTTP URL fallback, retry with it\n let lastError: unknown = primaryError\n if (fallbackEndpoint) {\n try {\n const paymentRequired: X402PaymentRequired = buildPaymentRequired(planId, {\n endpoint: fallbackEndpoint,\n agentId,\n httpVerb: httpVerb,\n })\n\n ret = await this.payments.facilitator.settlePermissions({\n paymentRequired,\n x402AccessToken: token,\n maxAmount: credits,\n })\n return ret\n } catch (fallbackError) {\n // Fallback also failed, use fallback error as the reported error\n lastError = fallbackError\n }\n }\n\n ret.success = false\n ret.errorReason = lastError instanceof Error ? lastError.message : String(lastError)\n if (options.onRedeemError === 'propagate') {\n throw createRpcError(ERROR_CODES.Misconfiguration, `Failed to redeem credits: ${ret.errorReason}`)\n }\n // Default: attach error to result but don't throw\n }\n return ret\n }\n}\n\n/**\n * Type guard to detect AsyncIterable values.\n */\nfunction isAsyncIterable<T = unknown>(value: any): value is AsyncIterable<T> {\n return value != null && typeof value[Symbol.asyncIterator] === 'function'\n}\n\n/**\n * Wrap an AsyncIterable with metadata injection at the end of the stream\n */\nfunction wrapAsyncIterable<T>(\n iterable: AsyncIterable<T>,\n onFinally: () => Promise<any>,\n planId: string,\n subscriberAddress: Address,\n credits: bigint,\n) {\n async function* generator() {\n let creditsResult: any = null\n try {\n for await (const chunk of iterable) {\n yield chunk as T\n }\n } finally {\n creditsResult = await onFinally()\n }\n\n // Yield a _meta chunk at the end with the redemption result\n const metadataChunk = {\n _meta: {\n // Only include txHash if it has a value\n ...(creditsResult?.transaction && { txHash: creditsResult.transaction }),\n creditsRedeemed: creditsResult?.success ? (creditsResult.creditsRedeemed ?? credits.toString()) : '0',\n remainingBalance: creditsResult?.remainingBalance,\n planId: planId,\n subscriberAddress: subscriberAddress,\n success: creditsResult?.success || false,\n ...(creditsResult?.errorReason && { errorReason: creditsResult.errorReason }),\n },\n }\n yield metadataChunk as T\n }\n return generator()\n}\n"]}
1
+ {"version":3,"file":"paywall.js","sourceRoot":"","sources":["../../../src/mcp/core/paywall.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Main paywall decorator for MCP handlers (tools, resources, prompts)\n */\nimport { Address, isValidScheme } from '../../common/types.js'\nimport type { Payments } from '../../payments.js'\nimport { decodeAccessToken } from '../../utils.js'\nimport {\n buildPaymentRequired,\n type SettlePermissionsResult,\n type X402PaymentRequired,\n} from '../../x402/facilitator-api.js'\nimport {\n McpConfig,\n PaywallOptions,\n PromptOptions,\n ResourceOptions,\n ToolOptions,\n} from '../types/paywall.types.js'\nimport { ERROR_CODES, createRpcError } from '../utils/errors.js'\nimport { PaywallAuthenticator } from './auth.js'\nimport { CreditsContextProvider } from './credits-context.js'\n\n/**\n * Main class for creating paywall-protected MCP handlers\n */\nexport class PaywallDecorator {\n // Internal config ensures serverName is always a concrete string\n private config: { agentId: string; serverName: string } = {\n agentId: '',\n serverName: 'mcp-server',\n }\n\n constructor(\n private payments: Payments,\n private authenticator: PaywallAuthenticator,\n private creditsContext: CreditsContextProvider,\n ) {}\n\n /**\n * Configure the paywall with agent and server information\n */\n configure(options: McpConfig): void {\n this.config = {\n agentId: options.agentId || this.config.agentId,\n serverName: options.serverName ?? this.config.serverName,\n }\n }\n\n /**\n * Create a paywall-protected handler (uncurried version only)\n */\n // Overloads per kind for stronger typing\n protect<TArgs = any>(\n handler: (args: TArgs, extra?: any) => Promise<any> | any,\n options: ToolOptions | PromptOptions,\n ): (args: TArgs, extra?: any) => Promise<any>\n protect(\n handler: (\n uri: URL,\n variables: Record<string, string | string[]>,\n extra?: any,\n ) => Promise<any> | any,\n options: ResourceOptions,\n ): (uri: URL, variables: Record<string, string | string[]>, extra?: any) => Promise<any>\n protect(handler: any, options: PaywallOptions): any {\n return this.createWrappedHandler(handler, options)\n }\n\n /**\n * Internal method to create the wrapped handler\n */\n private createWrappedHandler<TArgs = any>(\n handler: (args: TArgs, extra?: any) => Promise<any> | any,\n options: PaywallOptions,\n ): (...allArgs: any[]) => Promise<any> {\n return async (...allArgs: any[]): Promise<any> => {\n // Validate configuration\n if (!this.config.agentId) {\n throw createRpcError(\n ERROR_CODES.Misconfiguration,\n 'Server misconfiguration: missing agentId',\n )\n }\n\n const kind = options?.kind ?? 'tool'\n const name = options?.name ?? 'unnamed'\n\n // Detect resource signature: (url, variables, extra)\n const isResource = allArgs.length >= 2 && allArgs[0] instanceof URL\n const extra = isResource ? allArgs[2] : allArgs[1]\n const argsOrVars = isResource ? allArgs[1] : allArgs[0]\n\n // 1. Authenticate request\n const authResult = await this.authenticator.authenticate(\n extra,\n { planId: options?.planId, maxAmount: options?.maxAmount },\n this.config.agentId,\n this.config.serverName,\n name,\n kind,\n argsOrVars,\n )\n\n // 2. Pre-calculate credits if they are fixed (not a function)\n // This allows handlers to access credits during execution\n const creditsOption = options?.credits\n const isFixedCredits = typeof creditsOption === 'bigint' || creditsOption === undefined\n const preCalculatedCredits = isFixedCredits\n ? this.creditsContext.resolve(creditsOption, argsOrVars, null, authResult)\n : undefined\n\n // Determine effective planId: explicit option overrides token-derived value\n const effectivePlanId = options?.planId ?? authResult.planId\n\n // 3. Build PaywallContext for handler (with extra wrapper for backward compatibility)\n const paywallContext = {\n authResult,\n credits: preCalculatedCredits,\n planId: authResult.planId,\n subscriberAddress: authResult.subscriberAddress,\n agentRequest: authResult.agentRequest,\n }\n\n // 4. Execute original handler with context\n const result = await (handler as any)(...allArgs, paywallContext)\n\n // 5. Resolve final credits to burn (may be different if credits are dynamic)\n const credits = isFixedCredits\n ? (preCalculatedCredits ?? 1n)\n : this.creditsContext.resolve(creditsOption, argsOrVars, result, authResult)\n\n // Update context with final resolved credits\n paywallContext.credits = credits\n\n // 6. If the result is an AsyncIterable (stream), redeem on completion\n if (isAsyncIterable(result)) {\n const onFinally = async () => {\n return await this.redeemCredits(\n effectivePlanId,\n authResult.token,\n authResult.subscriberAddress,\n credits,\n options,\n authResult.agentId,\n authResult.logicalUrl,\n authResult.httpUrl,\n 'POST',\n )\n }\n return wrapAsyncIterable(\n result,\n onFinally,\n effectivePlanId,\n authResult.subscriberAddress,\n credits,\n )\n }\n\n // 7. Non-streaming: redeem immediately\n const creditsResult = await this.redeemCredits(\n effectivePlanId,\n authResult.token,\n authResult.subscriberAddress,\n credits,\n options,\n authResult.agentId,\n authResult.logicalUrl,\n 'POST',\n authResult.httpUrl,\n )\n result._meta = {\n ...result._meta,\n ...(creditsResult.transaction && { txHash: creditsResult.transaction }),\n creditsRedeemed: creditsResult.success ? (creditsResult.creditsRedeemed ?? credits.toString()) : '0',\n remainingBalance: creditsResult.remainingBalance,\n planId: authResult.planId,\n subscriberAddress: authResult.subscriberAddress,\n success: creditsResult.success,\n ...(creditsResult.errorReason && { errorReason: creditsResult.errorReason }),\n }\n return result\n }\n }\n\n /**\n * Redeem credits after successful request\n */\n private async redeemCredits(\n planId: string,\n token: string,\n subscriberAddress: Address,\n credits: bigint,\n options: PaywallOptions,\n agentId?: string,\n endpoint?: string,\n fallbackEndpoint?: string,\n httpVerb?: string,\n ): Promise<SettlePermissionsResult> {\n let ret: SettlePermissionsResult = {\n success: true,\n transaction: '',\n network: '',\n }\n const decoded = decodeAccessToken(token)\n const scheme = isValidScheme(decoded?.accepted?.scheme) ? decoded.accepted.scheme : 'nvm:erc4337'\n try {\n if (credits && credits > 0n && subscriberAddress && planId) {\n const paymentRequired: X402PaymentRequired = buildPaymentRequired(planId, {\n endpoint: endpoint || '',\n agentId,\n httpVerb,\n scheme,\n })\n\n ret = await this.payments.facilitator.settlePermissions({\n paymentRequired,\n x402AccessToken: token,\n maxAmount: credits,\n })\n }\n } catch (primaryError) {\n // If logical URL fails and we have an HTTP URL fallback, retry with it\n let lastError: unknown = primaryError\n if (fallbackEndpoint) {\n try {\n const paymentRequired: X402PaymentRequired = buildPaymentRequired(planId, {\n endpoint: fallbackEndpoint,\n agentId,\n httpVerb,\n scheme,\n })\n\n ret = await this.payments.facilitator.settlePermissions({\n paymentRequired,\n x402AccessToken: token,\n maxAmount: credits,\n })\n return ret\n } catch (fallbackError) {\n // Fallback also failed, use fallback error as the reported error\n lastError = fallbackError\n }\n }\n\n ret.success = false\n ret.errorReason = lastError instanceof Error ? lastError.message : String(lastError)\n if (options.onRedeemError === 'propagate') {\n throw createRpcError(ERROR_CODES.Misconfiguration, `Failed to redeem credits: ${ret.errorReason}`)\n }\n // Default: attach error to result but don't throw\n }\n return ret\n }\n}\n\n/**\n * Type guard to detect AsyncIterable values.\n */\nfunction isAsyncIterable<T = unknown>(value: any): value is AsyncIterable<T> {\n return value != null && typeof value[Symbol.asyncIterator] === 'function'\n}\n\n/**\n * Wrap an AsyncIterable with metadata injection at the end of the stream\n */\nfunction wrapAsyncIterable<T>(\n iterable: AsyncIterable<T>,\n onFinally: () => Promise<any>,\n planId: string,\n subscriberAddress: Address,\n credits: bigint,\n) {\n async function* generator() {\n let creditsResult: any = null\n try {\n for await (const chunk of iterable) {\n yield chunk as T\n }\n } finally {\n creditsResult = await onFinally()\n }\n\n // Yield a _meta chunk at the end with the redemption result\n const metadataChunk = {\n _meta: {\n // Only include txHash if it has a value\n ...(creditsResult?.transaction && { txHash: creditsResult.transaction }),\n creditsRedeemed: creditsResult?.success ? (creditsResult.creditsRedeemed ?? credits.toString()) : '0',\n remainingBalance: creditsResult?.remainingBalance,\n planId,\n subscriberAddress,\n success: creditsResult?.success || false,\n ...(creditsResult?.errorReason && { errorReason: creditsResult.errorReason }),\n },\n }\n yield metadataChunk as T\n }\n return generator()\n}\n"]}
@@ -12,6 +12,7 @@ import * as mcpModule from './mcp/index.js';
12
12
  import { OrganizationsAPI } from './api/organizations-api/organizations-api.js';
13
13
  import { FacilitatorAPI } from './x402/facilitator-api.js';
14
14
  import { X402TokenAPI } from './x402/token.js';
15
+ import { DelegationAPI } from './x402/delegation-api.js';
15
16
  /**
16
17
  * Main class that interacts with the Nevermined payments API.
17
18
  * Use `Payments.getInstance` for server-side usage or `Payments.getBrowserInstance` for browser usage.
@@ -36,6 +37,7 @@ export declare class Payments extends BasePaymentsAPI {
36
37
  facilitator: FacilitatorAPI;
37
38
  x402: X402TokenAPI;
38
39
  private _a2aRegistry?;
40
+ private _delegation?;
39
41
  /**
40
42
  * Cached MCP integration to preserve configuration (e.g., agentId, serverName)
41
43
  * across multiple getter accesses. This ensures callers do not need to retain
@@ -94,6 +96,11 @@ export declare class Payments extends BasePaymentsAPI {
94
96
  start: (config: mcpModule.McpServerConfig) => Promise<mcpModule.McpServerResult>;
95
97
  stop: () => Promise<void>;
96
98
  };
99
+ /**
100
+ * Returns the Delegation API for listing enrolled payment methods.
101
+ * The instance is lazily initialized on first access.
102
+ */
103
+ get delegation(): DelegationAPI;
97
104
  /**
98
105
  * Static A2A helpers and utilities.
99
106
  * Example: Payments.a2a.buildPaymentAgentCard(...)
@@ -1 +1 @@
1
- {"version":3,"file":"payments.d.ts","sourceRoot":"","sources":["../src/payments.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAE/C,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AACxD,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAA;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,8CAA8C,CAAA;AAE/E,OAAO,KAAK,EAAE,wBAAwB,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAA;AAExF,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAA;AAC3D,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,8CAA8C,CAAA;AAC/E,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAA;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAE9C;;;;;;;;;;;;GAYG;AACH,qBAAa,QAAS,SAAQ,eAAe;IACpC,KAAK,EAAG,UAAU,CAAA;IAClB,KAAK,EAAG,QAAQ,CAAA;IAChB,MAAM,EAAG,SAAS,CAAA;IAClB,QAAQ,EAAG,gBAAgB,CAAA;IAC3B,aAAa,EAAG,gBAAgB,CAAA;IAChC,aAAa,EAAG,gBAAgB,CAAA;IAChC,SAAS,EAAG,YAAY,CAAA;IACxB,WAAW,EAAG,cAAc,CAAA;IAC5B,IAAI,EAAG,YAAY,CAAA;IAC1B,OAAO,CAAC,YAAY,CAAC,CAAgB;IAErC;;;;OAIG;IACH,OAAO,CAAC,eAAe,CAAC,CAAkD;IAE1E;;;OAGG;IACH,IAAW,GAAG;QAEV;;;WAGG;yBAEQ,IAAI,CAAC,wBAAwB,EAAE,iBAAiB,CAAC,KACzD,uBAAuB;QAE1B;;;;WAIG;6BACwB,GAAG;MAOjC;IAED;;;OAGG;IACH,IAAW,GAAG;;;sDAgJc,CAAC,cAAc,CAAC,2LAA2G,CAAC;sDAA4F,CAAC,cAAc,CAAC,uEAAiE,CAAC;oFAA6I,CAAC,cAAoB,CAAC,mLAAgJ,CAAC;;;;;;;6FAA+5C,CAAC,cAAc,CAAC;8IAAwd,CAAC,cAAwB,CAAC;+FAAyc,CAAC,cAAc,CAAC;;;kBAArzD,CAAC;;;;mBAAuwI,CAAC;;;;;;;;;MA3Iv8K;IAED;;;OAGG;IACH,MAAM,CAAC,GAAG;;MAA4B;IAEtC;;;;;;;;;;;;;OAaG;IACH,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE,cAAc;IAO1C;;;;;;;;;;;;;;;;;;OAkBG;IACH,MAAM,CAAC,kBAAkB,CAAC,OAAO,EAAE,cAAc;IAoBjD;;;;;OAKG;IACH,OAAO;IAOP;;OAEG;IACH,OAAO,CAAC,aAAa;IAYrB;;;;;;;;;;OAUG;IACI,OAAO;IAMd;;;;;;;;;OASG;IACI,MAAM;IAIb;;;;;;;OAOG;IACH,IAAI,UAAU,IAAI,OAAO,CAExB;CACF"}
1
+ {"version":3,"file":"payments.d.ts","sourceRoot":"","sources":["../src/payments.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAE/C,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AACxD,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAA;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,8CAA8C,CAAA;AAE/E,OAAO,KAAK,EAAE,wBAAwB,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAA;AAExF,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAA;AAC3D,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,8CAA8C,CAAA;AAC/E,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAA;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAIxD;;;;;;;;;;;;GAYG;AACH,qBAAa,QAAS,SAAQ,eAAe;IACpC,KAAK,EAAG,UAAU,CAAA;IAClB,KAAK,EAAG,QAAQ,CAAA;IAChB,MAAM,EAAG,SAAS,CAAA;IAClB,QAAQ,EAAG,gBAAgB,CAAA;IAC3B,aAAa,EAAG,gBAAgB,CAAA;IAChC,aAAa,EAAG,gBAAgB,CAAA;IAChC,SAAS,EAAG,YAAY,CAAA;IACxB,WAAW,EAAG,cAAc,CAAA;IAC5B,IAAI,EAAG,YAAY,CAAA;IAC1B,OAAO,CAAC,YAAY,CAAC,CAAgB;IACrC,OAAO,CAAC,WAAW,CAAC,CAAe;IAEnC;;;;OAIG;IACH,OAAO,CAAC,eAAe,CAAC,CAAkD;IAE1E;;;OAGG;IACH,IAAW,GAAG;QAEV;;;WAGG;yBAEQ,IAAI,CAAC,wBAAwB,EAAE,iBAAiB,CAAC,KACzD,uBAAuB;QAE1B;;;;WAIG;6BACwB,GAAG;MAOjC;IAED;;;OAGG;IACH,IAAW,GAAG;;;sDA4Hb,CAAC,cACC,CAAA,2LAMO,CAAC;sDAE+B,CAAC,cAAc,CAAC,uEACxB,CAAC;oFASlC,CAAA,cACW,CAAC,mLAWR,CAAC;;;;;;;6FAQiwC,CAAC,cAAc,CAAC;8IAAwd,CAAC,cAAwB,CAAC;+FAAyc,CAAC,cAAc,CAAC;;;kBAArzD,CAAC;;;;mBAAuwI,CAAC;;;;;;;;;MA9JrrJ;IAED;;;OAGG;IACH,IAAW,UAAU,IAAI,aAAa,CAQrC;IAED;;;OAGG;IACH,MAAM,CAAC,GAAG;;MAA4B;IAEtC;;;;;;;;;;;;;OAaG;IACH,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE,cAAc;IAO1C;;;;;;;;;;;;;;;;;;OAkBG;IACH,MAAM,CAAC,kBAAkB,CAAC,OAAO,EAAE,cAAc;IAoBjD;;;;;OAKG;IACH,OAAO;IAOP;;OAEG;IACH,OAAO,CAAC,aAAa;IAiBrB;;;;;;;;;;OAUG;IACI,OAAO;IAMd;;;;;;;;;OASG;IACI,MAAM;IAIb;;;;;;;OAOG;IACH,IAAI,UAAU,IAAI,OAAO,CAExB;CACF"}
package/dist/payments.js CHANGED
@@ -13,6 +13,9 @@ import * as mcpModule from './mcp/index.js';
13
13
  import { OrganizationsAPI } from './api/organizations-api/organizations-api.js';
14
14
  import { FacilitatorAPI } from './x402/facilitator-api.js';
15
15
  import { X402TokenAPI } from './x402/token.js';
16
+ import { DelegationAPI } from './x402/delegation-api.js';
17
+ import { VisaFacilitatorAPI } from './x402/visa-facilitator-api.js';
18
+ import { VisaTokenAPI } from './x402/visa-token-api.js';
16
19
  /**
17
20
  * Main class that interacts with the Nevermined payments API.
18
21
  * Use `Payments.getInstance` for server-side usage or `Payments.getBrowserInstance` for browser usage.
@@ -61,6 +64,19 @@ export class Payments extends BasePaymentsAPI {
61
64
  }
62
65
  return this._mcpIntegration;
63
66
  }
67
+ /**
68
+ * Returns the Delegation API for listing enrolled payment methods.
69
+ * The instance is lazily initialized on first access.
70
+ */
71
+ get delegation() {
72
+ if (!this._delegation) {
73
+ this._delegation = DelegationAPI.getInstance({
74
+ nvmApiKey: this.nvmApiKey,
75
+ environment: this.environmentName,
76
+ });
77
+ }
78
+ return this._delegation;
79
+ }
64
80
  /**
65
81
  * Get an instance of the Payments class for server-side usage.
66
82
  *
@@ -138,8 +154,14 @@ export class Payments extends BasePaymentsAPI {
138
154
  this.organizations = OrganizationsAPI.getInstance(options);
139
155
  this.query = AIQueryApi.getInstance();
140
156
  this.contracts = new ContractsAPI(options);
141
- this.facilitator = FacilitatorAPI.getInstance(options);
142
- this.x402 = X402TokenAPI.getInstance(options);
157
+ if (options.scheme === 'visa') {
158
+ this.facilitator = VisaFacilitatorAPI.getInstance(options);
159
+ this.x402 = VisaTokenAPI.getInstance(options);
160
+ }
161
+ else {
162
+ this.facilitator = FacilitatorAPI.getInstance(options);
163
+ this.x402 = X402TokenAPI.getInstance(options);
164
+ }
143
165
  }
144
166
  /**
145
167
  * Initiates the connect flow. The user's browser will be redirected to
@@ -1 +1 @@
1
- {"version":3,"file":"payments.js","sourceRoot":"","sources":["../src/payments.ts"],"names":[],"mappings":"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","sourcesContent":["import { AIQueryApi } from './api/query-api.js'\nimport { PaymentsError } from './common/payments.error.js'\nimport { PaymentOptions } from './common/types.js'\nimport { BasePaymentsAPI } from './api/base-payments.js'\nimport { PlansAPI } from './api/plans-api.js'\nimport { ContractsAPI } from './api/contracts-api.js'\nimport { AgentsAPI } from './api/agents-api.js'\nimport { AgentRequestsAPI } from './api/requests-api.js'\nimport { ObservabilityAPI } from './api/observability-api/observability-api.js'\nimport { ClientRegistry } from './a2a/clientRegistry.js'\nimport type { PaymentsA2AServerOptions, PaymentsA2AServerResult } from './a2a/server.js'\nimport { PaymentsA2AServer } from './a2a/server.js'\nimport { buildPaymentAgentCard } from './a2a/agent-card.js'\nimport * as mcpModule from './mcp/index.js'\nimport { OrganizationsAPI } from './api/organizations-api/organizations-api.js'\nimport { FacilitatorAPI } from './x402/facilitator-api.js'\nimport { X402TokenAPI } from './x402/token.js'\n\n/**\n * Main class that interacts with the Nevermined payments API.\n * Use `Payments.getInstance` for server-side usage or `Payments.getBrowserInstance` for browser usage.\n * @remarks This API requires a Nevermined API Key, which can be obtained by logging in to the Nevermined App.\n *\n * The library provides methods to manage AI Agents, Plans & process AI Agent Requests.\n *\n * Each of these functionalities is encapsulated in its own API class:\n * - `plans`: Manages AI Plans, including registration and ordering and retrieving plan details.\n * - `agents`: Handles AI Agents, including registration of AI Agents and access token generation.\n * - `requests`: Manages requests received by AI Agents, including validation and tracking.\n * - `observability`: Provides observability and logging utilities for AI Agents with Helicone integration\n */\nexport class Payments extends BasePaymentsAPI {\n public query!: AIQueryApi\n public plans!: PlansAPI\n public agents!: AgentsAPI\n public requests!: AgentRequestsAPI\n public observability!: ObservabilityAPI\n public organizations!: OrganizationsAPI\n public contracts!: ContractsAPI\n public facilitator!: FacilitatorAPI\n public x402!: X402TokenAPI\n private _a2aRegistry?: ClientRegistry\n\n /**\n * Cached MCP integration to preserve configuration (e.g., agentId, serverName)\n * across multiple getter accesses. This ensures callers do not need to retain\n * a reference to a previously configured instance.\n */\n private _mcpIntegration?: ReturnType<typeof mcpModule.buildMcpIntegration>\n\n /**\n * Exposes A2A server and client registry methods.\n * The client registry is initialized only if getClient is called.\n */\n public get a2a() {\n return {\n /**\n * Starts the A2A server with payment integration.\n * @param options - Server options.\n */\n start: (\n options: Omit<PaymentsA2AServerOptions, 'paymentsService'>,\n ): PaymentsA2AServerResult => PaymentsA2AServer.start({ ...options, paymentsService: this }),\n\n /**\n * Gets (or creates) a RegisteredPaymentsClient for the given alias.\n * The registry is initialized only on first use.\n * @param options - ClientRegistryOptions.\n */\n getClient: async (options: any) => {\n if (!this._a2aRegistry) {\n this._a2aRegistry = new ClientRegistry(this)\n }\n return await this._a2aRegistry.getClient(options)\n },\n }\n }\n\n /**\n * Returns the MCP integration API. The instance is memoized so that configuration\n * set via `configure({ agentId, serverName })` persists across calls.\n */\n public get mcp() {\n if (!this._mcpIntegration) {\n this._mcpIntegration = mcpModule.buildMcpIntegration(this)\n }\n return this._mcpIntegration\n }\n\n /**\n * Static A2A helpers and utilities.\n * Example: Payments.a2a.buildPaymentAgentCard(...)\n */\n static a2a = { buildPaymentAgentCard }\n\n /**\n * Get an instance of the Payments class for server-side usage.\n *\n * @param options - The options to initialize the payments class.\n * @example\n * ```\n * const payments = Payments.getInstance({\n * nvmApiKey: 'your-nvm-api-key',\n * environment: 'sandbox'\n * })\n * ```\n * @returns An instance of {@link Payments}\n * @throws PaymentsError if nvmApiKey is missing.\n */\n static getInstance(options: PaymentOptions) {\n if (!options.nvmApiKey) {\n throw new PaymentsError('Nevermined API Key is required')\n }\n return new Payments(options, false)\n }\n\n /**\n * Get an instance of the Payments class for browser usage.\n *\n * @remarks\n * This is a browser-only function.\n *\n * @param options - The options to initialize the payments class.\n * @example\n * ```\n * const payments = Payments.getBrowserInstance({\n * returnUrl: 'https://mysite.example',\n * environment: 'sandbox',\n * appId: 'my-app-id',\n * version: '1.0.0'\n * })\n * ```\n * @returns An instance of {@link Payments}\n * @throws PaymentsError if returnUrl is missing.\n */\n static getBrowserInstance(options: PaymentOptions) {\n if (!options.returnUrl) {\n throw new PaymentsError('returnUrl is required')\n }\n const url = new URL(window.location.href)\n const urlNvmApiKey = url.searchParams.get('nvmApiKey') as string\n if (urlNvmApiKey) {\n url.searchParams.delete('nvmApiKey')\n }\n\n const urlAccountAddress = url.searchParams.get('accountAddress') as string\n if (urlAccountAddress) {\n url.searchParams.delete('accountAddress')\n }\n\n history.replaceState(history.state, '', url.toString())\n\n return new Payments(options, true)\n }\n\n /**\n * Initializes the Payments class.\n *\n * @param options - The options to initialize the payments class.\n * @param isBrowserInstance - Whether this instance is for browser usage.\n */\n private constructor(options: PaymentOptions, isBrowserInstance = true) {\n super(options)\n\n this.isBrowserInstance = isBrowserInstance\n this.initializeApi(options)\n }\n\n /**\n * Initializes the AI Query Protocol API.\n */\n private initializeApi(options: PaymentOptions) {\n this.plans = PlansAPI.getInstance(options)\n this.agents = AgentsAPI.getInstance(options)\n this.requests = AgentRequestsAPI.getInstance(options)\n this.observability = ObservabilityAPI.getInstance(options)\n this.organizations = OrganizationsAPI.getInstance(options)\n this.query = AIQueryApi.getInstance()\n this.contracts = new ContractsAPI(options)\n this.facilitator = FacilitatorAPI.getInstance(options)\n this.x402 = X402TokenAPI.getInstance(options)\n }\n\n /**\n * Initiates the connect flow. The user's browser will be redirected to\n * the Nevermined App login page.\n *\n * @remarks\n * This is a browser-only function.\n * @example\n * ```\n * payments.connect()\n * ```\n */\n public connect() {\n if (!this.isBrowserInstance) return\n const url = new URL(`/login?returnUrl=${this.returnUrl}`, this.environment.frontend)\n window.location.href = url.toString()\n }\n\n /**\n * Logs out the user by removing the NVM API key.\n *\n * @remarks\n * This is a browser-only function.\n * @example\n * ```\n * payments.logout()\n * ```\n */\n public logout() {\n this.nvmApiKey = ''\n }\n\n /**\n * Checks if a user is logged in.\n * @example\n * ```\n * payments.isLoggedIn\n * ```\n * @returns True if the user is logged in.\n */\n get isLoggedIn(): boolean {\n return this.nvmApiKey.length > 0\n }\n}\n"]}
1
+ {"version":3,"file":"payments.js","sourceRoot":"","sources":["../src/payments.ts"],"names":[],"mappings":"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","sourcesContent":["import { AIQueryApi } from './api/query-api.js'\nimport { PaymentsError } from './common/payments.error.js'\nimport { PaymentOptions } from './common/types.js'\nimport { BasePaymentsAPI } from './api/base-payments.js'\nimport { PlansAPI } from './api/plans-api.js'\nimport { ContractsAPI } from './api/contracts-api.js'\nimport { AgentsAPI } from './api/agents-api.js'\nimport { AgentRequestsAPI } from './api/requests-api.js'\nimport { ObservabilityAPI } from './api/observability-api/observability-api.js'\nimport { ClientRegistry } from './a2a/clientRegistry.js'\nimport type { PaymentsA2AServerOptions, PaymentsA2AServerResult } from './a2a/server.js'\nimport { PaymentsA2AServer } from './a2a/server.js'\nimport { buildPaymentAgentCard } from './a2a/agent-card.js'\nimport * as mcpModule from './mcp/index.js'\nimport { OrganizationsAPI } from './api/organizations-api/organizations-api.js'\nimport { FacilitatorAPI } from './x402/facilitator-api.js'\nimport { X402TokenAPI } from './x402/token.js'\nimport { DelegationAPI } from './x402/delegation-api.js'\nimport { VisaFacilitatorAPI } from './x402/visa-facilitator-api.js'\nimport { VisaTokenAPI } from './x402/visa-token-api.js'\n\n/**\n * Main class that interacts with the Nevermined payments API.\n * Use `Payments.getInstance` for server-side usage or `Payments.getBrowserInstance` for browser usage.\n * @remarks This API requires a Nevermined API Key, which can be obtained by logging in to the Nevermined App.\n *\n * The library provides methods to manage AI Agents, Plans & process AI Agent Requests.\n *\n * Each of these functionalities is encapsulated in its own API class:\n * - `plans`: Manages AI Plans, including registration and ordering and retrieving plan details.\n * - `agents`: Handles AI Agents, including registration of AI Agents and access token generation.\n * - `requests`: Manages requests received by AI Agents, including validation and tracking.\n * - `observability`: Provides observability and logging utilities for AI Agents with Helicone integration\n */\nexport class Payments extends BasePaymentsAPI {\n public query!: AIQueryApi\n public plans!: PlansAPI\n public agents!: AgentsAPI\n public requests!: AgentRequestsAPI\n public observability!: ObservabilityAPI\n public organizations!: OrganizationsAPI\n public contracts!: ContractsAPI\n public facilitator!: FacilitatorAPI\n public x402!: X402TokenAPI\n private _a2aRegistry?: ClientRegistry\n private _delegation?: DelegationAPI\n\n /**\n * Cached MCP integration to preserve configuration (e.g., agentId, serverName)\n * across multiple getter accesses. This ensures callers do not need to retain\n * a reference to a previously configured instance.\n */\n private _mcpIntegration?: ReturnType<typeof mcpModule.buildMcpIntegration>\n\n /**\n * Exposes A2A server and client registry methods.\n * The client registry is initialized only if getClient is called.\n */\n public get a2a() {\n return {\n /**\n * Starts the A2A server with payment integration.\n * @param options - Server options.\n */\n start: (\n options: Omit<PaymentsA2AServerOptions, 'paymentsService'>,\n ): PaymentsA2AServerResult => PaymentsA2AServer.start({ ...options, paymentsService: this }),\n\n /**\n * Gets (or creates) a RegisteredPaymentsClient for the given alias.\n * The registry is initialized only on first use.\n * @param options - ClientRegistryOptions.\n */\n getClient: async (options: any) => {\n if (!this._a2aRegistry) {\n this._a2aRegistry = new ClientRegistry(this)\n }\n return await this._a2aRegistry.getClient(options)\n },\n }\n }\n\n /**\n * Returns the MCP integration API. The instance is memoized so that configuration\n * set via `configure({ agentId, serverName })` persists across calls.\n */\n public get mcp() {\n if (!this._mcpIntegration) {\n this._mcpIntegration = mcpModule.buildMcpIntegration(this)\n }\n return this._mcpIntegration\n }\n\n /**\n * Returns the Delegation API for listing enrolled payment methods.\n * The instance is lazily initialized on first access.\n */\n public get delegation(): DelegationAPI {\n if (!this._delegation) {\n this._delegation = DelegationAPI.getInstance({\n nvmApiKey: this.nvmApiKey,\n environment: this.environmentName,\n })\n }\n return this._delegation\n }\n\n /**\n * Static A2A helpers and utilities.\n * Example: Payments.a2a.buildPaymentAgentCard(...)\n */\n static a2a = { buildPaymentAgentCard }\n\n /**\n * Get an instance of the Payments class for server-side usage.\n *\n * @param options - The options to initialize the payments class.\n * @example\n * ```\n * const payments = Payments.getInstance({\n * nvmApiKey: 'your-nvm-api-key',\n * environment: 'sandbox'\n * })\n * ```\n * @returns An instance of {@link Payments}\n * @throws PaymentsError if nvmApiKey is missing.\n */\n static getInstance(options: PaymentOptions) {\n if (!options.nvmApiKey) {\n throw new PaymentsError('Nevermined API Key is required')\n }\n return new Payments(options, false)\n }\n\n /**\n * Get an instance of the Payments class for browser usage.\n *\n * @remarks\n * This is a browser-only function.\n *\n * @param options - The options to initialize the payments class.\n * @example\n * ```\n * const payments = Payments.getBrowserInstance({\n * returnUrl: 'https://mysite.example',\n * environment: 'sandbox',\n * appId: 'my-app-id',\n * version: '1.0.0'\n * })\n * ```\n * @returns An instance of {@link Payments}\n * @throws PaymentsError if returnUrl is missing.\n */\n static getBrowserInstance(options: PaymentOptions) {\n if (!options.returnUrl) {\n throw new PaymentsError('returnUrl is required')\n }\n const url = new URL(window.location.href)\n const urlNvmApiKey = url.searchParams.get('nvmApiKey') as string\n if (urlNvmApiKey) {\n url.searchParams.delete('nvmApiKey')\n }\n\n const urlAccountAddress = url.searchParams.get('accountAddress') as string\n if (urlAccountAddress) {\n url.searchParams.delete('accountAddress')\n }\n\n history.replaceState(history.state, '', url.toString())\n\n return new Payments(options, true)\n }\n\n /**\n * Initializes the Payments class.\n *\n * @param options - The options to initialize the payments class.\n * @param isBrowserInstance - Whether this instance is for browser usage.\n */\n private constructor(options: PaymentOptions, isBrowserInstance = true) {\n super(options)\n\n this.isBrowserInstance = isBrowserInstance\n this.initializeApi(options)\n }\n\n /**\n * Initializes the AI Query Protocol API.\n */\n private initializeApi(options: PaymentOptions) {\n this.plans = PlansAPI.getInstance(options)\n this.agents = AgentsAPI.getInstance(options)\n this.requests = AgentRequestsAPI.getInstance(options)\n this.observability = ObservabilityAPI.getInstance(options)\n this.organizations = OrganizationsAPI.getInstance(options)\n this.query = AIQueryApi.getInstance()\n this.contracts = new ContractsAPI(options)\n if (options.scheme === 'visa') {\n this.facilitator = VisaFacilitatorAPI.getInstance(options)\n this.x402 = VisaTokenAPI.getInstance(options)\n } else {\n this.facilitator = FacilitatorAPI.getInstance(options)\n this.x402 = X402TokenAPI.getInstance(options)\n }\n }\n\n /**\n * Initiates the connect flow. The user's browser will be redirected to\n * the Nevermined App login page.\n *\n * @remarks\n * This is a browser-only function.\n * @example\n * ```\n * payments.connect()\n * ```\n */\n public connect() {\n if (!this.isBrowserInstance) return\n const url = new URL(`/login?returnUrl=${this.returnUrl}`, this.environment.frontend)\n window.location.href = url.toString()\n }\n\n /**\n * Logs out the user by removing the NVM API key.\n *\n * @remarks\n * This is a browser-only function.\n * @example\n * ```\n * payments.logout()\n * ```\n */\n public logout() {\n this.nvmApiKey = ''\n }\n\n /**\n * Checks if a user is logged in.\n * @example\n * ```\n * payments.isLoggedIn\n * ```\n * @returns True if the user is logged in.\n */\n get isLoggedIn(): boolean {\n return this.nvmApiKey.length > 0\n }\n}\n"]}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Delegation API for managing card-delegation payment methods.
3
+ *
4
+ * Provides access to the user's enrolled Stripe payment methods
5
+ * for use with the nvm:card-delegation x402 scheme.
6
+ */
7
+ import { BasePaymentsAPI } from '../api/base-payments.js';
8
+ import { PaymentOptions } from '../common/types.js';
9
+ /**
10
+ * Summary of a user's enrolled payment method.
11
+ */
12
+ export interface PaymentMethodSummary {
13
+ /** Payment method ID (e.g., 'pm_...') */
14
+ id: string;
15
+ /** Card brand (e.g., 'visa', 'mastercard') */
16
+ brand: string;
17
+ /** Last 4 digits of the card number */
18
+ last4: string;
19
+ /** Card expiration month */
20
+ expMonth: number;
21
+ /** Card expiration year */
22
+ expYear: number;
23
+ }
24
+ /**
25
+ * API for listing enrolled payment methods for card delegation.
26
+ */
27
+ export declare class DelegationAPI extends BasePaymentsAPI {
28
+ /**
29
+ * Get an instance of the DelegationAPI class.
30
+ *
31
+ * @param options - The options to initialize the API
32
+ * @returns The instance of the DelegationAPI class
33
+ */
34
+ static getInstance(options: PaymentOptions): DelegationAPI;
35
+ /**
36
+ * List the user's enrolled payment methods for card delegation.
37
+ *
38
+ * @returns A promise that resolves to an array of payment method summaries
39
+ * @throws PaymentsError if the request fails
40
+ */
41
+ listPaymentMethods(): Promise<PaymentMethodSummary[]>;
42
+ }
43
+ //# sourceMappingURL=delegation-api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delegation-api.d.ts","sourceRoot":"","sources":["../../src/x402/delegation-api.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AAEzD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AAEnD;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,yCAAyC;IACzC,EAAE,EAAE,MAAM,CAAA;IACV,8CAA8C;IAC9C,KAAK,EAAE,MAAM,CAAA;IACb,uCAAuC;IACvC,KAAK,EAAE,MAAM,CAAA;IACb,4BAA4B;IAC5B,QAAQ,EAAE,MAAM,CAAA;IAChB,2BAA2B;IAC3B,OAAO,EAAE,MAAM,CAAA;CAChB;AAED;;GAEG;AACH,qBAAa,aAAc,SAAQ,eAAe;IAChD;;;;;OAKG;IACH,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE,cAAc,GAAG,aAAa;IAI1D;;;;;OAKG;IACG,kBAAkB,IAAI,OAAO,CAAC,oBAAoB,EAAE,CAAC;CA0B5D"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Delegation API for managing card-delegation payment methods.
3
+ *
4
+ * Provides access to the user's enrolled Stripe payment methods
5
+ * for use with the nvm:card-delegation x402 scheme.
6
+ */
7
+ import { BasePaymentsAPI } from '../api/base-payments.js';
8
+ import { PaymentsError } from '../common/payments.error.js';
9
+ /**
10
+ * API for listing enrolled payment methods for card delegation.
11
+ */
12
+ export class DelegationAPI extends BasePaymentsAPI {
13
+ /**
14
+ * Get an instance of the DelegationAPI class.
15
+ *
16
+ * @param options - The options to initialize the API
17
+ * @returns The instance of the DelegationAPI class
18
+ */
19
+ static getInstance(options) {
20
+ return new DelegationAPI(options);
21
+ }
22
+ /**
23
+ * List the user's enrolled payment methods for card delegation.
24
+ *
25
+ * @returns A promise that resolves to an array of payment method summaries
26
+ * @throws PaymentsError if the request fails
27
+ */
28
+ async listPaymentMethods() {
29
+ const url = new URL('/api/v1/delegation/payment-methods', this.environment.backend);
30
+ const options = this.getBackendHTTPOptions('GET');
31
+ try {
32
+ const response = await fetch(url, options);
33
+ if (!response.ok) {
34
+ let errorMessage = 'Failed to list payment methods';
35
+ try {
36
+ const errorData = await response.json();
37
+ errorMessage = errorData.message || errorMessage;
38
+ }
39
+ catch {
40
+ // Use default error message
41
+ }
42
+ throw PaymentsError.internal(`${errorMessage} (HTTP ${response.status})`);
43
+ }
44
+ return await response.json();
45
+ }
46
+ catch (error) {
47
+ if (error instanceof PaymentsError) {
48
+ throw error;
49
+ }
50
+ throw PaymentsError.internal(`Network error while listing payment methods: ${error instanceof Error ? error.message : String(error)}`);
51
+ }
52
+ }
53
+ }
54
+ //# sourceMappingURL=delegation-api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delegation-api.js","sourceRoot":"","sources":["../../src/x402/delegation-api.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAA;AAmB3D;;GAEG;AACH,MAAM,OAAO,aAAc,SAAQ,eAAe;IAChD;;;;;OAKG;IACH,MAAM,CAAC,WAAW,CAAC,OAAuB;QACxC,OAAO,IAAI,aAAa,CAAC,OAAO,CAAC,CAAA;IACnC,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,kBAAkB;QACtB,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,oCAAoC,EAAE,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAA;QACnF,MAAM,OAAO,GAAG,IAAI,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAA;QAEjD,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,gCAAgC,CAAA;gBACnD,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,gDAAgD,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CACzG,CAAA;QACH,CAAC;IACH,CAAC;CACF","sourcesContent":["/**\n * Delegation API for managing card-delegation payment methods.\n *\n * Provides access to the user's enrolled Stripe payment methods\n * for use with the nvm:card-delegation x402 scheme.\n */\n\nimport { BasePaymentsAPI } from '../api/base-payments.js'\nimport { PaymentsError } from '../common/payments.error.js'\nimport { PaymentOptions } from '../common/types.js'\n\n/**\n * Summary of a user's enrolled payment method.\n */\nexport interface PaymentMethodSummary {\n /** Payment method ID (e.g., 'pm_...') */\n id: string\n /** Card brand (e.g., 'visa', 'mastercard') */\n brand: string\n /** Last 4 digits of the card number */\n last4: string\n /** Card expiration month */\n expMonth: number\n /** Card expiration year */\n expYear: number\n}\n\n/**\n * API for listing enrolled payment methods for card delegation.\n */\nexport class DelegationAPI extends BasePaymentsAPI {\n /**\n * Get an instance of the DelegationAPI class.\n *\n * @param options - The options to initialize the API\n * @returns The instance of the DelegationAPI class\n */\n static getInstance(options: PaymentOptions): DelegationAPI {\n return new DelegationAPI(options)\n }\n\n /**\n * List the user's enrolled payment methods for card delegation.\n *\n * @returns A promise that resolves to an array of payment method summaries\n * @throws PaymentsError if the request fails\n */\n async listPaymentMethods(): Promise<PaymentMethodSummary[]> {\n const url = new URL('/api/v1/delegation/payment-methods', this.environment.backend)\n const options = this.getBackendHTTPOptions('GET')\n\n try {\n const response = await fetch(url, options)\n if (!response.ok) {\n let errorMessage = 'Failed to list payment methods'\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 listing payment methods: ${error instanceof Error ? error.message : String(error)}`,\n )\n }\n }\n}\n"]}
@@ -53,7 +53,7 @@ import type { Request, Response, NextFunction } from 'express';
53
53
  */
54
54
  export type ExpressMiddleware = (req: Request, res: Response, next: NextFunction) => void;
55
55
  import type { Payments } from '../../payments.js';
56
- import type { StartAgentRequest } from '../../common/types.js';
56
+ import type { StartAgentRequest, X402SchemeType } from '../../common/types.js';
57
57
  import { type X402PaymentRequired, type VerifyPermissionsResult } from '../facilitator-api.js';
58
58
  /**
59
59
  * Configuration for a protected route
@@ -65,8 +65,10 @@ export interface RouteConfig {
65
65
  credits?: number | ((req: Request, res: Response) => number | Promise<number>);
66
66
  /** Optional agent ID */
67
67
  agentId?: string;
68
- /** Network identifier (default: 'eip155:84532' for Base Sepolia) */
68
+ /** Network identifier (default: auto-derived from scheme) */
69
69
  network?: string;
70
+ /** x402 scheme override (auto-detected from plan metadata if omitted) */
71
+ scheme?: X402SchemeType;
70
72
  }
71
73
  /**
72
74
  * Route configuration map: "METHOD \/path" -> RouteConfig
@@ -1 +1 @@
1
- {"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../../../src/x402/express/middleware.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAE9D;;;;GAIG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,KAAK,IAAI,CAAA;AACzF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AACjD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAA;AAC9D,OAAO,EAEL,KAAK,mBAAmB,EACxB,KAAK,uBAAuB,EAC7B,MAAM,uBAAuB,CAAA;AAE9B;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,sDAAsD;IACtD,MAAM,EAAE,MAAM,CAAA;IACd,8DAA8D;IAC9D,OAAO,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,KAAK,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAA;IAC9E,wBAAwB;IACxB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,oEAAoE;IACpE,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAA;AAExD;;;GAGG;AACH,eAAO,MAAM,YAAY;IACvB,gDAAgD;;IAEhD,mEAAmE;;IAEnE,sEAAsE;;CAE9D,CAAA;AAEV;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,4BAA4B;IAC5B,KAAK,EAAE,MAAM,CAAA;IACb,kCAAkC;IAClC,eAAe,EAAE,mBAAmB,CAAA;IACpC,kCAAkC;IAClC,eAAe,EAAE,MAAM,CAAA;IACvB,0CAA0C;IAC1C,QAAQ,EAAE,OAAO,CAAA;IACjB,2EAA2E;IAC3E,YAAY,CAAC,EAAE,iBAAiB,CAAA;IAChC,kDAAkD;IAClD,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IAC/B,gDAAgD;IAChD,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,KAAK,IAAI,CAAA;IACpE,sCAAsC;IACtC,cAAc,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,eAAe,EAAE,mBAAmB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC7F;;;OAGG;IACH,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,YAAY,EAAE,uBAAuB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC7F,8CAA8C;IAC9C,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAC7F;AAyGD,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,cAAc,EACtB,OAAO,GAAE,wBAA6B,GACrC,iBAAiB,CAuJnB;AAED,eAAe,iBAAiB,CAAA"}
1
+ {"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../../../src/x402/express/middleware.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAE9D;;;;GAIG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,KAAK,IAAI,CAAA;AACzF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AACjD,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAC9E,OAAO,EAGL,KAAK,mBAAmB,EACxB,KAAK,uBAAuB,EAC7B,MAAM,uBAAuB,CAAA;AAE9B;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,sDAAsD;IACtD,MAAM,EAAE,MAAM,CAAA;IACd,8DAA8D;IAC9D,OAAO,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,KAAK,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAA;IAC9E,wBAAwB;IACxB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,6DAA6D;IAC7D,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,yEAAyE;IACzE,MAAM,CAAC,EAAE,cAAc,CAAA;CACxB;AAED;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAA;AAExD;;;GAGG;AACH,eAAO,MAAM,YAAY;IACvB,gDAAgD;;IAEhD,mEAAmE;;IAEnE,sEAAsE;;CAE9D,CAAA;AAEV;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,4BAA4B;IAC5B,KAAK,EAAE,MAAM,CAAA;IACb,kCAAkC;IAClC,eAAe,EAAE,mBAAmB,CAAA;IACpC,kCAAkC;IAClC,eAAe,EAAE,MAAM,CAAA;IACvB,0CAA0C;IAC1C,QAAQ,EAAE,OAAO,CAAA;IACjB,2EAA2E;IAC3E,YAAY,CAAC,EAAE,iBAAiB,CAAA;IAChC,kDAAkD;IAClD,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IAC/B,gDAAgD;IAChD,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,KAAK,IAAI,CAAA;IACpE,sCAAsC;IACtC,cAAc,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,eAAe,EAAE,mBAAmB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC7F;;;OAGG;IACH,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,YAAY,EAAE,uBAAuB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC7F,8CAA8C;IAC9C,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAC7F;AAyGD,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,cAAc,EACtB,OAAO,GAAE,wBAA6B,GACrC,iBAAiB,CAwKnB;AAED,eAAe,iBAAiB,CAAA"}
@@ -45,7 +45,7 @@
45
45
  * })
46
46
  * ```
47
47
  */
48
- import { buildPaymentRequired, } from '../facilitator-api.js';
48
+ import { buildPaymentRequired, resolveScheme, } from '../facilitator-api.js';
49
49
  /**
50
50
  * x402 HTTP Transport header names (v2 spec)
51
51
  * @see https://github.com/coinbase/x402/blob/main/specs/transports-v2/http.md
@@ -159,13 +159,16 @@ export function paymentMiddleware(payments, routes, options = {}) {
159
159
  next();
160
160
  return;
161
161
  }
162
- const { planId, credits = 1, agentId, network } = routeConfig;
162
+ const { planId, credits = 1, agentId, network, scheme: explicitScheme } = routeConfig;
163
+ // Resolve scheme from plan metadata (cached) or explicit override
164
+ const scheme = await resolveScheme(payments, planId, explicitScheme);
163
165
  // Build payment required object (needed for both error responses and verification)
164
166
  const paymentRequired = buildPaymentRequired(planId, {
165
167
  endpoint: req.originalUrl || req.url,
166
168
  agentId,
167
169
  httpVerb: req.method,
168
170
  network,
171
+ scheme,
169
172
  });
170
173
  // Extract token from headers (x402 v2: payment-signature)
171
174
  const token = extractToken(req, tokenHeader);
@@ -218,25 +221,34 @@ export function paymentMiddleware(payments, routes, options = {}) {
218
221
  // This ensures credits are burned and payment-response header is included
219
222
  const originalJson = res.json.bind(res);
220
223
  res.json = function (body) {
221
- // Settle credits synchronously before sending response
222
- // Pass agentRequestId to enable observability updates
223
- payments.facilitator
224
- .settlePermissions({
225
- paymentRequired,
226
- x402AccessToken: token,
227
- maxAmount: BigInt(creditsToVerify),
228
- agentRequestId: paymentContext.agentRequestId,
229
- })
230
- .then((settlement) => {
231
- // Add settlement response header (base64-encoded per x402 spec)
232
- const settlementBase64 = Buffer.from(JSON.stringify(settlement)).toString('base64');
233
- res.setHeader(X402_HEADERS.PAYMENT_RESPONSE, settlementBase64);
234
- // Hook: after settlement
235
- if (onAfterSettle) {
236
- return Promise.resolve(onAfterSettle(req, creditsToVerify, settlement)).then(() => settlement);
237
- }
238
- return settlement;
239
- })
224
+ // Re-evaluate dynamic credits now that the handler has run and
225
+ // res.locals is populated. For fixed (numeric) credits this is a no-op.
226
+ const settlePromise = (typeof credits === 'function'
227
+ ? Promise.resolve(credits(req, res))
228
+ : Promise.resolve(creditsToVerify)).then((creditsToSettle) => {
229
+ // Update payment context so downstream consumers see the actual value
230
+ paymentContext.creditsToSettle = creditsToSettle;
231
+ // Settle credits before sending response
232
+ // Pass agentRequestId to enable observability updates
233
+ return payments.facilitator
234
+ .settlePermissions({
235
+ paymentRequired,
236
+ x402AccessToken: token,
237
+ maxAmount: BigInt(creditsToSettle),
238
+ agentRequestId: paymentContext.agentRequestId,
239
+ })
240
+ .then((settlement) => {
241
+ // Add settlement response header (base64-encoded per x402 spec)
242
+ const settlementBase64 = Buffer.from(JSON.stringify(settlement)).toString('base64');
243
+ res.setHeader(X402_HEADERS.PAYMENT_RESPONSE, settlementBase64);
244
+ // Hook: after settlement
245
+ if (onAfterSettle) {
246
+ return Promise.resolve(onAfterSettle(req, creditsToSettle, settlement)).then(() => settlement);
247
+ }
248
+ return settlement;
249
+ });
250
+ });
251
+ settlePromise
240
252
  .catch((settleError) => {
241
253
  console.error('Payment settlement failed:', settleError);
242
254
  // Still send response even if settlement fails
@@ -1 +1 @@
1
- {"version":3,"file":"middleware.js","sourceRoot":"","sources":["../../../src/x402/express/middleware.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Express middleware for Nevermined payment protection using the x402 protocol.\n *\n * This middleware provides a simple way to protect Express routes with\n * Nevermined payment verification and settlement.\n *\n * ## x402 HTTP Transport Headers\n *\n * Following the x402 spec (https://github.com/coinbase/x402/blob/main/specs/transports-v2/http.md):\n *\n * - **Client → Server**: `payment-signature` header with base64-encoded token\n * - **Server → Client (402)**: `payment-required` header with base64-encoded PaymentRequired\n * - **Server → Client (success)**: `payment-response` header with settlement receipt\n *\n * @example\n * ```typescript\n * import express from 'express'\n * import { Payments } from '@nevermined-io/payments'\n * import { paymentMiddleware } from '@nevermined-io/payments/express'\n *\n * const app = express()\n * const payments = Payments.getInstance({ nvmApiKey: '...', environment: 'testing' })\n *\n * // Protect routes with payment middleware\n * app.use(paymentMiddleware(payments, {\n * 'POST /ask': { planId: '123', credits: 1 },\n * 'POST /generate': { planId: '123', credits: 5 },\n * }))\n *\n * // Route handlers - no payment logic needed!\n * app.post('/ask', (req, res) => res.json({ answer: '...' }))\n * ```\n *\n * @example Client usage\n * ```typescript\n * const token = await payments.x402.getX402AccessToken(planId)\n *\n * const response = await fetch('/ask', {\n * method: 'POST',\n * headers: {\n * 'Content-Type': 'application/json',\n * 'payment-signature': token.accessToken, // x402 header\n * },\n * body: JSON.stringify({ query: 'Hello!' }),\n * })\n * ```\n */\n\nimport type { Request, Response, NextFunction } from 'express'\n\n/**\n * Express middleware function type.\n * Using explicit signature instead of RequestHandler to avoid type resolution issues\n * when SDK's \\@types/express version differs from consumer's.\n */\nexport type ExpressMiddleware = (req: Request, res: Response, next: NextFunction) => void\nimport type { Payments } from '../../payments.js'\nimport type { StartAgentRequest } from '../../common/types.js'\nimport {\n buildPaymentRequired,\n type X402PaymentRequired,\n type VerifyPermissionsResult,\n} from '../facilitator-api.js'\n\n/**\n * Configuration for a protected route\n */\nexport interface RouteConfig {\n /** The Nevermined plan ID that protects this route */\n planId: string\n /** Number of credits to charge for this route (default: 1) */\n credits?: number | ((req: Request, res: Response) => number | Promise<number>)\n /** Optional agent ID */\n agentId?: string\n /** Network identifier (default: 'eip155:84532' for Base Sepolia) */\n network?: string\n}\n\n/**\n * Route configuration map: \"METHOD \\/path\" -> RouteConfig\n */\nexport type RouteConfigMap = Record<string, RouteConfig>\n\n/**\n * x402 HTTP Transport header names (v2 spec)\n * @see https://github.com/coinbase/x402/blob/main/specs/transports-v2/http.md\n */\nexport const X402_HEADERS = {\n /** Client sends payment token in this header */\n PAYMENT_SIGNATURE: 'payment-signature',\n /** Server sends PaymentRequired in this header (base64-encoded) */\n PAYMENT_REQUIRED: 'payment-required',\n /** Server sends settlement receipt in this header (base64-encoded) */\n PAYMENT_RESPONSE: 'payment-response',\n} as const\n\n/**\n * Payment context attached to the request after verification.\n * Available as `req.paymentContext` in route handlers.\n */\nexport interface PaymentContext {\n /** The x402 access token */\n token: string\n /** The payment required object */\n paymentRequired: X402PaymentRequired\n /** Number of credits to settle */\n creditsToSettle: number\n /** Whether verification was successful */\n verified: boolean\n /** Agent request context for observability (from verification response) */\n agentRequest?: StartAgentRequest\n /** Agent request ID for observability tracking */\n agentRequestId?: string\n}\n\n/**\n * Options for the payment middleware\n */\nexport interface PaymentMiddlewareOptions {\n /**\n * Header name(s) to check for the x402 access token.\n * Default: 'payment-signature' (x402 v2 compliant)\n */\n tokenHeader?: string | string[]\n /** Custom error handler for payment failures */\n onPaymentError?: (error: Error, req: Request, res: Response) => void\n /** Hook called before verification */\n onBeforeVerify?: (req: Request, paymentRequired: X402PaymentRequired) => void | Promise<void>\n /**\n * Hook called after successful verification.\n * Use this to access agentRequest for observability configuration.\n */\n onAfterVerify?: (req: Request, verification: VerifyPermissionsResult) => void | Promise<void>\n /** Hook called after successful settlement */\n onAfterSettle?: (req: Request, creditsUsed: number, result: unknown) => void | Promise<void>\n}\n\n/**\n * Default header for token extraction (x402 v2 compliant)\n */\nconst DEFAULT_TOKEN_HEADERS = [X402_HEADERS.PAYMENT_SIGNATURE]\n\n/**\n * Extract the x402 access token from the request headers.\n * Checks multiple headers in priority order.\n */\nfunction extractToken(req: Request, headerNames: string | string[]): string | null {\n const headers = Array.isArray(headerNames) ? headerNames : [headerNames]\n\n for (const headerName of headers) {\n const header = req.headers[headerName.toLowerCase()]\n if (header && typeof header === 'string') {\n return header\n }\n }\n\n return null\n}\n\n/**\n * Match a request to a route config.\n * Returns the config if found, null otherwise.\n */\nfunction matchRoute(req: Request, routes: RouteConfigMap): RouteConfig | null {\n const method = req.method.toUpperCase()\n const path = req.path\n\n // Try exact match first: \"POST /ask\"\n const exactKey = `${method} ${path}`\n if (routes[exactKey]) {\n return routes[exactKey]\n }\n\n // Try pattern matching with path parameters\n for (const [routeKey, config] of Object.entries(routes)) {\n const [routeMethod, routePath] = routeKey.split(' ')\n if (routeMethod !== method) continue\n\n // Simple pattern matching: /users/:id -> /users/123\n const routeParts = routePath.split('/')\n const pathParts = path.split('/')\n\n if (routeParts.length !== pathParts.length) continue\n\n let match = true\n for (let i = 0; i < routeParts.length; i++) {\n if (routeParts[i].startsWith(':')) continue // Parameter - always matches\n if (routeParts[i] !== pathParts[i]) {\n match = false\n break\n }\n }\n\n if (match) return config\n }\n\n return null\n}\n\n/**\n * Create an Express middleware that protects routes with Nevermined payments.\n *\n * The middleware:\n * 1. Checks if the request matches a protected route\n * 2. Extracts the x402 token from headers\n * 3. Verifies the subscriber has sufficient credits\n * 4. Lets the route handler execute\n * 5. Settles (burns) the credits after successful response\n *\n * @param payments - The Payments instance\n * @param routes - Map of routes to protect: \\{ \"METHOD \\/path\": \\{ planId, credits \\} \\}\n * @param options - Optional middleware configuration\n * @returns Express middleware function\n *\n * @example\n * ```typescript\n * app.use(paymentMiddleware(payments, {\n * 'POST /ask': { planId: PLAN_ID, credits: 1 },\n * 'POST /generate': { planId: PLAN_ID, credits: 5 },\n * 'GET /status/:id': { planId: PLAN_ID, credits: 0 }, // Free but requires auth\n * }))\n * ```\n */\n/**\n * Helper to send a 402 Payment Required response with proper x402 headers.\n */\nfunction sendPaymentRequired(\n res: Response,\n paymentRequired: X402PaymentRequired,\n message: string,\n): void {\n // Base64 encode the PaymentRequired object for the header (per x402 spec)\n const paymentRequiredBase64 = Buffer.from(JSON.stringify(paymentRequired)).toString('base64')\n\n res.status(402).setHeader(X402_HEADERS.PAYMENT_REQUIRED, paymentRequiredBase64).json({\n error: 'Payment Required',\n message,\n })\n}\n\nexport function paymentMiddleware(\n payments: Payments,\n routes: RouteConfigMap,\n options: PaymentMiddlewareOptions = {},\n): ExpressMiddleware {\n const {\n tokenHeader = DEFAULT_TOKEN_HEADERS,\n onPaymentError,\n onBeforeVerify,\n onAfterVerify,\n onAfterSettle,\n } = options\n\n return (req: Request, res: Response, next: NextFunction): void => {\n // Wrap async logic to handle promises properly\n const handleRequest = async (): Promise<void> => {\n // Check if this route requires payment\n const routeConfig = matchRoute(req, routes)\n if (!routeConfig) {\n // Route not protected - pass through\n next()\n return\n }\n\n const { planId, credits = 1, agentId, network } = routeConfig\n\n // Build payment required object (needed for both error responses and verification)\n const paymentRequired = buildPaymentRequired(planId, {\n endpoint: req.originalUrl || req.url,\n agentId,\n httpVerb: req.method,\n network,\n })\n\n // Extract token from headers (x402 v2: payment-signature)\n const token = extractToken(req, tokenHeader)\n if (!token) {\n const error = new Error('Payment required: missing x402 access token')\n if (onPaymentError) {\n onPaymentError(error, req, res)\n return\n }\n sendPaymentRequired(\n res,\n paymentRequired,\n `Missing x402 payment token. Send token in ${X402_HEADERS.PAYMENT_SIGNATURE} header.`,\n )\n return\n }\n\n // Calculate credits to verify\n const creditsToVerify = typeof credits === 'function' ? await credits(req, res) : credits\n\n try {\n // Hook: before verification\n if (onBeforeVerify) {\n await onBeforeVerify(req, paymentRequired)\n }\n\n // Verify permissions\n const verification = await payments.facilitator.verifyPermissions({\n paymentRequired,\n x402AccessToken: token,\n maxAmount: BigInt(creditsToVerify),\n })\n\n if (!verification.isValid) {\n const error = new Error(verification.invalidReason || 'Payment verification failed')\n if (onPaymentError) {\n onPaymentError(error, req, res)\n return\n }\n sendPaymentRequired(\n res,\n paymentRequired,\n verification.invalidReason || 'Insufficient credits or invalid token',\n )\n return\n }\n\n // Hook: after verification (use for observability setup)\n if (onAfterVerify) {\n await onAfterVerify(req, verification)\n }\n\n // Store payment context for settlement and route handler access\n const paymentContext: PaymentContext = {\n token,\n paymentRequired,\n creditsToSettle: creditsToVerify,\n verified: true,\n agentRequest: verification.agentRequest,\n agentRequestId: verification.agentRequest?.agentRequestId || verification.agentRequestId,\n }\n\n // Attach to request for potential use by route handler\n ;(req as Request & { paymentContext?: PaymentContext }).paymentContext = paymentContext\n\n // Override res.json to settle BEFORE sending response\n // This ensures credits are burned and payment-response header is included\n const originalJson = res.json.bind(res)\n res.json = function (body: unknown) {\n // Settle credits synchronously before sending response\n // Pass agentRequestId to enable observability updates\n payments.facilitator\n .settlePermissions({\n paymentRequired,\n x402AccessToken: token,\n maxAmount: BigInt(creditsToVerify),\n agentRequestId: paymentContext.agentRequestId,\n })\n .then((settlement) => {\n // Add settlement response header (base64-encoded per x402 spec)\n const settlementBase64 = Buffer.from(JSON.stringify(settlement)).toString('base64')\n res.setHeader(X402_HEADERS.PAYMENT_RESPONSE, settlementBase64)\n\n // Hook: after settlement\n if (onAfterSettle) {\n return Promise.resolve(onAfterSettle(req, creditsToVerify, settlement)).then(\n () => settlement,\n )\n }\n return settlement\n })\n .catch((settleError) => {\n console.error('Payment settlement failed:', settleError)\n // Still send response even if settlement fails\n })\n .finally(() => {\n // Send the actual response after settlement completes\n originalJson(body)\n })\n\n // Return res for chaining (Express pattern)\n return res\n }\n\n // Continue to route handler\n next()\n } catch (error) {\n if (onPaymentError) {\n onPaymentError(error as Error, req, res)\n return\n }\n sendPaymentRequired(\n res,\n paymentRequired,\n error instanceof Error ? error.message : 'Payment verification failed',\n )\n }\n }\n\n // Execute async handler with error handling\n handleRequest().catch(next)\n }\n}\n\nexport default paymentMiddleware\n"]}
1
+ {"version":3,"file":"middleware.js","sourceRoot":"","sources":["../../../src/x402/express/middleware.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Express middleware for Nevermined payment protection using the x402 protocol.\n *\n * This middleware provides a simple way to protect Express routes with\n * Nevermined payment verification and settlement.\n *\n * ## x402 HTTP Transport Headers\n *\n * Following the x402 spec (https://github.com/coinbase/x402/blob/main/specs/transports-v2/http.md):\n *\n * - **Client → Server**: `payment-signature` header with base64-encoded token\n * - **Server → Client (402)**: `payment-required` header with base64-encoded PaymentRequired\n * - **Server → Client (success)**: `payment-response` header with settlement receipt\n *\n * @example\n * ```typescript\n * import express from 'express'\n * import { Payments } from '@nevermined-io/payments'\n * import { paymentMiddleware } from '@nevermined-io/payments/express'\n *\n * const app = express()\n * const payments = Payments.getInstance({ nvmApiKey: '...', environment: 'testing' })\n *\n * // Protect routes with payment middleware\n * app.use(paymentMiddleware(payments, {\n * 'POST /ask': { planId: '123', credits: 1 },\n * 'POST /generate': { planId: '123', credits: 5 },\n * }))\n *\n * // Route handlers - no payment logic needed!\n * app.post('/ask', (req, res) => res.json({ answer: '...' }))\n * ```\n *\n * @example Client usage\n * ```typescript\n * const token = await payments.x402.getX402AccessToken(planId)\n *\n * const response = await fetch('/ask', {\n * method: 'POST',\n * headers: {\n * 'Content-Type': 'application/json',\n * 'payment-signature': token.accessToken, // x402 header\n * },\n * body: JSON.stringify({ query: 'Hello!' }),\n * })\n * ```\n */\n\nimport type { Request, Response, NextFunction } from 'express'\n\n/**\n * Express middleware function type.\n * Using explicit signature instead of RequestHandler to avoid type resolution issues\n * when SDK's \\@types/express version differs from consumer's.\n */\nexport type ExpressMiddleware = (req: Request, res: Response, next: NextFunction) => void\nimport type { Payments } from '../../payments.js'\nimport type { StartAgentRequest, X402SchemeType } from '../../common/types.js'\nimport {\n buildPaymentRequired,\n resolveScheme,\n type X402PaymentRequired,\n type VerifyPermissionsResult,\n} from '../facilitator-api.js'\n\n/**\n * Configuration for a protected route\n */\nexport interface RouteConfig {\n /** The Nevermined plan ID that protects this route */\n planId: string\n /** Number of credits to charge for this route (default: 1) */\n credits?: number | ((req: Request, res: Response) => number | Promise<number>)\n /** Optional agent ID */\n agentId?: string\n /** Network identifier (default: auto-derived from scheme) */\n network?: string\n /** x402 scheme override (auto-detected from plan metadata if omitted) */\n scheme?: X402SchemeType\n}\n\n/**\n * Route configuration map: \"METHOD \\/path\" -> RouteConfig\n */\nexport type RouteConfigMap = Record<string, RouteConfig>\n\n/**\n * x402 HTTP Transport header names (v2 spec)\n * @see https://github.com/coinbase/x402/blob/main/specs/transports-v2/http.md\n */\nexport const X402_HEADERS = {\n /** Client sends payment token in this header */\n PAYMENT_SIGNATURE: 'payment-signature',\n /** Server sends PaymentRequired in this header (base64-encoded) */\n PAYMENT_REQUIRED: 'payment-required',\n /** Server sends settlement receipt in this header (base64-encoded) */\n PAYMENT_RESPONSE: 'payment-response',\n} as const\n\n/**\n * Payment context attached to the request after verification.\n * Available as `req.paymentContext` in route handlers.\n */\nexport interface PaymentContext {\n /** The x402 access token */\n token: string\n /** The payment required object */\n paymentRequired: X402PaymentRequired\n /** Number of credits to settle */\n creditsToSettle: number\n /** Whether verification was successful */\n verified: boolean\n /** Agent request context for observability (from verification response) */\n agentRequest?: StartAgentRequest\n /** Agent request ID for observability tracking */\n agentRequestId?: string\n}\n\n/**\n * Options for the payment middleware\n */\nexport interface PaymentMiddlewareOptions {\n /**\n * Header name(s) to check for the x402 access token.\n * Default: 'payment-signature' (x402 v2 compliant)\n */\n tokenHeader?: string | string[]\n /** Custom error handler for payment failures */\n onPaymentError?: (error: Error, req: Request, res: Response) => void\n /** Hook called before verification */\n onBeforeVerify?: (req: Request, paymentRequired: X402PaymentRequired) => void | Promise<void>\n /**\n * Hook called after successful verification.\n * Use this to access agentRequest for observability configuration.\n */\n onAfterVerify?: (req: Request, verification: VerifyPermissionsResult) => void | Promise<void>\n /** Hook called after successful settlement */\n onAfterSettle?: (req: Request, creditsUsed: number, result: unknown) => void | Promise<void>\n}\n\n/**\n * Default header for token extraction (x402 v2 compliant)\n */\nconst DEFAULT_TOKEN_HEADERS = [X402_HEADERS.PAYMENT_SIGNATURE]\n\n/**\n * Extract the x402 access token from the request headers.\n * Checks multiple headers in priority order.\n */\nfunction extractToken(req: Request, headerNames: string | string[]): string | null {\n const headers = Array.isArray(headerNames) ? headerNames : [headerNames]\n\n for (const headerName of headers) {\n const header = req.headers[headerName.toLowerCase()]\n if (header && typeof header === 'string') {\n return header\n }\n }\n\n return null\n}\n\n/**\n * Match a request to a route config.\n * Returns the config if found, null otherwise.\n */\nfunction matchRoute(req: Request, routes: RouteConfigMap): RouteConfig | null {\n const method = req.method.toUpperCase()\n const path = req.path\n\n // Try exact match first: \"POST /ask\"\n const exactKey = `${method} ${path}`\n if (routes[exactKey]) {\n return routes[exactKey]\n }\n\n // Try pattern matching with path parameters\n for (const [routeKey, config] of Object.entries(routes)) {\n const [routeMethod, routePath] = routeKey.split(' ')\n if (routeMethod !== method) continue\n\n // Simple pattern matching: /users/:id -> /users/123\n const routeParts = routePath.split('/')\n const pathParts = path.split('/')\n\n if (routeParts.length !== pathParts.length) continue\n\n let match = true\n for (let i = 0; i < routeParts.length; i++) {\n if (routeParts[i].startsWith(':')) continue // Parameter - always matches\n if (routeParts[i] !== pathParts[i]) {\n match = false\n break\n }\n }\n\n if (match) return config\n }\n\n return null\n}\n\n/**\n * Create an Express middleware that protects routes with Nevermined payments.\n *\n * The middleware:\n * 1. Checks if the request matches a protected route\n * 2. Extracts the x402 token from headers\n * 3. Verifies the subscriber has sufficient credits\n * 4. Lets the route handler execute\n * 5. Settles (burns) the credits after successful response\n *\n * @param payments - The Payments instance\n * @param routes - Map of routes to protect: \\{ \"METHOD \\/path\": \\{ planId, credits \\} \\}\n * @param options - Optional middleware configuration\n * @returns Express middleware function\n *\n * @example\n * ```typescript\n * app.use(paymentMiddleware(payments, {\n * 'POST /ask': { planId: PLAN_ID, credits: 1 },\n * 'POST /generate': { planId: PLAN_ID, credits: 5 },\n * 'GET /status/:id': { planId: PLAN_ID, credits: 0 }, // Free but requires auth\n * }))\n * ```\n */\n/**\n * Helper to send a 402 Payment Required response with proper x402 headers.\n */\nfunction sendPaymentRequired(\n res: Response,\n paymentRequired: X402PaymentRequired,\n message: string,\n): void {\n // Base64 encode the PaymentRequired object for the header (per x402 spec)\n const paymentRequiredBase64 = Buffer.from(JSON.stringify(paymentRequired)).toString('base64')\n\n res.status(402).setHeader(X402_HEADERS.PAYMENT_REQUIRED, paymentRequiredBase64).json({\n error: 'Payment Required',\n message,\n })\n}\n\nexport function paymentMiddleware(\n payments: Payments,\n routes: RouteConfigMap,\n options: PaymentMiddlewareOptions = {},\n): ExpressMiddleware {\n const {\n tokenHeader = DEFAULT_TOKEN_HEADERS,\n onPaymentError,\n onBeforeVerify,\n onAfterVerify,\n onAfterSettle,\n } = options\n\n return (req: Request, res: Response, next: NextFunction): void => {\n // Wrap async logic to handle promises properly\n const handleRequest = async (): Promise<void> => {\n // Check if this route requires payment\n const routeConfig = matchRoute(req, routes)\n if (!routeConfig) {\n // Route not protected - pass through\n next()\n return\n }\n\n const { planId, credits = 1, agentId, network, scheme: explicitScheme } = routeConfig\n\n // Resolve scheme from plan metadata (cached) or explicit override\n const scheme = await resolveScheme(payments, planId, explicitScheme)\n\n // Build payment required object (needed for both error responses and verification)\n const paymentRequired = buildPaymentRequired(planId, {\n endpoint: req.originalUrl || req.url,\n agentId,\n httpVerb: req.method,\n network,\n scheme,\n })\n\n // Extract token from headers (x402 v2: payment-signature)\n const token = extractToken(req, tokenHeader)\n if (!token) {\n const error = new Error('Payment required: missing x402 access token')\n if (onPaymentError) {\n onPaymentError(error, req, res)\n return\n }\n sendPaymentRequired(\n res,\n paymentRequired,\n `Missing x402 payment token. Send token in ${X402_HEADERS.PAYMENT_SIGNATURE} header.`,\n )\n return\n }\n\n // Calculate credits to verify\n const creditsToVerify = typeof credits === 'function' ? await credits(req, res) : credits\n\n try {\n // Hook: before verification\n if (onBeforeVerify) {\n await onBeforeVerify(req, paymentRequired)\n }\n\n // Verify permissions\n const verification = await payments.facilitator.verifyPermissions({\n paymentRequired,\n x402AccessToken: token,\n maxAmount: BigInt(creditsToVerify),\n })\n\n if (!verification.isValid) {\n const error = new Error(verification.invalidReason || 'Payment verification failed')\n if (onPaymentError) {\n onPaymentError(error, req, res)\n return\n }\n sendPaymentRequired(\n res,\n paymentRequired,\n verification.invalidReason || 'Insufficient credits or invalid token',\n )\n return\n }\n\n // Hook: after verification (use for observability setup)\n if (onAfterVerify) {\n await onAfterVerify(req, verification)\n }\n\n // Store payment context for settlement and route handler access\n const paymentContext: PaymentContext = {\n token,\n paymentRequired,\n creditsToSettle: creditsToVerify,\n verified: true,\n agentRequest: verification.agentRequest,\n agentRequestId: verification.agentRequest?.agentRequestId || verification.agentRequestId,\n }\n\n // Attach to request for potential use by route handler\n ;(req as Request & { paymentContext?: PaymentContext }).paymentContext = paymentContext\n\n // Override res.json to settle BEFORE sending response\n // This ensures credits are burned and payment-response header is included\n const originalJson = res.json.bind(res)\n res.json = function (body: unknown) {\n // Re-evaluate dynamic credits now that the handler has run and\n // res.locals is populated. For fixed (numeric) credits this is a no-op.\n const settlePromise = (\n typeof credits === 'function'\n ? Promise.resolve(credits(req, res))\n : Promise.resolve(creditsToVerify)\n ).then((creditsToSettle) => {\n // Update payment context so downstream consumers see the actual value\n paymentContext.creditsToSettle = creditsToSettle\n\n // Settle credits before sending response\n // Pass agentRequestId to enable observability updates\n return payments.facilitator\n .settlePermissions({\n paymentRequired,\n x402AccessToken: token,\n maxAmount: BigInt(creditsToSettle),\n agentRequestId: paymentContext.agentRequestId,\n })\n .then((settlement) => {\n // Add settlement response header (base64-encoded per x402 spec)\n const settlementBase64 = Buffer.from(JSON.stringify(settlement)).toString('base64')\n res.setHeader(X402_HEADERS.PAYMENT_RESPONSE, settlementBase64)\n\n // Hook: after settlement\n if (onAfterSettle) {\n return Promise.resolve(onAfterSettle(req, creditsToSettle, settlement)).then(\n () => settlement,\n )\n }\n return settlement\n })\n })\n\n settlePromise\n .catch((settleError) => {\n console.error('Payment settlement failed:', settleError)\n // Still send response even if settlement fails\n })\n .finally(() => {\n // Send the actual response after settlement completes\n originalJson(body)\n })\n\n // Return res for chaining (Express pattern)\n return res\n }\n\n // Continue to route handler\n next()\n } catch (error) {\n if (onPaymentError) {\n onPaymentError(error as Error, req, res)\n return\n }\n sendPaymentRequired(\n res,\n paymentRequired,\n error instanceof Error ? error.message : 'Payment verification failed',\n )\n }\n }\n\n // Execute async handler with error handling\n handleRequest().catch(next)\n }\n}\n\nexport default paymentMiddleware\n"]}
@@ -41,7 +41,9 @@
41
41
  * ```
42
42
  */
43
43
  import { BasePaymentsAPI } from '../api/base-payments.js';
44
- import { PaymentOptions, StartAgentRequest } from '../common/types.js';
44
+ import { PaymentOptions, StartAgentRequest, X402SchemeType } from '../common/types.js';
45
+ import type { Payments } from '../payments.js';
46
+ import type { VisaPaymentRequired } from './visa-facilitator-api.js';
45
47
  /**
46
48
  * x402 Resource information
47
49
  */
@@ -115,8 +117,8 @@ export interface X402PaymentAccepted {
115
117
  * Parameters for verifying permissions
116
118
  */
117
119
  export interface VerifyPermissionsParams {
118
- /** The server's 402 PaymentRequired response */
119
- paymentRequired: X402PaymentRequired;
120
+ /** The server's 402 PaymentRequired response (NVM or Visa flavored) */
121
+ paymentRequired: X402PaymentRequired | VisaPaymentRequired;
120
122
  /** The X402 access token (base64-encoded) */
121
123
  x402AccessToken: string;
122
124
  /** Maximum credits to verify (optional) */
@@ -144,8 +146,8 @@ export interface VerifyPermissionsResult {
144
146
  * Parameters for settling permissions
145
147
  */
146
148
  export interface SettlePermissionsParams {
147
- /** The server's 402 PaymentRequired response */
148
- paymentRequired: X402PaymentRequired;
149
+ /** The server's 402 PaymentRequired response (NVM or Visa flavored) */
150
+ paymentRequired: X402PaymentRequired | VisaPaymentRequired;
149
151
  /** The X402 access token (base64-encoded) */
150
152
  x402AccessToken: string;
151
153
  /** Number of credits to burn (optional) */
@@ -212,7 +214,19 @@ export declare function buildPaymentRequired(planId: string, options?: {
212
214
  httpVerb?: string;
213
215
  network?: string;
214
216
  description?: string;
217
+ scheme?: X402SchemeType;
215
218
  }): X402PaymentRequired;
219
+ /**
220
+ * Resolve the x402 scheme for a plan by fetching plan metadata (cached).
221
+ * Used in callsites that don't have a token to extract scheme from
222
+ * (402 responses and token generation).
223
+ *
224
+ * @param payments - The Payments instance for API access
225
+ * @param planId - The plan identifier
226
+ * @param explicitScheme - Optional explicit override; returned immediately if provided
227
+ * @returns The resolved scheme type
228
+ */
229
+ export declare function resolveScheme(payments: Payments, planId: string, explicitScheme?: X402SchemeType): Promise<X402SchemeType>;
216
230
  /**
217
231
  * The FacilitatorAPI class provides methods to verify and settle AI agent permissions.
218
232
  * It enables AI agents to act as facilitators, managing credit verification and settlement