@nevermined-io/payments 1.13.0 → 1.14.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 (54) hide show
  1. package/dist/a2a/paymentsRequestHandler.d.ts +5 -1
  2. package/dist/a2a/paymentsRequestHandler.d.ts.map +1 -1
  3. package/dist/a2a/paymentsRequestHandler.js +156 -13
  4. package/dist/a2a/paymentsRequestHandler.js.map +1 -1
  5. package/dist/a2a/types.d.ts +25 -0
  6. package/dist/a2a/types.d.ts.map +1 -1
  7. package/dist/a2a/types.js.map +1 -1
  8. package/dist/api/agents-api.d.ts +4 -3
  9. package/dist/api/agents-api.d.ts.map +1 -1
  10. package/dist/api/agents-api.js +7 -4
  11. package/dist/api/agents-api.js.map +1 -1
  12. package/dist/api/base-payments.d.ts +7 -2
  13. package/dist/api/base-payments.d.ts.map +1 -1
  14. package/dist/api/base-payments.js +15 -8
  15. package/dist/api/base-payments.js.map +1 -1
  16. package/dist/api/nvm-api.d.ts +5 -5
  17. package/dist/api/observability-api/types.d.ts +34 -6
  18. package/dist/api/observability-api/types.d.ts.map +1 -1
  19. package/dist/api/observability-api/types.js.map +1 -1
  20. package/dist/api/plans-api.d.ts +15 -12
  21. package/dist/api/plans-api.d.ts.map +1 -1
  22. package/dist/api/plans-api.js +17 -14
  23. package/dist/api/plans-api.js.map +1 -1
  24. package/dist/api/query-api.d.ts +1 -1
  25. package/dist/common/types.d.ts +88 -18
  26. package/dist/common/types.d.ts.map +1 -1
  27. package/dist/common/types.js.map +1 -1
  28. package/dist/mcp/core/paywall.d.ts.map +1 -1
  29. package/dist/mcp/core/paywall.js +59 -8
  30. package/dist/mcp/core/paywall.js.map +1 -1
  31. package/dist/mcp/http/index.d.ts +1 -1
  32. package/dist/mcp/http/index.d.ts.map +1 -1
  33. package/dist/mcp/http/index.js +1 -1
  34. package/dist/mcp/http/index.js.map +1 -1
  35. package/dist/mcp/http/oauth-metadata.d.ts +32 -0
  36. package/dist/mcp/http/oauth-metadata.d.ts.map +1 -1
  37. package/dist/mcp/http/oauth-metadata.js +329 -34
  38. package/dist/mcp/http/oauth-metadata.js.map +1 -1
  39. package/dist/mcp/index.d.ts +4 -4
  40. package/dist/mcp/index.d.ts.map +1 -1
  41. package/dist/mcp/index.js +5 -5
  42. package/dist/mcp/index.js.map +1 -1
  43. package/dist/mcp/types/http.types.d.ts +38 -3
  44. package/dist/mcp/types/http.types.d.ts.map +1 -1
  45. package/dist/mcp/types/http.types.js.map +1 -1
  46. package/dist/mcp/types/paywall.types.d.ts +19 -3
  47. package/dist/mcp/types/paywall.types.d.ts.map +1 -1
  48. package/dist/mcp/types/paywall.types.js.map +1 -1
  49. package/dist/payments.d.ts.map +1 -1
  50. package/dist/x402/delegation-api.d.ts +5 -17
  51. package/dist/x402/delegation-api.d.ts.map +1 -1
  52. package/dist/x402/delegation-api.js +2 -2
  53. package/dist/x402/delegation-api.js.map +1 -1
  54. package/package.json +22 -13
