Commit 0aa3de1
feat: introduce PaymentProvider interface and migrate Skyfire to provider pattern, add x402 payment provider (#590)
* feat: introduce PaymentProvider interface and migrate Skyfire to provider pattern
Replace hardcoded Skyfire payment logic with a generic PaymentProvider interface
that supports multiple payment schemes (Skyfire, x402). This refactoring:
- Add src/payments/ module with PaymentProvider type, SkyfirePaymentProvider, and resolver
- Replace skyfireMode boolean with paymentProvider instance on server options
- Rename requiresSkyfirePayId to paymentRequired on tool definitions
- Rename createApifyClientWithSkyfireSupport to createApifyClientWithPaymentSupport
- Replace skyfirePayId with generic paymentHeaders on ApifyClient
- Preserve full backward compatibility in index_internals.ts exports
* chore: remove dead validateSkyfirePayId utility
The function is superseded by SkyfirePaymentProvider.validatePayment()
and has no remaining callers.
* refactor: address PR review - rename methods, add preparePayment helper, pass client via InternalToolArgs
- Rename PaymentProvider methods: augmentTool→decorateToolSchema, stripPaymentArgs→removePaymentFields, redactArgs→redactForLogging
- Add preparePayment() helper centralizing payment processing (cleanArgs, logArgs, client creation)
- Move ApifyClient creation to server handler, pass via InternalToolArgs instead of per-tool creation
- Remove additionalProperties:true hack from common tools (no longer needed since payment fields are stripped before validation)
- Restore additionalProperties:true for call-actor and dynamic Actor tools (needed for arbitrary Actor input)
- Remove stale Skyfire-specific comments from tool files
- Add PaymentHeaders type alias
* refactor: rename payments/prepare.ts to payments/helpers.ts
* feat: add x-apify-payment-protocol header to Skyfire payment headers for consistency
* fix: Replace stale Skyfire-specific comments with provider-agnostic wording (#605)
* fix: replace stale Skyfire-specific comments with provider-agnostic wording
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
* fix: replace Skyfire-specific error messages with provider-agnostic wording
---------
Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: MQ37 <themq37@gmail.com>
* feat: implement X402PaymentProvider for x402 protocol support (#591)
* feat: implement X402PaymentProvider for x402 protocol support
Add X402PaymentProvider that reads payment signatures from MCP _meta["x402/payment"]
and forwards them as PAYMENT-SIGNATURE headers to the Apify API.
- Add src/payments/x402.ts with full PaymentProvider implementation
- Add PaymentMeta type and meta? parameter to validatePayment/getPaymentHeaders
- Thread meta through InternalToolArgs, server.ts, and all 14 tool files
- Wire up x402 in resolvePaymentProvider (replaces placeholder error)
- Export X402PaymentProvider and PaymentMeta from barrel
* feat: extract x402 payment signature from HTTP header with _meta fallback
- Add HTTP PAYMENT-SIGNATURE header extraction as fallback when _meta is absent
- Thread requestHeaders through PaymentProvider interface (validatePayment, getPaymentHeaders)
- Prefer _meta over HTTP header for backward compatibility
- Fix isError: true on payment validation error responses
- Add 5 unit tests for x402 header extraction and precedence
- Add x402 integration test for streamable-http transport
- Replace skyfireMode boolean with generic payment string param in test helpers
- Add typecheck script alias in package.json
* feat: add x-apify-payment-protocol header to x402 payment headers
* feat: finalize x402 payment support — propagate 402 errors to MCP clients (#608)
* feat: finalize x402 payment support — propagate 402 errors to MCP clients
- Intercept HTTP 402 from Apify API via Axios response interceptor
- Extract payment-required header and throw structured McpError(402)
- Fetch x402 payment requirements from API during server init
- Inject x402 payment details into tool _meta.x402 via decorateToolSchema
- Make resolvePaymentProvider async for x402 requirement fetching
* refactor: use x402 tool result approach instead of JSON-RPC 402 errors
Switch payment-required responses from McpError(402) throws to tool results
with isError: true + content[0].text containing PaymentRequired JSON. This
matches the x402 MCP transport spec used by @x402/mcp client/server.
Changes:
- Return buildMCPResponse with JSON-stringified PaymentRequired instead of
throwing McpError(402) in all 3 code paths (validation, catch, task)
- Do not use structuredContent (MCP SDK validates it against outputSchema)
- Flatten first accepts entry in _meta.x402 via getFirstAcceptEntry()
- Add try-catch guard on axios interceptor registration
- Add instanceof ApifyApiError guard on extractPaymentRequiredData Source 2
- Add 8s AbortController timeout to fetchX402PaymentRequirements
* fix: handle 402 payment required in task mode and update stale comments
- Add 402 Payment Required handling to the task mode catch block, returning a proper x402 tool result so clients can auto-pay.
- Do not use structuredContent in task mode 402 responses to avoid schema validation errors.
- Update stale comments in types.ts, x402.ts, and payment_errors.ts to reflect the new tool result approach instead of McpError.data.
* refactor: minimize x402 payment error handling and deduplicate logic
- Centralized MCP response building for 402 errors in buildPaymentRequiredResponse helper.
- Flattened the axios interceptor registration in registerPaymentRequiredInterceptor to use optional chaining instead of deeply nested try/catch blocks.
- Modified preparePayment to return a pre-built errorResult instead of individual error strings/data, saving 30 lines of repeated response logic in server.ts.
- Deduplicated signature extraction in X402PaymentProvider by adding getEncodedPaymentSignature helper.
* fix(payments): address PR #608 review comments
- Add 30m promise caching to `fetchX402PaymentRequirements()` to prevent blocking SSE setup
- Deduplicate Skyfire log redaction using shared `redactSkyfirePayId` (see #618 for migration plan)
- Add `create()` factory to `SkyfirePaymentProvider` to normalize instantiation
- Generalize Actor MCP restriction messages to apply to any third-party payment provider
* fix(lint): remove trailing whitespace from x402.ts comments
---------
Co-authored-by: Jiří Spilka <jiri.spilka@apify.com>
Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>1 parent 36de0a4 commit 0aa3de1
43 files changed
Lines changed: 926 additions & 255 deletions
File tree
- src
- actor
- mcp
- payments
- resources
- tools
- common
- core
- default
- openai
- utils
- tests
- integration
- unit
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
92 | 92 | | |
93 | 93 | | |
94 | 94 | | |
| 95 | + | |
95 | 96 | | |
96 | 97 | | |
97 | 98 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
16 | 16 | | |
17 | 17 | | |
18 | 18 | | |
| 19 | + | |
19 | 20 | | |
20 | 21 | | |
21 | 22 | | |
| |||
67 | 68 | | |
68 | 69 | | |
69 | 70 | | |
70 | | - | |
71 | | - | |
72 | | - | |
| 71 | + | |
| 72 | + | |
73 | 73 | | |
74 | 74 | | |
75 | 75 | | |
| |||
79 | 79 | | |
80 | 80 | | |
81 | 81 | | |
82 | | - | |
| 82 | + | |
83 | 83 | | |
84 | 84 | | |
85 | 85 | | |
| |||
199 | 199 | | |
200 | 200 | | |
201 | 201 | | |
202 | | - | |
203 | | - | |
204 | | - | |
| 202 | + | |
| 203 | + | |
205 | 204 | | |
206 | 205 | | |
207 | 206 | | |
| |||
212 | 211 | | |
213 | 212 | | |
214 | 213 | | |
215 | | - | |
| 214 | + | |
216 | 215 | | |
217 | 216 | | |
218 | 217 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3 | 3 | | |
4 | 4 | | |
5 | 5 | | |
6 | | - | |
7 | | - | |
| 6 | + | |
8 | 7 | | |
9 | 8 | | |
10 | 9 | | |
11 | | - | |
| 10 | + | |
| 11 | + | |
12 | 12 | | |
13 | 13 | | |
14 | 14 | | |
| |||
42 | 42 | | |
43 | 43 | | |
44 | 44 | | |
45 | | - | |
| 45 | + | |
46 | 46 | | |
47 | 47 | | |
48 | | - | |
| 48 | + | |
49 | 49 | | |
50 | | - | |
| 50 | + | |
51 | 51 | | |
52 | 52 | | |
53 | 53 | | |
54 | | - | |
| 54 | + | |
55 | 55 | | |
56 | 56 | | |
57 | 57 | | |
| |||
64 | 64 | | |
65 | 65 | | |
66 | 66 | | |
67 | | - | |
68 | | - | |
69 | | - | |
70 | | - | |
71 | | - | |
72 | | - | |
73 | | - | |
74 | | - | |
75 | | - | |
76 | | - | |
77 | | - | |
78 | | - | |
79 | | - | |
80 | | - | |
81 | | - | |
82 | | - | |
83 | | - | |
84 | | - | |
85 | | - | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
200 | 200 | | |
201 | 201 | | |
202 | 202 | | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
203 | 206 | | |
204 | 207 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
| 8 | + | |
| 9 | + | |
8 | 10 | | |
9 | 11 | | |
10 | 12 | | |
| |||
48 | 50 | | |
49 | 51 | | |
50 | 52 | | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
51 | 58 | | |
52 | 59 | | |
0 commit comments