@@ -94,7 +94,11 @@ export declare class PaymentsRequestHandler extends DefaultRequestHandler {
94
94
  * @param bearerToken - The bearer token for authentication
95
95
  * @param creditsUsed - The number of credits to burn
96
96
  * @param httpContext - Optional HTTP context with endpoint and method information
97
- * @returns Promise resolving to the redemption result
97
+ * @returns The settlement receipt, verbatim as the facilitator returned it. A
98
+ * settle the backend accepted but could not complete comes back as
99
+ * `success: false` with an `errorReason` rather than throwing — see
100
+ * {@link SettlePermissionsResult} for which fields evidence a charge under
101
+ * which billing model.
98
102
  */
99
103
  private executeRedemption;
100
104
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"paymentsRequestHandler.d.ts","sourceRoot":"","sources":["../../src/a2a/paymentsRequestHandler.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"paymentsRequestHandler.d.ts","sourceRoot":"","sources":["../../src/a2a/paymentsRequestHandler.ts"],"names":[],"mappings":"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"}
@@ -6,6 +6,121 @@ import { decodeAccessToken } from '../utils.js';
6
6
  import { buildPaymentRequired, } from '../x402/facilitator-api.js';
7
7
  import { x402A2AUtils } from './x402-a2a.js';
8
8
  const terminalStates = ['completed', 'failed', 'canceled', 'rejected'];
9
+ /**
10
+ * A decimal string, and nothing else — no sign, no whitespace, no `0x`/`1e3`,
11
+ * no fractional part. `Number()` accepts every one of those, and worse, maps the
12
+ * empty-ish family (`''`, `' '`, `null`, `[]`, `false`) to **0** rather than
13
+ * `NaN`, so `Number.isFinite` does not catch them. Publishing that 0 would say
14
+ * "you were charged nothing" on a settle we simply could not read — the same
15
+ * class of lie this helper exists to prevent on pay-as-you-go.
16
+ *
17
+ * Same reasoning, same shape as `DECIMAL_INTEGER_STRING` in `mpp/mpp-api.ts`.
18
+ */
19
+ const DECIMAL_INTEGER_STRING = /^\d+$/;
20
+ /**
21
+ * The credits a settle actually redeemed, for `event.metadata.creditsCharged`.
22
+ *
23
+ * Reads {@link SettlePermissionsResult.creditsRedeemed} per billing model rather
24
+ * than trusting it flat, because it does not mean the same thing under both:
25
+ *
26
+ * - `credits` — the plan holds a balance and `creditsRedeemed` is what came out
27
+ * of it. Report it. It can legitimately differ from the credits the request
28
+ * asked to burn (margin-based pricing), which is the whole reason to report
29
+ * the settled figure rather than the requested one.
30
+ * - `pay-as-you-go` — the plan holds no credit balance at all, so
31
+ * `creditsRedeemed` is the string `'0'` *even on a settle that charged the
32
+ * buyer*. Returning that `0` would tell a buyer they were charged nothing for
33
+ * a payment that really happened, so report nothing instead. The charge is
34
+ * referenced by `orderTx` (fiat) or `transaction` (crypto); the credits the
35
+ * request asked to burn remain on the event as `creditsUsed`, so nothing is
36
+ * lost by omitting a figure that has no meaning on this billing model.
37
+ *
38
+ * ⚠️ MCP does the OPPOSITE and that is deliberate — a settled decision (repo
39
+ * owner, on the #443 review), not drift. `_meta['nevermined/credits']` reports
40
+ * the `'0'` because it emits `billingModel` BESIDE it, so a consumer can read
41
+ * it; `creditsCharged` here has no discriminator next to it, so a bare `0`
42
+ * would say "you were charged nothing" about a charge that succeeded. Do not
43
+ * reconcile the two.
44
+ * - absent — a Nevermined API older than the discriminator (`creditsRedeemed`
45
+ * has been on the settle response since 2026-03-25, `billingModel` only since
46
+ * 2026-08-06). Apply the `credits` rule: a missing discriminator must never be
47
+ * read as pay-as-you-go.
48
+ *
49
+ * Mind the type: these are **strings**. `'0'` is truthy while `Number('0') > 0`
50
+ * is false, so a truthiness check and a numeric one disagree on exactly the
51
+ * value that matters.
52
+ *
53
+ * Three ways this returns `undefined`, and they mean different things — the
54
+ * first is a design decision, the other two are faults, which is why only the
55
+ * faults warn:
56
+ *
57
+ * 1. the billing model has no credits figure to report (pay-as-you-go, or any
58
+ * discriminator that is present and is not `credits`) — silent, by design;
59
+ * 2. `creditsRedeemed` is absent, or not a plain decimal string — warns;
60
+ * 3. the value is a decimal string too large for a JS number — warns.
61
+ *
62
+ * @param settlement - The settlement receipt as the facilitator returned it
63
+ * @returns The credits redeemed, or `undefined` per the three cases above
64
+ */
65
+ function resolveCreditsCharged(settlement) {
66
+ // ALLOWLIST, not a denylist. `=== 'pay-as-you-go'` let every other value fall
67
+ // into the credits branch and publish a `0`: `null`, `''`, `'PAY-AS-YOU-GO'`,
68
+ // a future third billing model, a non-string. The response is an unchecked
69
+ // `as SettlePermissionsResult` over `response.json()`, so the union type
70
+ // provides no runtime guarantee and the wrong values are reachable.
71
+ //
72
+ // `undefined` still means `credits` — that is the documented ruling above and
73
+ // it is preserved exactly. What changes is that a discriminator which is
74
+ // present but not `credits` now omits rather than reporting a zero.
75
+ if (settlement.billingModel !== undefined && settlement.billingModel !== 'credits') {
76
+ return undefined;
77
+ }
78
+ // A FAILED settle has no measured redemption to report, so it gets no figure.
79
+ // `settlePermissions` does not throw on one — it returns 200 with
80
+ // `success: false` verbatim — so without this a failure published
81
+ // `creditsCharged` as though it were measured: `{success: false,
82
+ // creditsRedeemed: '7'}` reported 7 credits charged for a settle that charged
83
+ // nothing. The published contract makes that a lie rather than merely noise,
84
+ // because `markdown/a2a-integration.md` defines `0` as "a real figure, not an
85
+ // absence" — a number here asserts the settle completed.
86
+ //
87
+ // ⚠️ `!== true`, not `=== false`, and the asymmetry with `billingModel` above
88
+ // is deliberate. An ABSENT `billingModel` is a documented legacy shape (APIs
89
+ // predating the field) and is read as `credits`; an absent `success` is not a
90
+ // legacy shape — the field has always been there and is declared
91
+ // non-optional — so its absence means the response is malformed, and a
92
+ // malformed response is exactly when not to publish a figure.
93
+ //
94
+ // Silent, like the pay-as-you-go branch: a failed settle is a legitimate
95
+ // outcome the caller already sees on `success`, not a reporting fault.
96
+ if (settlement.success !== true) {
97
+ return undefined;
98
+ }
99
+ const raw = settlement.creditsRedeemed;
100
+ if (typeof raw !== 'string' || !DECIMAL_INTEGER_STRING.test(raw)) {
101
+ // Silence here would be indistinguishable from the pay-as-you-go omission,
102
+ // which is a deliberate design decision rather than a fault. Warn, as
103
+ // `x402/express/middleware.ts` does on this same field.
104
+ console.warn(raw === undefined
105
+ ? `[PaymentsRequestHandler] settle reported no creditsRedeemed; omitting ` +
106
+ `creditsCharged rather than publishing a figure`
107
+ : `[PaymentsRequestHandler] settle reported an unusable creditsRedeemed ` +
108
+ `(${JSON.stringify(raw)}); omitting creditsCharged rather than publishing a figure`);
109
+ return undefined;
110
+ }
111
+ const redeemed = Number(raw);
112
+ if (!Number.isSafeInteger(redeemed)) {
113
+ // The wire carries this as a string precisely because it can exceed what a
114
+ // JS number represents. Above 2^53 the conversion is silently wrong
115
+ // (`'9007199254740993'` becomes 9007199254740992), and a wrong number is
116
+ // worse than no number: the exact value is still on the task, verbatim, in
117
+ // the `x402.payment.receipts` entry that `recordPaymentSuccess` writes.
118
+ console.warn(`[PaymentsRequestHandler] creditsRedeemed ${raw} exceeds Number.MAX_SAFE_INTEGER; ` +
119
+ `omitting creditsCharged rather than publishing a rounded figure`);
120
+ return undefined;
121
+ }
122
+ return redeemed;
123
+ }
9
124
  /**
10
125
  * PaymentsRequestHandler extends DefaultRequestHandler to add payments validation and burning.
11
126
  * It validates credits before executing a task and burns credits after successful execution.
@@ -157,7 +272,11 @@ export class PaymentsRequestHandler extends DefaultRequestHandler {
157
272
  * @param bearerToken - The bearer token for authentication
158
273
  * @param creditsUsed - The number of credits to burn
159
274
  * @param httpContext - Optional HTTP context with endpoint and method information
160
- * @returns Promise resolving to the redemption result
275
+ * @returns The settlement receipt, verbatim as the facilitator returned it. A
276
+ * settle the backend accepted but could not complete comes back as
277
+ * `success: false` with an `errorReason` rather than throwing — see
278
+ * {@link SettlePermissionsResult} for which fields evidence a charge under
279
+ * which billing model.
161
280
  */
162
281
  async executeRedemption(bearerToken, creditsUsed, httpContext) {
163
282
  const decodedAccessToken = decodeAccessToken(bearerToken);
@@ -341,7 +460,13 @@ export class PaymentsRequestHandler extends DefaultRequestHandler {
341
460
  if (!task || !httpContext?.inBand) {
342
461
  return;
343
462
  }
344
- if (settlement && settlement.success === false) {
463
+ // `!== true`, not `=== false` — the same rule as `resolveCreditsCharged` above,
464
+ // for the same reason. `success` is declared non-optional, so its absence means
465
+ // a malformed response rather than a legacy shape, and stamping one of those
466
+ // `payment-completed` publishes the settle's figures under a success banner on
467
+ // the surface a buyer is told to read for the authoritative receipt.
468
+ // `settlePermissions` already reasons this way (`src/x402/facilitator-api.ts`).
469
+ if (settlement && settlement.success !== true) {
345
470
  x402A2AUtils.recordPaymentFailure(task, settlement.errorReason || 'SETTLEMENT_FAILED', settlement);
346
471
  }
347
472
  else if (settlement) {
@@ -393,12 +518,24 @@ export class PaymentsRequestHandler extends DefaultRequestHandler {
393
518
  const httpContext = requestHttpContext ?? this.getHttpRequestContextForTask(event.taskId);
394
519
  // Execute redemption with server configuration for non-batch requests
395
520
  const response = await this.executeRedemption(bearerToken, BigInt(event.metadata.creditsUsed), httpContext);
396
- // Update event metadata with response data
521
+ // `txHash` is the A2A metadata key a buyer is shown for payment
522
+ // support; the settle response reports that id as `transaction`.
523
+ // There is no `txHash` on the wire — see handleTaskFinalization.
397
524
  if (response && event.metadata) {
398
- event.metadata.txHash = response.txHash ?? response.transaction;
399
- event.metadata.creditsCharged = response.amountOfCredits
400
- ? Number(response.amountOfCredits)
401
- : event.metadata.creditsUsed;
525
+ // Only on a settle that SUCCEEDED. `transaction` is documented as
526
+ // an empty string when settlement failed, and a blank id beside a
527
+ // completed task is the same defect as publishing `creditsCharged`
528
+ // for a settle that charged nothing — see resolveCreditsCharged.
529
+ if (response.success === true && response.transaction) {
530
+ event.metadata.txHash = response.transaction;
531
+ }
532
+ // Left unset when the billing model has no credits to report —
533
+ // see resolveCreditsCharged. `creditsUsed` still carries what
534
+ // the request asked to burn.
535
+ const creditsCharged = resolveCreditsCharged(response);
536
+ if (creditsCharged !== undefined) {
537
+ event.metadata.creditsCharged = creditsCharged;
538
+ }
402
539
  }
403
540
  // x402 v2 A2A transport: stamp the settlement receipt onto the
404
541
  // persisted task in band. NOTE: a stream cannot retract the event
@@ -632,14 +769,20 @@ export class PaymentsRequestHandler extends DefaultRequestHandler {
632
769
  // Execute redemption with server configuration for non-batch requests
633
770
  const response = await this.executeRedemption(bearerToken, BigInt(creditsToBurn), httpContext);
634
771
  settlement = response;
635
- // Update event metadata with redemption results
772
+ // Update event metadata with redemption results. `txHash` is the A2A
773
+ // metadata key, not a wire field: the settle response reports the
774
+ // transaction id as `transaction`.
775
+ const creditsCharged = resolveCreditsCharged(response);
776
+ const settled = response.success === true;
636
777
  event.metadata = {
637
778
  ...event.metadata,
638
- txHash: response.txHash ?? response.transaction,
639
- // Store the actual credits charged (especially important for margin-based)
640
- creditsCharged: response.amountOfCredits
641
- ? Number(response.amountOfCredits)
642
- : creditsToBurn,
779
+ // Same rule as `creditsCharged` below: a failed settle has no
780
+ // transaction to name, and `transaction` is an empty string there.
781
+ ...(settled && response.transaction ? { txHash: response.transaction } : {}),
782
+ // The credits actually redeemed, omitted entirely when the billing
783
+ // model has none to report — see resolveCreditsCharged. The credits
784
+ // this request asked to burn stay available as `creditsUsed`.
785
+ ...(creditsCharged !== undefined && { creditsCharged }),
643
786
  };
644
787
  }
645
788
  }
@@ -1 +1 @@
1
- {"version":3,"file":"paymentsRequestHandler.js","sourceRoot":"","sources":["../../src/a2a/paymentsRequestHandler.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n AgentCard,\n Message,\n MessageSendParams,\n PushNotificationConfig,\n Task,\n TaskArtifactUpdateEvent,\n TaskIdParams,\n TaskState,\n TaskStatusUpdateEvent,\n} from '@a2a-js/sdk'\nimport type { ExecutionEventBusManager, TaskStore } from '@a2a-js/sdk/server'\nimport {\n A2AError,\n AgentExecutor,\n DefaultRequestHandler,\n ExecutionEventBus,\n ExecutionEventQueue,\n ResultManager,\n} from '@a2a-js/sdk/server'\nimport { v4 as uuidv4 } from 'uuid'\nimport { PaymentsError } from '../common/payments.error.js'\nimport { StartAgentRequest, isValidScheme } from '../common/types.js'\nimport { 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 { x402A2AUtils } from './x402-a2a.js'\nimport type {\n A2AAuthResult,\n A2AStreamEvent,\n AgentRequestContext,\n HttpRequestContext,\n PaymentRedemptionConfig,\n PaymentsRequestContext,\n} from './types.js'\n\nconst terminalStates: TaskState[] = ['completed', 'failed', 'canceled', 'rejected']\n\n/**\n * Options for configuring the PaymentsRequestHandler\n */\nexport interface PaymentsRequestHandlerOptions {\n /** Whether to execute tasks asynchronously */\n asyncExecution?: boolean\n /** Default batch mode for all requests (can be overridden per-request) */\n defaultBatch?: boolean\n /** Default margin percentage for all requests (can be overridden per-request) */\n defaultMarginPercent?: number\n}\n\n/**\n * PaymentsRequestHandler extends DefaultRequestHandler to add payments validation and burning.\n * It validates credits before executing a task and burns credits after successful execution.\n * It also sends push notifications when a task reaches a terminal state.\n * @param options - Handler options, including asyncExecution, defaultBatch, and defaultMarginPercent\n */\nexport class PaymentsRequestHandler extends DefaultRequestHandler {\n private paymentsService: Payments\n private httpContextByTaskId: Map<string, HttpRequestContext> = new Map()\n private httpContextByMessageId: Map<string, HttpRequestContext> = new Map()\n private asyncExecution: boolean\n private defaultBatch: boolean\n private defaultMarginPercent?: number\n\n /**\n * Store HTTP context temporarily by messageId (used in middleware when taskId is not yet available).\n * @param messageId - The messageId from the incoming message\n * @param ctx - The HTTP context (bearerToken, url, method)\n */\n public setHttpRequestContextForMessage(messageId: string, ctx: HttpRequestContext) {\n this.httpContextByMessageId.set(messageId, ctx)\n }\n\n /**\n * Store HTTP context by taskId (used in middleware when taskId is available).\n * @param taskId - The taskId of the task\n * @param ctx - The HTTP context (bearerToken, url, method)\n */\n public setHttpRequestContextForTask(taskId: string, ctx: HttpRequestContext) {\n this.httpContextByTaskId.set(taskId, ctx)\n }\n\n /**\n * @param agentCard - The agent card\n * @param taskStore - The task store\n * @param agentExecutor - The business logic executor\n * @param paymentsService - The payments service for validation and burning\n * @param eventBusManager - The event bus manager (optional)\n * @param options - Handler options (asyncExecution, defaultBatch, defaultMarginPercent)\n */\n constructor(\n agentCard: AgentCard,\n taskStore: TaskStore,\n agentExecutor: AgentExecutor,\n paymentsService: any,\n eventBusManager?: ExecutionEventBusManager,\n options?: PaymentsRequestHandlerOptions,\n ) {\n super(agentCard, taskStore, agentExecutor, eventBusManager)\n this.paymentsService = paymentsService\n this.asyncExecution = options?.asyncExecution ?? false\n this.defaultBatch = options?.defaultBatch ?? false\n this.defaultMarginPercent = options?.defaultMarginPercent\n }\n\n /**\n * Retrieve the HTTP context for a given taskId.\n * @param taskId - The taskId of the task\n * @returns The HTTP context (bearerToken, url, method) or undefined\n */\n private getHttpRequestContextForTask(taskId: string): HttpRequestContext | undefined {\n return this.httpContextByTaskId.get(taskId)\n }\n\n /**\n * Retrieve the HTTP context for a given messageId.\n * @param messageId - The messageId of the message\n * @returns The HTTP context (bearerToken, url, method) or undefined\n */\n private getHttpRequestContextForMessage(messageId: string): HttpRequestContext | undefined {\n return this.httpContextByMessageId.get(messageId)\n }\n\n /**\n * Deletes the HTTP context associated with a taskId.\n * @param taskId - The taskId to delete context for\n */\n public deleteHttpRequestContextForTask(taskId: string): void {\n this.httpContextByTaskId.delete(taskId)\n }\n\n /**\n * Get the handler options (defaultBatch, defaultMarginPercent).\n * Used by middleware to determine default redemption behavior.\n * @returns The handler options\n */\n public getHandlerOptions(): PaymentsRequestHandlerOptions {\n return {\n asyncExecution: this.asyncExecution,\n defaultBatch: this.defaultBatch,\n defaultMarginPercent: this.defaultMarginPercent,\n }\n }\n\n /**\n * Validates a request using the x402 payments service.\n * This method is used by the middleware to validate credits before processing requests.\n *\n * @param bearerToken - The bearer token for authentication\n * @param endpoint - Optional endpoint URL being requested\n * @param httpVerb - Optional HTTP method being used\n * @returns Promise resolving to the validation result\n */\n public async validateRequest(\n bearerToken: string,\n endpoint?: string,\n httpVerb?: string,\n ): Promise<any> {\n let planId: string | undefined\n const agentCard = await this.getAgentCard()\n const paymentExtension = agentCard.capabilities?.extensions?.find(\n (ext: any) => ext.uri === 'urn:nevermined:payment',\n )\n if (paymentExtension) {\n planId = paymentExtension.params?.planId as string\n }\n\n const decodedAccessToken = decodeAccessToken(bearerToken)\n\n if (!decodedAccessToken) {\n throw PaymentsError.unauthorized('Invalid access token.')\n }\n\n if (!planId) {\n throw PaymentsError.unauthorized('Plan ID not found in agent card.')\n }\n\n // Extract subscriberAddress from token (payload.authorization.from per x402 spec)\n const subscriberAddress = decodedAccessToken.payload?.authorization?.from\n\n if (!subscriberAddress) {\n throw PaymentsError.unauthorized(\n 'Cannot determine subscriberAddress from token (expected payload.authorization.from)',\n )\n }\n\n const agentId = paymentExtension?.params?.agentId as string | undefined\n const scheme = isValidScheme(decodedAccessToken.accepted?.scheme)\n ? decodedAccessToken.accepted.scheme\n : 'nvm:erc4337'\n\n const paymentRequired: X402PaymentRequired = buildPaymentRequired(planId, {\n endpoint: endpoint || '',\n agentId,\n httpVerb,\n scheme,\n environment: this.paymentsService.getEnvironmentName(),\n })\n\n const result = await this.paymentsService.facilitator.verifyPermissions({\n paymentRequired,\n x402AccessToken: bearerToken,\n maxAmount: 1n,\n })\n if (!result.isValid) {\n throw PaymentsError.unauthorized('Permission verification failed.')\n }\n return {\n success: true,\n planId,\n subscriberAddress,\n balance: { isSubscriber: true },\n }\n }\n\n /**\n * Gets redemption configuration for a task based on AgentCard and handler defaults.\n * The configuration is determined by the server, not by client metadata.\n *\n * @returns The redemption configuration\n */\n private async getRedemptionConfig(): Promise<PaymentRedemptionConfig> {\n const agentCard = await this.getAgentCard()\n const paymentExtension = agentCard.capabilities?.extensions?.find(\n (ext: any) => ext.uri === 'urn:nevermined:payment',\n )\n\n const agentConfig =\n (paymentExtension?.params?.redemptionConfig as PaymentRedemptionConfig) || {}\n\n return {\n useBatch: agentConfig.useBatch ?? this.defaultBatch ?? false,\n useMargin: agentConfig.useMargin ?? false,\n marginPercent: agentConfig.marginPercent ?? this.defaultMarginPercent,\n }\n }\n\n /**\n * Determines the appropriate redemption method based on server configuration.\n *\n * @param bearerToken - The bearer token for authentication\n * @param creditsUsed - The number of credits to burn\n * @param httpContext - Optional HTTP context with endpoint and method information\n * @returns Promise resolving to the redemption result\n */\n private async executeRedemption(\n bearerToken: string,\n creditsUsed: bigint | number,\n httpContext?: HttpRequestContext,\n ): Promise<any> {\n const decodedAccessToken = decodeAccessToken(bearerToken)\n if (!decodedAccessToken) {\n throw PaymentsError.unauthorized('Invalid access token.')\n }\n\n let planId: string | undefined\n let agentId: string | undefined\n const agentCard = await this.getAgentCard()\n const paymentExtension = agentCard.capabilities?.extensions?.find(\n (ext: any) => ext.uri === 'urn:nevermined:payment',\n )\n if (paymentExtension) {\n planId = paymentExtension.params?.planId as string | undefined\n agentId = paymentExtension.params?.agentId as string | undefined\n }\n\n if (!planId) {\n throw PaymentsError.unauthorized('Plan ID not found in agent card.')\n }\n\n const scheme = isValidScheme(decodedAccessToken.accepted?.scheme)\n ? decodedAccessToken.accepted.scheme\n : 'nvm:erc4337'\n\n // Build paymentRequired using the helper\n const paymentRequired = buildPaymentRequired(planId, {\n endpoint: httpContext?.urlRequested,\n agentId,\n httpVerb: httpContext?.httpMethodRequested,\n scheme,\n environment: this.paymentsService.getEnvironmentName(),\n })\n\n return await this.paymentsService.facilitator.settlePermissions({\n paymentRequired,\n x402AccessToken: bearerToken,\n maxAmount: BigInt(creditsUsed),\n })\n }\n\n /**\n * Creates PaymentsRequestContext from message parameters.\n * This method handles HTTP context retrieval, validation, and context creation.\n * @param params - Message send parameters\n * @param isStreaming - Whether this is for streaming (affects createRequestContext call)\n * @returns Object containing PaymentsRequestContext and related data\n */\n private async createPaymentsRequestContext(\n params: MessageSendParams,\n isStreaming = false,\n ): Promise<{\n paymentsRequestContext: PaymentsRequestContext\n taskId: string\n httpContext: HttpRequestContext\n bearerToken: string\n validation: StartAgentRequest\n requestContext: any\n finalMessageForAgent: Message\n eventBus: ExecutionEventBus\n eventQueue: ExecutionEventQueue\n resultManager: ResultManager\n }> {\n // Validate required parameters before any processing\n const missingParam = !params.message\n ? 'message'\n : !params.message.messageId\n ? 'message.messageId'\n : null\n if (missingParam) {\n throw A2AError.invalidParams(`${missingParam} is required.`)\n }\n\n // 1. Get HTTP context for the task or message\n let taskId = params.message.taskId\n let httpContext: HttpRequestContext | undefined\n if (taskId) {\n httpContext = this.getHttpRequestContextForTask(taskId)\n } else {\n const messageId = params.message.messageId\n httpContext = this.getHttpRequestContextForMessage(messageId)\n }\n\n if (!httpContext) {\n throw A2AError.internalError('HTTP context not found for task or message.')\n }\n\n // 2. Extract bearer token and validate presence of required fields.\n // This path only runs for an *authorized* context (a token was supplied), so\n // both bearerToken and validation must be present — assert the invariant\n // explicitly instead of carrying an `undefined as any`.\n const { bearerToken, validation } = httpContext\n if (!bearerToken) {\n throw PaymentsError.unauthorized('Missing bearer token for payment validation.')\n }\n if (!validation) {\n throw PaymentsError.unauthorized('Missing validation context for payment.')\n }\n\n // 3. Validate credits before executing the task\n const agentCard = await this.getAgentCard()\n const agentId = agentCard.capabilities?.extensions?.find(\n (ext) => ext.uri === 'urn:nevermined:payment',\n )?.params?.agentId\n if (!agentId) {\n throw A2AError.internalError('Agent ID not found in payment extension.')\n }\n\n // 4. Generate taskId if not present and migrate HTTP context\n const incomingMessage = params.message\n if (!taskId) {\n taskId = uuidv4()\n this.migrateHttpRequestContextFromMessageToTask(params.message.messageId, taskId)\n }\n\n // 5. Instantiate ResultManager and eventBus\n const resultManager = new ResultManager(this.getTaskStore())\n resultManager.setContext(incomingMessage)\n const requestContext = await this.callCreateRequestContext(incomingMessage, taskId, isStreaming)\n const finalMessageForAgent = requestContext.userMessage\n const eventBus = this.getEventBusManager().createOrGetByTaskId(taskId)\n const eventQueue = new ExecutionEventQueue(eventBus)\n\n // 6. Create PaymentsRequestContext\n const authResult: A2AAuthResult = {\n requestId: validation.agentRequestId,\n token: bearerToken,\n agentId: validation.agentId,\n agentRequest: validation,\n }\n\n const agentRequestContext: AgentRequestContext = {\n authResult,\n httpContext,\n paymentsService: this.paymentsService,\n }\n\n // 7. Create extended request context with agent request data\n const paymentsRequestContext: PaymentsRequestContext = {\n ...requestContext,\n payments: agentRequestContext,\n }\n\n return {\n paymentsRequestContext,\n taskId,\n httpContext,\n bearerToken,\n validation,\n requestContext,\n finalMessageForAgent,\n eventBus,\n eventQueue,\n resultManager,\n }\n }\n\n /**\n * x402 v2 A2A transport: if the request is payment-gated and arrived with no\n * token (the middleware stored a `paymentRequired` on the HTTP context), build\n * and return the spec-shaped `input-required` task carrying the\n * X402PaymentRequired object under `x402.payment.required` — WITHOUT executing\n * the agent. Returns `undefined` when a token was present (normal flow).\n *\n * @param params - The incoming message send parameters\n * @returns The `input-required` Task to return to the client, or `undefined`\n */\n private async buildPaymentRequiredTaskIfNeeded(\n params: MessageSendParams,\n ): Promise<Task | undefined> {\n const message = params.message\n if (!message) {\n return undefined\n }\n const incomingTaskId = message.taskId\n const httpContext = incomingTaskId\n ? this.getHttpRequestContextForTask(incomingTaskId)\n : this.getHttpRequestContextForMessage(message.messageId)\n\n if (!httpContext?.paymentRequired) {\n return undefined\n }\n\n // Correlate the input-required task with the incoming taskId when present so\n // the client's follow-up payment payload (same taskId) maps back to it.\n const taskId = incomingTaskId || uuidv4()\n const contextId = message.contextId || uuidv4()\n const task: Task = {\n kind: 'task',\n id: taskId,\n contextId,\n status: { state: 'submitted', timestamp: new Date().toISOString() },\n history: [message],\n }\n const paymentRequiredTask = x402A2AUtils.createPaymentRequiredTask(\n task,\n httpContext.paymentRequired,\n )\n\n // Persist the input-required task so the client's follow-up (same taskId)\n // can correlate to it (otherwise the SDK's _createRequestContext raises\n // \"Task not found\"). The follow-up carries the in-band payload, so the\n // middleware overwrites this taskId's HTTP context with the authorized one.\n await this.getTaskStore().save(paymentRequiredTask)\n if (!incomingTaskId) {\n this.deleteHttpRequestContextForMessage(message.messageId)\n }\n return paymentRequiredTask\n }\n\n /**\n * Stamp x402 settlement state onto the final task's metadata, in band, per the\n * x402 v2 A2A transport. Only applied when the token arrived in band (so the\n * legacy `payment-signature` header path is unchanged). On success the task\n * carries `x402.payment.status: payment-completed` + `x402.payment.receipts`;\n * on failure `payment-failed` + `x402.payment.error` + receipts.\n *\n * @param task - The current task (mutated in place)\n * @param httpContext - The request's HTTP context\n * @param settlement - The settlement result, or undefined when none ran\n */\n private recordInBandSettlement(\n task: Task | undefined,\n httpContext: HttpRequestContext | undefined,\n settlement?: SettlePermissionsResult,\n settlementDeferred = false,\n ): void {\n if (!task || !httpContext?.inBand) {\n return\n }\n if (settlement && settlement.success === false) {\n x402A2AUtils.recordPaymentFailure(\n task,\n settlement.errorReason || 'SETTLEMENT_FAILED',\n settlement,\n )\n } else if (settlement) {\n x402A2AUtils.recordPaymentSuccess(task, settlement)\n } else if (settlementDeferred) {\n // No in-band settlement result because redemption is BATCHED: the payload was\n // verified but on-chain settlement is deferred out-of-band (this handler never\n // confirms it). Mark payment-verified + the deferred marker, NOT\n // payment-completed — so the client knows it will be charged out-of-band\n // rather than reading a completed task as \"nothing owed\".\n x402A2AUtils.recordPaymentDeferred(task)\n } else {\n // Defensive default: verified, but no settlement result AND not batch-deferred\n // (e.g. a settle that returned nothing). Record a bare verify.\n x402A2AUtils.recordPaymentVerified(task)\n }\n }\n\n /**\n * Processes streaming events with finalization (credits burning and push notifications).\n * Similar to processEventsWithFinalization but yields events for streaming.\n * @param taskId - The task ID\n * @param resultManager - The result manager\n * @param eventQueue - The event queue\n * @param bearerToken - The bearer token\n * @param validation - The validation result\n * @returns Async generator yielding processed events\n */\n protected async *processStreamingEventsWithFinalization(\n taskId: string,\n resultManager: ResultManager,\n eventQueue: ExecutionEventQueue,\n bearerToken: string,\n requestHttpContext?: HttpRequestContext,\n ): AsyncGenerator<A2AStreamEvent, void, undefined> {\n try {\n for await (const event of eventQueue.events()) {\n await resultManager.processEvent(event)\n yield event\n\n if (\n event.kind === 'status-update' &&\n event.final &&\n event?.metadata?.creditsUsed !== undefined &&\n event?.metadata?.creditsUsed !== null &&\n bearerToken &&\n (typeof event.metadata.creditsUsed === 'string' ||\n typeof event.metadata.creditsUsed === 'number' ||\n typeof event.metadata.creditsUsed === 'bigint')\n ) {\n try {\n // Get redemption configuration from server (not from client metadata)\n const redemptionConfig = await this.getRedemptionConfig()\n\n if (!redemptionConfig.useBatch) {\n // Prefer the per-request context (authoritative in-band flag); fall\n // back to a per-taskId lookup for executors that mint their own task id.\n const httpContext =\n requestHttpContext ?? this.getHttpRequestContextForTask(event.taskId)\n // Execute redemption with server configuration for non-batch requests\n const response = await this.executeRedemption(\n bearerToken,\n BigInt(event.metadata.creditsUsed),\n httpContext,\n )\n\n // Update event metadata with response data\n if (response && event.metadata) {\n event.metadata.txHash = response.txHash ?? response.transaction\n event.metadata.creditsCharged = response.amountOfCredits\n ? Number(response.amountOfCredits)\n : event.metadata.creditsUsed\n }\n\n // x402 v2 A2A transport: stamp the settlement receipt onto the\n // persisted task in band. NOTE: a stream cannot retract the event\n // it already yielded above, so an in-band settlement is reflected\n // on the saved task (visible via tasks/get + resubscribe) — it\n // cannot withhold content the way a non-streaming result does.\n if (httpContext?.inBand) {\n const task = resultManager.getCurrentTask()\n if (task) {\n this.recordInBandSettlement(\n task,\n httpContext,\n response as SettlePermissionsResult,\n )\n await resultManager.processEvent(task)\n }\n }\n } else {\n // Batch redemption: on-chain settlement is deferred out-of-band. The\n // stream already yielded the content (can't retract), but stamp the\n // PERSISTED task with payment-verified + the deferred marker so a\n // streaming client (via tasks/get + resubscribe) isn't left reading a\n // completed task as \"nothing owed\" — matching the non-streaming path.\n const httpContext =\n requestHttpContext ?? this.getHttpRequestContextForTask(event.taskId)\n if (httpContext?.inBand) {\n const task = resultManager.getCurrentTask()\n if (task) {\n this.recordInBandSettlement(task, httpContext, undefined, true)\n await resultManager.processEvent(task)\n }\n }\n }\n } catch (err) {\n // x402 v2 A2A: settlement failed AFTER the paid event was already\n // streamed to the client (a stream cannot retract it). Do NOT swallow\n // it — log, and stamp payment-failed on the persisted task so\n // tasks/get + resubscribe reflect the failure (mirrors non-streaming).\n console.error('[PaymentsA2A] streaming settlement failed after execution:', err)\n const httpContext =\n requestHttpContext ?? this.getHttpRequestContextForTask(event.taskId)\n if (httpContext?.inBand) {\n try {\n const task = resultManager.getCurrentTask()\n if (task) {\n const errorReason = err instanceof Error ? err.message : String(err)\n if (task.status) task.status.state = 'failed'\n task.artifacts = undefined\n this.recordInBandSettlement(task, httpContext, {\n success: false,\n errorReason,\n transaction: '',\n network: '',\n })\n await resultManager.processEvent(task)\n }\n } catch (stampErr) {\n console.error('[PaymentsA2A] failed to stamp streaming payment-failed:', stampErr)\n }\n }\n }\n }\n\n // Handle push notification\n if (\n event.kind === 'status-update' &&\n event.final &&\n event.status?.state &&\n terminalStates.includes(event.status.state)\n ) {\n try {\n const taskPushNotificationConfig = await this.getTaskPushNotificationConfig({\n id: event.taskId,\n })\n if (taskPushNotificationConfig) {\n await this.sendPushNotification(\n event.taskId,\n event.status.state,\n taskPushNotificationConfig.pushNotificationConfig,\n {\n contextId: event.contextId,\n },\n )\n }\n } catch (err) {\n // Do nothing\n }\n }\n }\n } finally {\n // Cleanup when the stream is fully consumed or breaks\n //this.getEventBusManager().cleanupByTaskId(taskId)\n }\n }\n\n /**\n * Processes all events, calling handleTaskFinalization when a terminal status-update event is received.\n * In async mode, it can be launched in background.\n */\n protected async processEventsWithFinalization(\n taskId: string,\n resultManager: ResultManager,\n eventQueue: ExecutionEventQueue,\n bearerToken: string,\n validation: StartAgentRequest,\n options?: {\n firstResultResolver?: (event: any) => void\n firstResultRejector?: (err: any) => void\n },\n requestHttpContext?: HttpRequestContext,\n ) {\n let firstResultSent = false\n try {\n for await (const event of eventQueue.events()) {\n // Handle redemption before processing the event\n if (\n event.kind === 'status-update' &&\n event.final &&\n terminalStates.includes(event.status?.state)\n ) {\n // Prefer the per-request HTTP context (authoritative for this request,\n // carries the in-band flag). Fall back to a per-taskId lookup for\n // executors that mint their own task id (the event's taskId may then\n // differ from the request's generated one).\n const httpContext = requestHttpContext ?? this.getHttpRequestContextForTask(event.taskId)\n await this.handleTaskFinalization(resultManager, event, bearerToken, httpContext)\n }\n\n await resultManager.processEvent(event)\n if (options?.firstResultResolver && !firstResultSent) {\n if (event.kind === 'message' || event.kind === 'task') {\n options.firstResultResolver(event)\n firstResultSent = true\n }\n }\n }\n if (options?.firstResultRejector && !firstResultSent) {\n options.firstResultRejector(\n A2AError.internalError('Execution finished before a message or task was produced.'),\n )\n }\n } catch (error) {\n if (options?.firstResultRejector && !firstResultSent) {\n options.firstResultRejector(error)\n }\n throw error\n } finally {\n this.getEventBusManager().cleanupByTaskId(taskId)\n }\n }\n\n /**\n * Sends a message, validating credits before execution and burning credits after.\n * Also sends a push notification if the task reaches a terminal state.\n * This method overrides the parent implementation to allow eventBus subscription before agent execution.\n * @param params - Message send parameters\n * @returns The resulting message or task\n */\n async sendMessage(params: MessageSendParams): Promise<Message | Task> {\n // x402 v2 A2A transport: a payment-gated request with no token returns an\n // `input-required` task (in band) instead of executing the agent.\n const paymentRequiredTask = await this.buildPaymentRequiredTaskIfNeeded(params)\n if (paymentRequiredTask) {\n return paymentRequiredTask\n }\n\n // Create PaymentsRequestContext and related data\n const {\n paymentsRequestContext,\n taskId,\n httpContext,\n bearerToken,\n validation,\n requestContext,\n finalMessageForAgent,\n eventBus,\n eventQueue,\n resultManager,\n } = await this.createPaymentsRequestContext(params, false)\n\n // Execute agent with extended context\n ;(this as any).agentExecutor\n .execute(paymentsRequestContext as any, eventBus)\n .catch((err: any) => {\n const errorTask: Task = {\n id: requestContext.task?.id || uuidv4(),\n contextId: finalMessageForAgent.contextId || uuidv4(),\n status: {\n state: 'failed',\n message: {\n kind: 'message',\n role: 'agent',\n messageId: uuidv4(),\n parts: [{ kind: 'text', text: `Agent execution error: ${err.message}` }],\n taskId: requestContext.task?.id,\n contextId: finalMessageForAgent.contextId,\n },\n timestamp: new Date().toISOString(),\n },\n history: requestContext.task?.history ? [...requestContext.task.history] : [],\n kind: 'task',\n }\n if (finalMessageForAgent) {\n if (\n !errorTask.history?.find((m: any) => m.messageId === finalMessageForAgent.messageId)\n ) {\n errorTask.history?.push(finalMessageForAgent)\n }\n }\n eventBus.publish(errorTask)\n eventBus.publish({\n kind: 'status-update',\n taskId: errorTask.id,\n contextId: errorTask.contextId,\n status: errorTask.status,\n final: true,\n })\n eventBus.finished()\n })\n\n // Determine if execution should be blocking based on client request\n // The blocking parameter comes from params.configuration.blocking\n const isBlocking = params.configuration?.blocking !== false // Default to blocking if not specified\n\n if (isBlocking) {\n await this.processEventsWithFinalization(\n taskId,\n resultManager,\n eventQueue,\n bearerToken,\n validation,\n undefined,\n httpContext,\n )\n const finalResult = resultManager.getFinalResult()\n if (!finalResult) {\n throw A2AError.internalError(\n 'Agent execution finished without a result, and no task context found.',\n )\n }\n return finalResult\n } else {\n // Non-blocking execution - return immediately with first result\n if (!taskId) {\n throw A2AError.internalError('Task ID is required for non-blocking execution.')\n }\n const validTaskId = taskId\n return new Promise((resolve, reject) => {\n this.processEventsWithFinalization(\n validTaskId,\n resultManager,\n eventQueue,\n bearerToken,\n validation,\n {\n firstResultResolver: resolve,\n firstResultRejector: reject,\n },\n httpContext,\n )\n })\n }\n }\n\n /**\n * Handles credits burning and push notification when a task reaches a terminal state.\n * This is called asynchronously from the eventBus listener.\n * Supports batch and margin-based redemptions based on server configuration.\n * @param resultManager - The result manager\n * @param event - The status-update event with final state\n * @param bearerToken - The bearer token for payment validation\n * @param validation - The validation result from the request\n */\n private async handleTaskFinalization(\n resultManager: ResultManager,\n event: TaskStatusUpdateEvent,\n bearerToken: string,\n httpContext?: HttpRequestContext,\n ) {\n const creditsToBurn = event.metadata?.creditsUsed\n if (\n creditsToBurn !== undefined &&\n creditsToBurn !== null &&\n bearerToken &&\n (typeof creditsToBurn === 'string' ||\n typeof creditsToBurn === 'number' ||\n typeof creditsToBurn === 'bigint')\n ) {\n let settlement: SettlePermissionsResult | undefined\n let settlementError: unknown\n let settlementDeferred = false\n try {\n // Get redemption configuration from server (not from client metadata)\n const redemptionConfig = await this.getRedemptionConfig()\n // Batch redemption defers on-chain settlement out-of-band (no receipt here).\n settlementDeferred = redemptionConfig.useBatch ?? false\n\n if (!redemptionConfig.useBatch) {\n // Execute redemption with server configuration for non-batch requests\n const response = await this.executeRedemption(\n bearerToken,\n BigInt(creditsToBurn),\n httpContext,\n )\n settlement = response as SettlePermissionsResult\n\n // Update event metadata with redemption results\n event.metadata = {\n ...event.metadata,\n txHash: response.txHash ?? response.transaction,\n // Store the actual credits charged (especially important for margin-based)\n creditsCharged: response.amountOfCredits\n ? Number(response.amountOfCredits)\n : creditsToBurn,\n }\n }\n } catch (err) {\n // Settlement failed AFTER the agent executed. Always log it (the legacy\n // header path has no other surface for it). For the in-band x402 v2 A2A\n // path it is additionally surfaced below as payment-failed + suppressed\n // content; the legacy header path still delivers the result (no retract).\n console.error('[PaymentsA2A] settlement failed after execution:', err)\n settlementError = err\n }\n\n // Stamp the in-band x402 state onto the FINAL event so it survives when the\n // caller processes this event into the task's status (mutating the task\n // here would be overwritten by the final event). The event carries a Task\n // shape under `event.status`; the helpers mutate `event.status.message`.\n if (httpContext?.inBand && settlementError) {\n // x402 v2 A2A transport: a settlement failure after execution must NOT\n // deliver paid content — replace the agent's status message with a\n // failed one carrying payment-failed metadata + an error receipt.\n const errorReason =\n settlementError instanceof Error ? settlementError.message : String(settlementError)\n event.status = {\n state: 'failed',\n message: {\n kind: 'message',\n messageId: uuidv4(),\n role: 'agent',\n parts: [{ kind: 'text', text: `Payment settlement failed: ${errorReason}` }],\n taskId: event.taskId,\n contextId: event.contextId,\n metadata: {},\n },\n timestamp: new Date().toISOString(),\n }\n this.recordInBandSettlement({ status: event.status } as any, httpContext, {\n success: false,\n errorReason,\n transaction: '',\n network: settlement?.network || '',\n })\n } else if (httpContext?.inBand) {\n // Stamp in-band settlement state onto the final event's status message.\n this.recordInBandSettlement(\n { status: event.status } as any,\n httpContext,\n settlement,\n settlementDeferred,\n )\n }\n\n try {\n // Always update task metadata and process the task\n const task = resultManager.getCurrentTask()\n if (task) {\n // Update task metadata with current event metadata (executor / redemption).\n task.metadata = {\n ...task.metadata,\n ...event.metadata,\n }\n\n if (httpContext?.inBand && settlementError) {\n // x402 v2 A2A transport: a settlement failure must never deliver paid\n // content. The agent's status message was already replaced above; also\n // drop any artifacts it emitted so the paid result cannot surface there\n // (mirrors the Python SDK's _apply_inband_settlement). History is rebuilt\n // by processEvent below from the replaced (failed) status, so it carries\n // no paid content.\n task.artifacts = undefined\n }\n\n await resultManager.processEvent(task)\n // Delete http context associated with the task\n this.deleteHttpRequestContextForTask(event.taskId)\n }\n } catch (err) {\n // This block persists the payment-failed/suppressed task; if it throws the\n // suppression itself failed, so log loudly rather than swallow.\n console.error('[PaymentsA2A] failed to persist finalized task:', err)\n }\n }\n try {\n const taskPushNotificationConfig = await this.getTaskPushNotificationConfig({\n id: event.taskId,\n })\n if (taskPushNotificationConfig) {\n await this.sendPushNotification(\n event.taskId,\n event.status.state,\n taskPushNotificationConfig.pushNotificationConfig,\n { contextId: event.contextId },\n )\n }\n } catch (err) {\n // Do nothing\n }\n }\n\n /**\n * Streams messages and events for a task, with payments validation.\n * Also sends a push notification if a terminal status-update event is emitted.\n * @param params - Message send parameters\n * @returns Async generator of events\n */\n async *sendMessageStream(\n params: MessageSendParams,\n ): AsyncGenerator<A2AStreamEvent, void, undefined> {\n // x402 v2 A2A transport: a payment-gated request with no token yields a\n // single `input-required` task (in band) instead of executing the agent.\n const paymentRequiredTask = await this.buildPaymentRequiredTaskIfNeeded(params)\n if (paymentRequiredTask) {\n yield paymentRequiredTask\n return\n }\n\n // Create PaymentsRequestContext and related data\n const {\n paymentsRequestContext,\n taskId,\n httpContext,\n bearerToken,\n requestContext,\n finalMessageForAgent,\n eventBus,\n eventQueue,\n resultManager,\n } = await this.createPaymentsRequestContext(params, true)\n\n // Execute agent with extended context\n ;(this as any).agentExecutor\n .execute(paymentsRequestContext as any, eventBus)\n .catch((err: any) => {\n console.error(\n `Agent execution failed for stream message ${finalMessageForAgent.messageId}:`,\n err,\n )\n const contextId = finalMessageForAgent.contextId || uuidv4()\n const errorTaskStatus: TaskStatusUpdateEvent = {\n kind: 'status-update',\n taskId: requestContext.task?.id || uuidv4(),\n contextId,\n status: {\n state: 'failed',\n message: {\n kind: 'message',\n role: 'agent',\n messageId: uuidv4(),\n parts: [{ kind: 'text', text: `Agent execution error: ${err.message}` }],\n taskId: requestContext.task?.id,\n contextId,\n },\n timestamp: new Date().toISOString(),\n },\n final: true,\n }\n eventBus.publish(errorTaskStatus)\n })\n\n // Process streaming events with finalization\n yield* this.processStreamingEventsWithFinalization(\n taskId,\n resultManager,\n eventQueue,\n bearerToken,\n httpContext,\n )\n }\n\n /**\n * Sends a push notification when a task reaches a terminal state.\n * @param taskId - The task ID\n * @param state - The terminal state\n * @param pushNotificationConfig - The push notification configuration\n * @param payload - Additional payload to include in the notification\n */\n private async sendPushNotification(\n taskId: string,\n state: TaskState,\n pushNotificationConfig: PushNotificationConfig,\n payload: Record<string, any> = {},\n ) {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n }\n if (pushNotificationConfig.authentication) {\n if (pushNotificationConfig.authentication.schemes.includes('basic')) {\n const basic = Buffer.from(`${pushNotificationConfig.authentication.credentials}`).toString(\n 'base64',\n )\n headers['Authorization'] = `Basic ${basic}`\n } else if (pushNotificationConfig.authentication.schemes.includes('bearer')) {\n headers['Authorization'] = `Bearer ${pushNotificationConfig.authentication.credentials}`\n } else if (pushNotificationConfig.authentication.schemes.includes('custom')) {\n Object.assign(headers, pushNotificationConfig.authentication.credentials)\n }\n }\n const body = JSON.stringify({\n taskId,\n state,\n payload,\n })\n const response = await fetch(pushNotificationConfig.url, {\n method: 'POST',\n headers,\n body,\n })\n if (!response.ok) {\n throw A2AError.internalError('Failed to send push notification.')\n }\n }\n\n /**\n * Migrates the HTTP context from a messageId to a taskId and deletes the temporary messageId context.\n * @param messageId - The messageId to migrate from\n * @param taskId - The taskId to migrate to\n */\n public migrateHttpRequestContextFromMessageToTask(messageId: string, taskId: string): void {\n const ctx = this.getHttpRequestContextForMessage(messageId)\n if (ctx) {\n this.setHttpRequestContextForTask(taskId, ctx)\n this.deleteHttpRequestContextForMessage(messageId)\n }\n }\n\n /**\n * Deletes the HTTP context associated with a messageId.\n * @param messageId - The messageId to delete context for\n */\n public deleteHttpRequestContextForMessage(messageId: string): void {\n this.httpContextByMessageId.delete(messageId)\n }\n\n /**\n * Protected getter to access the private taskStore property from the parent class.\n * This is a workaround due to SDK limitations.\n */\n protected getTaskStore(): TaskStore {\n return (this as any).taskStore as TaskStore\n }\n\n /**\n * Protected getter to access the private eventBusManager property from the parent class.\n * This is a workaround due to SDK limitations.\n */\n protected getEventBusManager(): ExecutionEventBusManager {\n return (this as any).eventBusManager as ExecutionEventBusManager\n }\n\n /**\n * Protected getter to access the private _createRequestContext method from the parent class.\n * This is a workaround due to SDK limitations.\n */\n protected async callCreateRequestContext(\n incomingMessage: any,\n taskId: string,\n isStream: boolean,\n ): Promise<any> {\n return await (this as any)._createRequestContext(incomingMessage, taskId, isStream)\n }\n\n /**\n * Protected getter to access the private _processEvents method from the parent class.\n * This is a workaround due to SDK limitations.\n */\n protected callProcessEvents(...args: any[]): any {\n return (this as any)._processEvents.apply(this, args)\n }\n\n /**\n * Resubscribes to a task's event stream, ensuring the task has updated metadata before yielding.\n * This method overrides the parent implementation to ensure metadata is updated before yielding.\n * @param params - Parameters containing the taskId\n * @returns Async generator of events\n */\n async *resubscribe(\n params: TaskIdParams,\n ): AsyncGenerator<Task | TaskStatusUpdateEvent | TaskArtifactUpdateEvent, void, undefined> {\n const task = await this.getTaskStore().load(params.id)\n if (!task) {\n throw A2AError.taskNotFound(params.id)\n }\n\n // Yield task immediately (with current metadata)\n yield task\n\n const finalStates: TaskState[] = ['completed', 'failed', 'canceled', 'rejected']\n if (finalStates.includes(task.status.state)) {\n return\n }\n\n const eventBus = this.getEventBusManager().getByTaskId(params.id)\n if (!eventBus) {\n console.warn(`Resubscribe: No active event bus for task ${params.id}.`)\n return\n }\n\n const eventQueue = new ExecutionEventQueue(eventBus)\n try {\n for await (const event of eventQueue.events()) {\n // Process event with ResultManager to ensure task is saved\n const resultManager = new ResultManager(this.getTaskStore())\n // Set context from task history if available\n if (task.history && task.history.length > 0) {\n resultManager.setContext(task.history[0])\n }\n await resultManager.processEvent(event)\n\n // Handle redemption and push notification for final status-update events\n if (\n event.kind === 'status-update' &&\n event.final &&\n event.taskId === params.id &&\n terminalStates.includes(event.status?.state)\n ) {\n // Get HTTP context for this task\n const httpContext = this.getHttpRequestContextForTask(event.taskId)\n if (httpContext) {\n const { bearerToken, validation } = httpContext\n if (bearerToken && validation) {\n // Handle task finalization (redemption and push notification)\n await this.handleTaskFinalization(resultManager, event, bearerToken, httpContext)\n }\n }\n }\n\n // Yield event after processing (so metadata is updated)\n if (event.kind === 'status-update' && event.taskId === params.id) {\n yield event\n } else if (event.kind === 'artifact-update' && event.taskId === params.id) {\n yield event\n } else if (event.kind === 'task' && event.id === params.id) {\n yield event\n }\n }\n } finally {\n eventQueue.stop()\n }\n }\n}\n"]}
1
+ {"version":3,"file":"paymentsRequestHandler.js","sourceRoot":"","sources":["../../src/a2a/paymentsRequestHandler.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n AgentCard,\n Message,\n MessageSendParams,\n PushNotificationConfig,\n Task,\n TaskArtifactUpdateEvent,\n TaskIdParams,\n TaskState,\n TaskStatusUpdateEvent,\n} from '@a2a-js/sdk'\nimport type { ExecutionEventBusManager, TaskStore } from '@a2a-js/sdk/server'\nimport {\n A2AError,\n AgentExecutor,\n DefaultRequestHandler,\n ExecutionEventBus,\n ExecutionEventQueue,\n ResultManager,\n} from '@a2a-js/sdk/server'\nimport { v4 as uuidv4 } from 'uuid'\nimport { PaymentsError } from '../common/payments.error.js'\nimport { StartAgentRequest, isValidScheme } from '../common/types.js'\nimport { 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 { x402A2AUtils } from './x402-a2a.js'\nimport type {\n A2AAuthResult,\n A2AStreamEvent,\n AgentRequestContext,\n HttpRequestContext,\n PaymentRedemptionConfig,\n PaymentsRequestContext,\n} from './types.js'\n\nconst terminalStates: TaskState[] = ['completed', 'failed', 'canceled', 'rejected']\n\n/**\n * A decimal string, and nothing else — no sign, no whitespace, no `0x`/`1e3`,\n * no fractional part. `Number()` accepts every one of those, and worse, maps the\n * empty-ish family (`''`, `' '`, `null`, `[]`, `false`) to **0** rather than\n * `NaN`, so `Number.isFinite` does not catch them. Publishing that 0 would say\n * \"you were charged nothing\" on a settle we simply could not read — the same\n * class of lie this helper exists to prevent on pay-as-you-go.\n *\n * Same reasoning, same shape as `DECIMAL_INTEGER_STRING` in `mpp/mpp-api.ts`.\n */\nconst DECIMAL_INTEGER_STRING = /^\\d+$/\n\n/**\n * The credits a settle actually redeemed, for `event.metadata.creditsCharged`.\n *\n * Reads {@link SettlePermissionsResult.creditsRedeemed} per billing model rather\n * than trusting it flat, because it does not mean the same thing under both:\n *\n * - `credits` — the plan holds a balance and `creditsRedeemed` is what came out\n * of it. Report it. It can legitimately differ from the credits the request\n * asked to burn (margin-based pricing), which is the whole reason to report\n * the settled figure rather than the requested one.\n * - `pay-as-you-go` — the plan holds no credit balance at all, so\n * `creditsRedeemed` is the string `'0'` *even on a settle that charged the\n * buyer*. Returning that `0` would tell a buyer they were charged nothing for\n * a payment that really happened, so report nothing instead. The charge is\n * referenced by `orderTx` (fiat) or `transaction` (crypto); the credits the\n * request asked to burn remain on the event as `creditsUsed`, so nothing is\n * lost by omitting a figure that has no meaning on this billing model.\n *\n * ⚠️ MCP does the OPPOSITE and that is deliberate — a settled decision (repo\n * owner, on the #443 review), not drift. `_meta['nevermined/credits']` reports\n * the `'0'` because it emits `billingModel` BESIDE it, so a consumer can read\n * it; `creditsCharged` here has no discriminator next to it, so a bare `0`\n * would say \"you were charged nothing\" about a charge that succeeded. Do not\n * reconcile the two.\n * - absent — a Nevermined API older than the discriminator (`creditsRedeemed`\n * has been on the settle response since 2026-03-25, `billingModel` only since\n * 2026-08-06). Apply the `credits` rule: a missing discriminator must never be\n * read as pay-as-you-go.\n *\n * Mind the type: these are **strings**. `'0'` is truthy while `Number('0') > 0`\n * is false, so a truthiness check and a numeric one disagree on exactly the\n * value that matters.\n *\n * Three ways this returns `undefined`, and they mean different things — the\n * first is a design decision, the other two are faults, which is why only the\n * faults warn:\n *\n * 1. the billing model has no credits figure to report (pay-as-you-go, or any\n * discriminator that is present and is not `credits`) — silent, by design;\n * 2. `creditsRedeemed` is absent, or not a plain decimal string — warns;\n * 3. the value is a decimal string too large for a JS number — warns.\n *\n * @param settlement - The settlement receipt as the facilitator returned it\n * @returns The credits redeemed, or `undefined` per the three cases above\n */\nfunction resolveCreditsCharged(settlement: SettlePermissionsResult): number | undefined {\n // ALLOWLIST, not a denylist. `=== 'pay-as-you-go'` let every other value fall\n // into the credits branch and publish a `0`: `null`, `''`, `'PAY-AS-YOU-GO'`,\n // a future third billing model, a non-string. The response is an unchecked\n // `as SettlePermissionsResult` over `response.json()`, so the union type\n // provides no runtime guarantee and the wrong values are reachable.\n //\n // `undefined` still means `credits` — that is the documented ruling above and\n // it is preserved exactly. What changes is that a discriminator which is\n // present but not `credits` now omits rather than reporting a zero.\n if (settlement.billingModel !== undefined && settlement.billingModel !== 'credits') {\n return undefined\n }\n\n // A FAILED settle has no measured redemption to report, so it gets no figure.\n // `settlePermissions` does not throw on one — it returns 200 with\n // `success: false` verbatim — so without this a failure published\n // `creditsCharged` as though it were measured: `{success: false,\n // creditsRedeemed: '7'}` reported 7 credits charged for a settle that charged\n // nothing. The published contract makes that a lie rather than merely noise,\n // because `markdown/a2a-integration.md` defines `0` as \"a real figure, not an\n // absence\" — a number here asserts the settle completed.\n //\n // ⚠️ `!== true`, not `=== false`, and the asymmetry with `billingModel` above\n // is deliberate. An ABSENT `billingModel` is a documented legacy shape (APIs\n // predating the field) and is read as `credits`; an absent `success` is not a\n // legacy shape — the field has always been there and is declared\n // non-optional — so its absence means the response is malformed, and a\n // malformed response is exactly when not to publish a figure.\n //\n // Silent, like the pay-as-you-go branch: a failed settle is a legitimate\n // outcome the caller already sees on `success`, not a reporting fault.\n if (settlement.success !== true) {\n return undefined\n }\n\n const raw = settlement.creditsRedeemed\n if (typeof raw !== 'string' || !DECIMAL_INTEGER_STRING.test(raw)) {\n // Silence here would be indistinguishable from the pay-as-you-go omission,\n // which is a deliberate design decision rather than a fault. Warn, as\n // `x402/express/middleware.ts` does on this same field.\n console.warn(\n raw === undefined\n ? `[PaymentsRequestHandler] settle reported no creditsRedeemed; omitting ` +\n `creditsCharged rather than publishing a figure`\n : `[PaymentsRequestHandler] settle reported an unusable creditsRedeemed ` +\n `(${JSON.stringify(raw)}); omitting creditsCharged rather than publishing a figure`,\n )\n return undefined\n }\n\n const redeemed = Number(raw)\n if (!Number.isSafeInteger(redeemed)) {\n // The wire carries this as a string precisely because it can exceed what a\n // JS number represents. Above 2^53 the conversion is silently wrong\n // (`'9007199254740993'` becomes 9007199254740992), and a wrong number is\n // worse than no number: the exact value is still on the task, verbatim, in\n // the `x402.payment.receipts` entry that `recordPaymentSuccess` writes.\n console.warn(\n `[PaymentsRequestHandler] creditsRedeemed ${raw} exceeds Number.MAX_SAFE_INTEGER; ` +\n `omitting creditsCharged rather than publishing a rounded figure`,\n )\n return undefined\n }\n\n return redeemed\n}\n\n/**\n * Options for configuring the PaymentsRequestHandler\n */\nexport interface PaymentsRequestHandlerOptions {\n /** Whether to execute tasks asynchronously */\n asyncExecution?: boolean\n /** Default batch mode for all requests (can be overridden per-request) */\n defaultBatch?: boolean\n /** Default margin percentage for all requests (can be overridden per-request) */\n defaultMarginPercent?: number\n}\n\n/**\n * PaymentsRequestHandler extends DefaultRequestHandler to add payments validation and burning.\n * It validates credits before executing a task and burns credits after successful execution.\n * It also sends push notifications when a task reaches a terminal state.\n * @param options - Handler options, including asyncExecution, defaultBatch, and defaultMarginPercent\n */\nexport class PaymentsRequestHandler extends DefaultRequestHandler {\n private paymentsService: Payments\n private httpContextByTaskId: Map<string, HttpRequestContext> = new Map()\n private httpContextByMessageId: Map<string, HttpRequestContext> = new Map()\n private asyncExecution: boolean\n private defaultBatch: boolean\n private defaultMarginPercent?: number\n\n /**\n * Store HTTP context temporarily by messageId (used in middleware when taskId is not yet available).\n * @param messageId - The messageId from the incoming message\n * @param ctx - The HTTP context (bearerToken, url, method)\n */\n public setHttpRequestContextForMessage(messageId: string, ctx: HttpRequestContext) {\n this.httpContextByMessageId.set(messageId, ctx)\n }\n\n /**\n * Store HTTP context by taskId (used in middleware when taskId is available).\n * @param taskId - The taskId of the task\n * @param ctx - The HTTP context (bearerToken, url, method)\n */\n public setHttpRequestContextForTask(taskId: string, ctx: HttpRequestContext) {\n this.httpContextByTaskId.set(taskId, ctx)\n }\n\n /**\n * @param agentCard - The agent card\n * @param taskStore - The task store\n * @param agentExecutor - The business logic executor\n * @param paymentsService - The payments service for validation and burning\n * @param eventBusManager - The event bus manager (optional)\n * @param options - Handler options (asyncExecution, defaultBatch, defaultMarginPercent)\n */\n constructor(\n agentCard: AgentCard,\n taskStore: TaskStore,\n agentExecutor: AgentExecutor,\n paymentsService: any,\n eventBusManager?: ExecutionEventBusManager,\n options?: PaymentsRequestHandlerOptions,\n ) {\n super(agentCard, taskStore, agentExecutor, eventBusManager)\n this.paymentsService = paymentsService\n this.asyncExecution = options?.asyncExecution ?? false\n this.defaultBatch = options?.defaultBatch ?? false\n this.defaultMarginPercent = options?.defaultMarginPercent\n }\n\n /**\n * Retrieve the HTTP context for a given taskId.\n * @param taskId - The taskId of the task\n * @returns The HTTP context (bearerToken, url, method) or undefined\n */\n private getHttpRequestContextForTask(taskId: string): HttpRequestContext | undefined {\n return this.httpContextByTaskId.get(taskId)\n }\n\n /**\n * Retrieve the HTTP context for a given messageId.\n * @param messageId - The messageId of the message\n * @returns The HTTP context (bearerToken, url, method) or undefined\n */\n private getHttpRequestContextForMessage(messageId: string): HttpRequestContext | undefined {\n return this.httpContextByMessageId.get(messageId)\n }\n\n /**\n * Deletes the HTTP context associated with a taskId.\n * @param taskId - The taskId to delete context for\n */\n public deleteHttpRequestContextForTask(taskId: string): void {\n this.httpContextByTaskId.delete(taskId)\n }\n\n /**\n * Get the handler options (defaultBatch, defaultMarginPercent).\n * Used by middleware to determine default redemption behavior.\n * @returns The handler options\n */\n public getHandlerOptions(): PaymentsRequestHandlerOptions {\n return {\n asyncExecution: this.asyncExecution,\n defaultBatch: this.defaultBatch,\n defaultMarginPercent: this.defaultMarginPercent,\n }\n }\n\n /**\n * Validates a request using the x402 payments service.\n * This method is used by the middleware to validate credits before processing requests.\n *\n * @param bearerToken - The bearer token for authentication\n * @param endpoint - Optional endpoint URL being requested\n * @param httpVerb - Optional HTTP method being used\n * @returns Promise resolving to the validation result\n */\n public async validateRequest(\n bearerToken: string,\n endpoint?: string,\n httpVerb?: string,\n ): Promise<any> {\n let planId: string | undefined\n const agentCard = await this.getAgentCard()\n const paymentExtension = agentCard.capabilities?.extensions?.find(\n (ext: any) => ext.uri === 'urn:nevermined:payment',\n )\n if (paymentExtension) {\n planId = paymentExtension.params?.planId as string\n }\n\n const decodedAccessToken = decodeAccessToken(bearerToken)\n\n if (!decodedAccessToken) {\n throw PaymentsError.unauthorized('Invalid access token.')\n }\n\n if (!planId) {\n throw PaymentsError.unauthorized('Plan ID not found in agent card.')\n }\n\n // Extract subscriberAddress from token (payload.authorization.from per x402 spec)\n const subscriberAddress = decodedAccessToken.payload?.authorization?.from\n\n if (!subscriberAddress) {\n throw PaymentsError.unauthorized(\n 'Cannot determine subscriberAddress from token (expected payload.authorization.from)',\n )\n }\n\n const agentId = paymentExtension?.params?.agentId as string | undefined\n const scheme = isValidScheme(decodedAccessToken.accepted?.scheme)\n ? decodedAccessToken.accepted.scheme\n : 'nvm:erc4337'\n\n const paymentRequired: X402PaymentRequired = buildPaymentRequired(planId, {\n endpoint: endpoint || '',\n agentId,\n httpVerb,\n scheme,\n environment: this.paymentsService.getEnvironmentName(),\n })\n\n const result = await this.paymentsService.facilitator.verifyPermissions({\n paymentRequired,\n x402AccessToken: bearerToken,\n maxAmount: 1n,\n })\n if (!result.isValid) {\n throw PaymentsError.unauthorized('Permission verification failed.')\n }\n return {\n success: true,\n planId,\n subscriberAddress,\n balance: { isSubscriber: true },\n }\n }\n\n /**\n * Gets redemption configuration for a task based on AgentCard and handler defaults.\n * The configuration is determined by the server, not by client metadata.\n *\n * @returns The redemption configuration\n */\n private async getRedemptionConfig(): Promise<PaymentRedemptionConfig> {\n const agentCard = await this.getAgentCard()\n const paymentExtension = agentCard.capabilities?.extensions?.find(\n (ext: any) => ext.uri === 'urn:nevermined:payment',\n )\n\n const agentConfig =\n (paymentExtension?.params?.redemptionConfig as PaymentRedemptionConfig) || {}\n\n return {\n useBatch: agentConfig.useBatch ?? this.defaultBatch ?? false,\n useMargin: agentConfig.useMargin ?? false,\n marginPercent: agentConfig.marginPercent ?? this.defaultMarginPercent,\n }\n }\n\n /**\n * Determines the appropriate redemption method based on server configuration.\n *\n * @param bearerToken - The bearer token for authentication\n * @param creditsUsed - The number of credits to burn\n * @param httpContext - Optional HTTP context with endpoint and method information\n * @returns The settlement receipt, verbatim as the facilitator returned it. A\n * settle the backend accepted but could not complete comes back as\n * `success: false` with an `errorReason` rather than throwing — see\n * {@link SettlePermissionsResult} for which fields evidence a charge under\n * which billing model.\n */\n private async executeRedemption(\n bearerToken: string,\n creditsUsed: bigint | number,\n httpContext?: HttpRequestContext,\n ): Promise<SettlePermissionsResult> {\n const decodedAccessToken = decodeAccessToken(bearerToken)\n if (!decodedAccessToken) {\n throw PaymentsError.unauthorized('Invalid access token.')\n }\n\n let planId: string | undefined\n let agentId: string | undefined\n const agentCard = await this.getAgentCard()\n const paymentExtension = agentCard.capabilities?.extensions?.find(\n (ext: any) => ext.uri === 'urn:nevermined:payment',\n )\n if (paymentExtension) {\n planId = paymentExtension.params?.planId as string | undefined\n agentId = paymentExtension.params?.agentId as string | undefined\n }\n\n if (!planId) {\n throw PaymentsError.unauthorized('Plan ID not found in agent card.')\n }\n\n const scheme = isValidScheme(decodedAccessToken.accepted?.scheme)\n ? decodedAccessToken.accepted.scheme\n : 'nvm:erc4337'\n\n // Build paymentRequired using the helper\n const paymentRequired = buildPaymentRequired(planId, {\n endpoint: httpContext?.urlRequested,\n agentId,\n httpVerb: httpContext?.httpMethodRequested,\n scheme,\n environment: this.paymentsService.getEnvironmentName(),\n })\n\n return await this.paymentsService.facilitator.settlePermissions({\n paymentRequired,\n x402AccessToken: bearerToken,\n maxAmount: BigInt(creditsUsed),\n })\n }\n\n /**\n * Creates PaymentsRequestContext from message parameters.\n * This method handles HTTP context retrieval, validation, and context creation.\n * @param params - Message send parameters\n * @param isStreaming - Whether this is for streaming (affects createRequestContext call)\n * @returns Object containing PaymentsRequestContext and related data\n */\n private async createPaymentsRequestContext(\n params: MessageSendParams,\n isStreaming = false,\n ): Promise<{\n paymentsRequestContext: PaymentsRequestContext\n taskId: string\n httpContext: HttpRequestContext\n bearerToken: string\n validation: StartAgentRequest\n requestContext: any\n finalMessageForAgent: Message\n eventBus: ExecutionEventBus\n eventQueue: ExecutionEventQueue\n resultManager: ResultManager\n }> {\n // Validate required parameters before any processing\n const missingParam = !params.message\n ? 'message'\n : !params.message.messageId\n ? 'message.messageId'\n : null\n if (missingParam) {\n throw A2AError.invalidParams(`${missingParam} is required.`)\n }\n\n // 1. Get HTTP context for the task or message\n let taskId = params.message.taskId\n let httpContext: HttpRequestContext | undefined\n if (taskId) {\n httpContext = this.getHttpRequestContextForTask(taskId)\n } else {\n const messageId = params.message.messageId\n httpContext = this.getHttpRequestContextForMessage(messageId)\n }\n\n if (!httpContext) {\n throw A2AError.internalError('HTTP context not found for task or message.')\n }\n\n // 2. Extract bearer token and validate presence of required fields.\n // This path only runs for an *authorized* context (a token was supplied), so\n // both bearerToken and validation must be present — assert the invariant\n // explicitly instead of carrying an `undefined as any`.\n const { bearerToken, validation } = httpContext\n if (!bearerToken) {\n throw PaymentsError.unauthorized('Missing bearer token for payment validation.')\n }\n if (!validation) {\n throw PaymentsError.unauthorized('Missing validation context for payment.')\n }\n\n // 3. Validate credits before executing the task\n const agentCard = await this.getAgentCard()\n const agentId = agentCard.capabilities?.extensions?.find(\n (ext) => ext.uri === 'urn:nevermined:payment',\n )?.params?.agentId\n if (!agentId) {\n throw A2AError.internalError('Agent ID not found in payment extension.')\n }\n\n // 4. Generate taskId if not present and migrate HTTP context\n const incomingMessage = params.message\n if (!taskId) {\n taskId = uuidv4()\n this.migrateHttpRequestContextFromMessageToTask(params.message.messageId, taskId)\n }\n\n // 5. Instantiate ResultManager and eventBus\n const resultManager = new ResultManager(this.getTaskStore())\n resultManager.setContext(incomingMessage)\n const requestContext = await this.callCreateRequestContext(incomingMessage, taskId, isStreaming)\n const finalMessageForAgent = requestContext.userMessage\n const eventBus = this.getEventBusManager().createOrGetByTaskId(taskId)\n const eventQueue = new ExecutionEventQueue(eventBus)\n\n // 6. Create PaymentsRequestContext\n const authResult: A2AAuthResult = {\n requestId: validation.agentRequestId,\n token: bearerToken,\n agentId: validation.agentId,\n agentRequest: validation,\n }\n\n const agentRequestContext: AgentRequestContext = {\n authResult,\n httpContext,\n paymentsService: this.paymentsService,\n }\n\n // 7. Create extended request context with agent request data\n const paymentsRequestContext: PaymentsRequestContext = {\n ...requestContext,\n payments: agentRequestContext,\n }\n\n return {\n paymentsRequestContext,\n taskId,\n httpContext,\n bearerToken,\n validation,\n requestContext,\n finalMessageForAgent,\n eventBus,\n eventQueue,\n resultManager,\n }\n }\n\n /**\n * x402 v2 A2A transport: if the request is payment-gated and arrived with no\n * token (the middleware stored a `paymentRequired` on the HTTP context), build\n * and return the spec-shaped `input-required` task carrying the\n * X402PaymentRequired object under `x402.payment.required` — WITHOUT executing\n * the agent. Returns `undefined` when a token was present (normal flow).\n *\n * @param params - The incoming message send parameters\n * @returns The `input-required` Task to return to the client, or `undefined`\n */\n private async buildPaymentRequiredTaskIfNeeded(\n params: MessageSendParams,\n ): Promise<Task | undefined> {\n const message = params.message\n if (!message) {\n return undefined\n }\n const incomingTaskId = message.taskId\n const httpContext = incomingTaskId\n ? this.getHttpRequestContextForTask(incomingTaskId)\n : this.getHttpRequestContextForMessage(message.messageId)\n\n if (!httpContext?.paymentRequired) {\n return undefined\n }\n\n // Correlate the input-required task with the incoming taskId when present so\n // the client's follow-up payment payload (same taskId) maps back to it.\n const taskId = incomingTaskId || uuidv4()\n const contextId = message.contextId || uuidv4()\n const task: Task = {\n kind: 'task',\n id: taskId,\n contextId,\n status: { state: 'submitted', timestamp: new Date().toISOString() },\n history: [message],\n }\n const paymentRequiredTask = x402A2AUtils.createPaymentRequiredTask(\n task,\n httpContext.paymentRequired,\n )\n\n // Persist the input-required task so the client's follow-up (same taskId)\n // can correlate to it (otherwise the SDK's _createRequestContext raises\n // \"Task not found\"). The follow-up carries the in-band payload, so the\n // middleware overwrites this taskId's HTTP context with the authorized one.\n await this.getTaskStore().save(paymentRequiredTask)\n if (!incomingTaskId) {\n this.deleteHttpRequestContextForMessage(message.messageId)\n }\n return paymentRequiredTask\n }\n\n /**\n * Stamp x402 settlement state onto the final task's metadata, in band, per the\n * x402 v2 A2A transport. Only applied when the token arrived in band (so the\n * legacy `payment-signature` header path is unchanged). On success the task\n * carries `x402.payment.status: payment-completed` + `x402.payment.receipts`;\n * on failure `payment-failed` + `x402.payment.error` + receipts.\n *\n * @param task - The current task (mutated in place)\n * @param httpContext - The request's HTTP context\n * @param settlement - The settlement result, or undefined when none ran\n */\n private recordInBandSettlement(\n task: Task | undefined,\n httpContext: HttpRequestContext | undefined,\n settlement?: SettlePermissionsResult,\n settlementDeferred = false,\n ): void {\n if (!task || !httpContext?.inBand) {\n return\n }\n // `!== true`, not `=== false` — the same rule as `resolveCreditsCharged` above,\n // for the same reason. `success` is declared non-optional, so its absence means\n // a malformed response rather than a legacy shape, and stamping one of those\n // `payment-completed` publishes the settle's figures under a success banner on\n // the surface a buyer is told to read for the authoritative receipt.\n // `settlePermissions` already reasons this way (`src/x402/facilitator-api.ts`).\n if (settlement && settlement.success !== true) {\n x402A2AUtils.recordPaymentFailure(\n task,\n settlement.errorReason || 'SETTLEMENT_FAILED',\n settlement,\n )\n } else if (settlement) {\n x402A2AUtils.recordPaymentSuccess(task, settlement)\n } else if (settlementDeferred) {\n // No in-band settlement result because redemption is BATCHED: the payload was\n // verified but on-chain settlement is deferred out-of-band (this handler never\n // confirms it). Mark payment-verified + the deferred marker, NOT\n // payment-completed — so the client knows it will be charged out-of-band\n // rather than reading a completed task as \"nothing owed\".\n x402A2AUtils.recordPaymentDeferred(task)\n } else {\n // Defensive default: verified, but no settlement result AND not batch-deferred\n // (e.g. a settle that returned nothing). Record a bare verify.\n x402A2AUtils.recordPaymentVerified(task)\n }\n }\n\n /**\n * Processes streaming events with finalization (credits burning and push notifications).\n * Similar to processEventsWithFinalization but yields events for streaming.\n * @param taskId - The task ID\n * @param resultManager - The result manager\n * @param eventQueue - The event queue\n * @param bearerToken - The bearer token\n * @param validation - The validation result\n * @returns Async generator yielding processed events\n */\n protected async *processStreamingEventsWithFinalization(\n taskId: string,\n resultManager: ResultManager,\n eventQueue: ExecutionEventQueue,\n bearerToken: string,\n requestHttpContext?: HttpRequestContext,\n ): AsyncGenerator<A2AStreamEvent, void, undefined> {\n try {\n for await (const event of eventQueue.events()) {\n await resultManager.processEvent(event)\n yield event\n\n if (\n event.kind === 'status-update' &&\n event.final &&\n event?.metadata?.creditsUsed !== undefined &&\n event?.metadata?.creditsUsed !== null &&\n bearerToken &&\n (typeof event.metadata.creditsUsed === 'string' ||\n typeof event.metadata.creditsUsed === 'number' ||\n typeof event.metadata.creditsUsed === 'bigint')\n ) {\n try {\n // Get redemption configuration from server (not from client metadata)\n const redemptionConfig = await this.getRedemptionConfig()\n\n if (!redemptionConfig.useBatch) {\n // Prefer the per-request context (authoritative in-band flag); fall\n // back to a per-taskId lookup for executors that mint their own task id.\n const httpContext =\n requestHttpContext ?? this.getHttpRequestContextForTask(event.taskId)\n // Execute redemption with server configuration for non-batch requests\n const response = await this.executeRedemption(\n bearerToken,\n BigInt(event.metadata.creditsUsed),\n httpContext,\n )\n\n // `txHash` is the A2A metadata key a buyer is shown for payment\n // support; the settle response reports that id as `transaction`.\n // There is no `txHash` on the wire — see handleTaskFinalization.\n if (response && event.metadata) {\n // Only on a settle that SUCCEEDED. `transaction` is documented as\n // an empty string when settlement failed, and a blank id beside a\n // completed task is the same defect as publishing `creditsCharged`\n // for a settle that charged nothing — see resolveCreditsCharged.\n if (response.success === true && response.transaction) {\n event.metadata.txHash = response.transaction\n }\n // Left unset when the billing model has no credits to report —\n // see resolveCreditsCharged. `creditsUsed` still carries what\n // the request asked to burn.\n const creditsCharged = resolveCreditsCharged(response)\n if (creditsCharged !== undefined) {\n event.metadata.creditsCharged = creditsCharged\n }\n }\n\n // x402 v2 A2A transport: stamp the settlement receipt onto the\n // persisted task in band. NOTE: a stream cannot retract the event\n // it already yielded above, so an in-band settlement is reflected\n // on the saved task (visible via tasks/get + resubscribe) — it\n // cannot withhold content the way a non-streaming result does.\n if (httpContext?.inBand) {\n const task = resultManager.getCurrentTask()\n if (task) {\n this.recordInBandSettlement(task, httpContext, response)\n await resultManager.processEvent(task)\n }\n }\n } else {\n // Batch redemption: on-chain settlement is deferred out-of-band. The\n // stream already yielded the content (can't retract), but stamp the\n // PERSISTED task with payment-verified + the deferred marker so a\n // streaming client (via tasks/get + resubscribe) isn't left reading a\n // completed task as \"nothing owed\" — matching the non-streaming path.\n const httpContext =\n requestHttpContext ?? this.getHttpRequestContextForTask(event.taskId)\n if (httpContext?.inBand) {\n const task = resultManager.getCurrentTask()\n if (task) {\n this.recordInBandSettlement(task, httpContext, undefined, true)\n await resultManager.processEvent(task)\n }\n }\n }\n } catch (err) {\n // x402 v2 A2A: settlement failed AFTER the paid event was already\n // streamed to the client (a stream cannot retract it). Do NOT swallow\n // it — log, and stamp payment-failed on the persisted task so\n // tasks/get + resubscribe reflect the failure (mirrors non-streaming).\n console.error('[PaymentsA2A] streaming settlement failed after execution:', err)\n const httpContext =\n requestHttpContext ?? this.getHttpRequestContextForTask(event.taskId)\n if (httpContext?.inBand) {\n try {\n const task = resultManager.getCurrentTask()\n if (task) {\n const errorReason = err instanceof Error ? err.message : String(err)\n if (task.status) task.status.state = 'failed'\n task.artifacts = undefined\n this.recordInBandSettlement(task, httpContext, {\n success: false,\n errorReason,\n transaction: '',\n network: '',\n })\n await resultManager.processEvent(task)\n }\n } catch (stampErr) {\n console.error('[PaymentsA2A] failed to stamp streaming payment-failed:', stampErr)\n }\n }\n }\n }\n\n // Handle push notification\n if (\n event.kind === 'status-update' &&\n event.final &&\n event.status?.state &&\n terminalStates.includes(event.status.state)\n ) {\n try {\n const taskPushNotificationConfig = await this.getTaskPushNotificationConfig({\n id: event.taskId,\n })\n if (taskPushNotificationConfig) {\n await this.sendPushNotification(\n event.taskId,\n event.status.state,\n taskPushNotificationConfig.pushNotificationConfig,\n {\n contextId: event.contextId,\n },\n )\n }\n } catch (err) {\n // Do nothing\n }\n }\n }\n } finally {\n // Cleanup when the stream is fully consumed or breaks\n //this.getEventBusManager().cleanupByTaskId(taskId)\n }\n }\n\n /**\n * Processes all events, calling handleTaskFinalization when a terminal status-update event is received.\n * In async mode, it can be launched in background.\n */\n protected async processEventsWithFinalization(\n taskId: string,\n resultManager: ResultManager,\n eventQueue: ExecutionEventQueue,\n bearerToken: string,\n validation: StartAgentRequest,\n options?: {\n firstResultResolver?: (event: any) => void\n firstResultRejector?: (err: any) => void\n },\n requestHttpContext?: HttpRequestContext,\n ) {\n let firstResultSent = false\n try {\n for await (const event of eventQueue.events()) {\n // Handle redemption before processing the event\n if (\n event.kind === 'status-update' &&\n event.final &&\n terminalStates.includes(event.status?.state)\n ) {\n // Prefer the per-request HTTP context (authoritative for this request,\n // carries the in-band flag). Fall back to a per-taskId lookup for\n // executors that mint their own task id (the event's taskId may then\n // differ from the request's generated one).\n const httpContext = requestHttpContext ?? this.getHttpRequestContextForTask(event.taskId)\n await this.handleTaskFinalization(resultManager, event, bearerToken, httpContext)\n }\n\n await resultManager.processEvent(event)\n if (options?.firstResultResolver && !firstResultSent) {\n if (event.kind === 'message' || event.kind === 'task') {\n options.firstResultResolver(event)\n firstResultSent = true\n }\n }\n }\n if (options?.firstResultRejector && !firstResultSent) {\n options.firstResultRejector(\n A2AError.internalError('Execution finished before a message or task was produced.'),\n )\n }\n } catch (error) {\n if (options?.firstResultRejector && !firstResultSent) {\n options.firstResultRejector(error)\n }\n throw error\n } finally {\n this.getEventBusManager().cleanupByTaskId(taskId)\n }\n }\n\n /**\n * Sends a message, validating credits before execution and burning credits after.\n * Also sends a push notification if the task reaches a terminal state.\n * This method overrides the parent implementation to allow eventBus subscription before agent execution.\n * @param params - Message send parameters\n * @returns The resulting message or task\n */\n async sendMessage(params: MessageSendParams): Promise<Message | Task> {\n // x402 v2 A2A transport: a payment-gated request with no token returns an\n // `input-required` task (in band) instead of executing the agent.\n const paymentRequiredTask = await this.buildPaymentRequiredTaskIfNeeded(params)\n if (paymentRequiredTask) {\n return paymentRequiredTask\n }\n\n // Create PaymentsRequestContext and related data\n const {\n paymentsRequestContext,\n taskId,\n httpContext,\n bearerToken,\n validation,\n requestContext,\n finalMessageForAgent,\n eventBus,\n eventQueue,\n resultManager,\n } = await this.createPaymentsRequestContext(params, false)\n\n // Execute agent with extended context\n ;(this as any).agentExecutor\n .execute(paymentsRequestContext as any, eventBus)\n .catch((err: any) => {\n const errorTask: Task = {\n id: requestContext.task?.id || uuidv4(),\n contextId: finalMessageForAgent.contextId || uuidv4(),\n status: {\n state: 'failed',\n message: {\n kind: 'message',\n role: 'agent',\n messageId: uuidv4(),\n parts: [{ kind: 'text', text: `Agent execution error: ${err.message}` }],\n taskId: requestContext.task?.id,\n contextId: finalMessageForAgent.contextId,\n },\n timestamp: new Date().toISOString(),\n },\n history: requestContext.task?.history ? [...requestContext.task.history] : [],\n kind: 'task',\n }\n if (finalMessageForAgent) {\n if (\n !errorTask.history?.find((m: any) => m.messageId === finalMessageForAgent.messageId)\n ) {\n errorTask.history?.push(finalMessageForAgent)\n }\n }\n eventBus.publish(errorTask)\n eventBus.publish({\n kind: 'status-update',\n taskId: errorTask.id,\n contextId: errorTask.contextId,\n status: errorTask.status,\n final: true,\n })\n eventBus.finished()\n })\n\n // Determine if execution should be blocking based on client request\n // The blocking parameter comes from params.configuration.blocking\n const isBlocking = params.configuration?.blocking !== false // Default to blocking if not specified\n\n if (isBlocking) {\n await this.processEventsWithFinalization(\n taskId,\n resultManager,\n eventQueue,\n bearerToken,\n validation,\n undefined,\n httpContext,\n )\n const finalResult = resultManager.getFinalResult()\n if (!finalResult) {\n throw A2AError.internalError(\n 'Agent execution finished without a result, and no task context found.',\n )\n }\n return finalResult\n } else {\n // Non-blocking execution - return immediately with first result\n if (!taskId) {\n throw A2AError.internalError('Task ID is required for non-blocking execution.')\n }\n const validTaskId = taskId\n return new Promise((resolve, reject) => {\n this.processEventsWithFinalization(\n validTaskId,\n resultManager,\n eventQueue,\n bearerToken,\n validation,\n {\n firstResultResolver: resolve,\n firstResultRejector: reject,\n },\n httpContext,\n )\n })\n }\n }\n\n /**\n * Handles credits burning and push notification when a task reaches a terminal state.\n * This is called asynchronously from the eventBus listener.\n * Supports batch and margin-based redemptions based on server configuration.\n * @param resultManager - The result manager\n * @param event - The status-update event with final state\n * @param bearerToken - The bearer token for payment validation\n * @param validation - The validation result from the request\n */\n private async handleTaskFinalization(\n resultManager: ResultManager,\n event: TaskStatusUpdateEvent,\n bearerToken: string,\n httpContext?: HttpRequestContext,\n ) {\n const creditsToBurn = event.metadata?.creditsUsed\n if (\n creditsToBurn !== undefined &&\n creditsToBurn !== null &&\n bearerToken &&\n (typeof creditsToBurn === 'string' ||\n typeof creditsToBurn === 'number' ||\n typeof creditsToBurn === 'bigint')\n ) {\n let settlement: SettlePermissionsResult | undefined\n let settlementError: unknown\n let settlementDeferred = false\n try {\n // Get redemption configuration from server (not from client metadata)\n const redemptionConfig = await this.getRedemptionConfig()\n // Batch redemption defers on-chain settlement out-of-band (no receipt here).\n settlementDeferred = redemptionConfig.useBatch ?? false\n\n if (!redemptionConfig.useBatch) {\n // Execute redemption with server configuration for non-batch requests\n const response = await this.executeRedemption(\n bearerToken,\n BigInt(creditsToBurn),\n httpContext,\n )\n settlement = response\n\n // Update event metadata with redemption results. `txHash` is the A2A\n // metadata key, not a wire field: the settle response reports the\n // transaction id as `transaction`.\n const creditsCharged = resolveCreditsCharged(response)\n const settled = response.success === true\n event.metadata = {\n ...event.metadata,\n // Same rule as `creditsCharged` below: a failed settle has no\n // transaction to name, and `transaction` is an empty string there.\n ...(settled && response.transaction ? { txHash: response.transaction } : {}),\n // The credits actually redeemed, omitted entirely when the billing\n // model has none to report — see resolveCreditsCharged. The credits\n // this request asked to burn stay available as `creditsUsed`.\n ...(creditsCharged !== undefined && { creditsCharged }),\n }\n }\n } catch (err) {\n // Settlement failed AFTER the agent executed. Always log it (the legacy\n // header path has no other surface for it). For the in-band x402 v2 A2A\n // path it is additionally surfaced below as payment-failed + suppressed\n // content; the legacy header path still delivers the result (no retract).\n console.error('[PaymentsA2A] settlement failed after execution:', err)\n settlementError = err\n }\n\n // Stamp the in-band x402 state onto the FINAL event so it survives when the\n // caller processes this event into the task's status (mutating the task\n // here would be overwritten by the final event). The event carries a Task\n // shape under `event.status`; the helpers mutate `event.status.message`.\n if (httpContext?.inBand && settlementError) {\n // x402 v2 A2A transport: a settlement failure after execution must NOT\n // deliver paid content — replace the agent's status message with a\n // failed one carrying payment-failed metadata + an error receipt.\n const errorReason =\n settlementError instanceof Error ? settlementError.message : String(settlementError)\n event.status = {\n state: 'failed',\n message: {\n kind: 'message',\n messageId: uuidv4(),\n role: 'agent',\n parts: [{ kind: 'text', text: `Payment settlement failed: ${errorReason}` }],\n taskId: event.taskId,\n contextId: event.contextId,\n metadata: {},\n },\n timestamp: new Date().toISOString(),\n }\n this.recordInBandSettlement({ status: event.status } as any, httpContext, {\n success: false,\n errorReason,\n transaction: '',\n network: settlement?.network || '',\n })\n } else if (httpContext?.inBand) {\n // Stamp in-band settlement state onto the final event's status message.\n this.recordInBandSettlement(\n { status: event.status } as any,\n httpContext,\n settlement,\n settlementDeferred,\n )\n }\n\n try {\n // Always update task metadata and process the task\n const task = resultManager.getCurrentTask()\n if (task) {\n // Update task metadata with current event metadata (executor / redemption).\n task.metadata = {\n ...task.metadata,\n ...event.metadata,\n }\n\n if (httpContext?.inBand && settlementError) {\n // x402 v2 A2A transport: a settlement failure must never deliver paid\n // content. The agent's status message was already replaced above; also\n // drop any artifacts it emitted so the paid result cannot surface there\n // (mirrors the Python SDK's _apply_inband_settlement). History is rebuilt\n // by processEvent below from the replaced (failed) status, so it carries\n // no paid content.\n task.artifacts = undefined\n }\n\n await resultManager.processEvent(task)\n // Delete http context associated with the task\n this.deleteHttpRequestContextForTask(event.taskId)\n }\n } catch (err) {\n // This block persists the payment-failed/suppressed task; if it throws the\n // suppression itself failed, so log loudly rather than swallow.\n console.error('[PaymentsA2A] failed to persist finalized task:', err)\n }\n }\n try {\n const taskPushNotificationConfig = await this.getTaskPushNotificationConfig({\n id: event.taskId,\n })\n if (taskPushNotificationConfig) {\n await this.sendPushNotification(\n event.taskId,\n event.status.state,\n taskPushNotificationConfig.pushNotificationConfig,\n { contextId: event.contextId },\n )\n }\n } catch (err) {\n // Do nothing\n }\n }\n\n /**\n * Streams messages and events for a task, with payments validation.\n * Also sends a push notification if a terminal status-update event is emitted.\n * @param params - Message send parameters\n * @returns Async generator of events\n */\n async *sendMessageStream(\n params: MessageSendParams,\n ): AsyncGenerator<A2AStreamEvent, void, undefined> {\n // x402 v2 A2A transport: a payment-gated request with no token yields a\n // single `input-required` task (in band) instead of executing the agent.\n const paymentRequiredTask = await this.buildPaymentRequiredTaskIfNeeded(params)\n if (paymentRequiredTask) {\n yield paymentRequiredTask\n return\n }\n\n // Create PaymentsRequestContext and related data\n const {\n paymentsRequestContext,\n taskId,\n httpContext,\n bearerToken,\n requestContext,\n finalMessageForAgent,\n eventBus,\n eventQueue,\n resultManager,\n } = await this.createPaymentsRequestContext(params, true)\n\n // Execute agent with extended context\n ;(this as any).agentExecutor\n .execute(paymentsRequestContext as any, eventBus)\n .catch((err: any) => {\n console.error(\n `Agent execution failed for stream message ${finalMessageForAgent.messageId}:`,\n err,\n )\n const contextId = finalMessageForAgent.contextId || uuidv4()\n const errorTaskStatus: TaskStatusUpdateEvent = {\n kind: 'status-update',\n taskId: requestContext.task?.id || uuidv4(),\n contextId,\n status: {\n state: 'failed',\n message: {\n kind: 'message',\n role: 'agent',\n messageId: uuidv4(),\n parts: [{ kind: 'text', text: `Agent execution error: ${err.message}` }],\n taskId: requestContext.task?.id,\n contextId,\n },\n timestamp: new Date().toISOString(),\n },\n final: true,\n }\n eventBus.publish(errorTaskStatus)\n })\n\n // Process streaming events with finalization\n yield* this.processStreamingEventsWithFinalization(\n taskId,\n resultManager,\n eventQueue,\n bearerToken,\n httpContext,\n )\n }\n\n /**\n * Sends a push notification when a task reaches a terminal state.\n * @param taskId - The task ID\n * @param state - The terminal state\n * @param pushNotificationConfig - The push notification configuration\n * @param payload - Additional payload to include in the notification\n */\n private async sendPushNotification(\n taskId: string,\n state: TaskState,\n pushNotificationConfig: PushNotificationConfig,\n payload: Record<string, any> = {},\n ) {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n }\n if (pushNotificationConfig.authentication) {\n if (pushNotificationConfig.authentication.schemes.includes('basic')) {\n const basic = Buffer.from(`${pushNotificationConfig.authentication.credentials}`).toString(\n 'base64',\n )\n headers['Authorization'] = `Basic ${basic}`\n } else if (pushNotificationConfig.authentication.schemes.includes('bearer')) {\n headers['Authorization'] = `Bearer ${pushNotificationConfig.authentication.credentials}`\n } else if (pushNotificationConfig.authentication.schemes.includes('custom')) {\n Object.assign(headers, pushNotificationConfig.authentication.credentials)\n }\n }\n const body = JSON.stringify({\n taskId,\n state,\n payload,\n })\n const response = await fetch(pushNotificationConfig.url, {\n method: 'POST',\n headers,\n body,\n })\n if (!response.ok) {\n throw A2AError.internalError('Failed to send push notification.')\n }\n }\n\n /**\n * Migrates the HTTP context from a messageId to a taskId and deletes the temporary messageId context.\n * @param messageId - The messageId to migrate from\n * @param taskId - The taskId to migrate to\n */\n public migrateHttpRequestContextFromMessageToTask(messageId: string, taskId: string): void {\n const ctx = this.getHttpRequestContextForMessage(messageId)\n if (ctx) {\n this.setHttpRequestContextForTask(taskId, ctx)\n this.deleteHttpRequestContextForMessage(messageId)\n }\n }\n\n /**\n * Deletes the HTTP context associated with a messageId.\n * @param messageId - The messageId to delete context for\n */\n public deleteHttpRequestContextForMessage(messageId: string): void {\n this.httpContextByMessageId.delete(messageId)\n }\n\n /**\n * Protected getter to access the private taskStore property from the parent class.\n * This is a workaround due to SDK limitations.\n */\n protected getTaskStore(): TaskStore {\n return (this as any).taskStore as TaskStore\n }\n\n /**\n * Protected getter to access the private eventBusManager property from the parent class.\n * This is a workaround due to SDK limitations.\n */\n protected getEventBusManager(): ExecutionEventBusManager {\n return (this as any).eventBusManager as ExecutionEventBusManager\n }\n\n /**\n * Protected getter to access the private _createRequestContext method from the parent class.\n * This is a workaround due to SDK limitations.\n */\n protected async callCreateRequestContext(\n incomingMessage: any,\n taskId: string,\n isStream: boolean,\n ): Promise<any> {\n return await (this as any)._createRequestContext(incomingMessage, taskId, isStream)\n }\n\n /**\n * Protected getter to access the private _processEvents method from the parent class.\n * This is a workaround due to SDK limitations.\n */\n protected callProcessEvents(...args: any[]): any {\n return (this as any)._processEvents.apply(this, args)\n }\n\n /**\n * Resubscribes to a task's event stream, ensuring the task has updated metadata before yielding.\n * This method overrides the parent implementation to ensure metadata is updated before yielding.\n * @param params - Parameters containing the taskId\n * @returns Async generator of events\n */\n async *resubscribe(\n params: TaskIdParams,\n ): AsyncGenerator<Task | TaskStatusUpdateEvent | TaskArtifactUpdateEvent, void, undefined> {\n const task = await this.getTaskStore().load(params.id)\n if (!task) {\n throw A2AError.taskNotFound(params.id)\n }\n\n // Yield task immediately (with current metadata)\n yield task\n\n const finalStates: TaskState[] = ['completed', 'failed', 'canceled', 'rejected']\n if (finalStates.includes(task.status.state)) {\n return\n }\n\n const eventBus = this.getEventBusManager().getByTaskId(params.id)\n if (!eventBus) {\n console.warn(`Resubscribe: No active event bus for task ${params.id}.`)\n return\n }\n\n const eventQueue = new ExecutionEventQueue(eventBus)\n try {\n for await (const event of eventQueue.events()) {\n // Process event with ResultManager to ensure task is saved\n const resultManager = new ResultManager(this.getTaskStore())\n // Set context from task history if available\n if (task.history && task.history.length > 0) {\n resultManager.setContext(task.history[0])\n }\n await resultManager.processEvent(event)\n\n // Handle redemption and push notification for final status-update events\n if (\n event.kind === 'status-update' &&\n event.final &&\n event.taskId === params.id &&\n terminalStates.includes(event.status?.state)\n ) {\n // Get HTTP context for this task\n const httpContext = this.getHttpRequestContextForTask(event.taskId)\n if (httpContext) {\n const { bearerToken, validation } = httpContext\n if (bearerToken && validation) {\n // Handle task finalization (redemption and push notification)\n await this.handleTaskFinalization(resultManager, event, bearerToken, httpContext)\n }\n }\n }\n\n // Yield event after processing (so metadata is updated)\n if (event.kind === 'status-update' && event.taskId === params.id) {\n yield event\n } else if (event.kind === 'artifact-update' && event.taskId === params.id) {\n yield event\n } else if (event.kind === 'task' && event.id === params.id) {\n yield event\n }\n }\n } finally {\n eventQueue.stop()\n }\n }\n}\n"]}