@coinbase/agentkit 0.10.1 → 0.10.3

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 (127) hide show
  1. package/README.md +179 -40
  2. package/dist/action-providers/across/schemas.d.ts +1 -1
  3. package/dist/action-providers/baseAccount/baseAccountActionProvider.d.ts +46 -0
  4. package/dist/action-providers/baseAccount/baseAccountActionProvider.js +404 -0
  5. package/dist/action-providers/baseAccount/baseAccountActionProvider.test.d.ts +1 -0
  6. package/dist/action-providers/baseAccount/baseAccountActionProvider.test.js +325 -0
  7. package/dist/action-providers/baseAccount/index.d.ts +2 -0
  8. package/dist/action-providers/baseAccount/index.js +18 -0
  9. package/dist/action-providers/baseAccount/schemas.d.ts +43 -0
  10. package/dist/action-providers/baseAccount/schemas.js +62 -0
  11. package/dist/action-providers/baseAccount/types.d.ts +17 -0
  12. package/dist/action-providers/baseAccount/types.js +2 -0
  13. package/dist/action-providers/baseAccount/utils.d.ts +14 -0
  14. package/dist/action-providers/baseAccount/utils.js +57 -0
  15. package/dist/action-providers/cdp/cdpApiActionProvider.js +7 -30
  16. package/dist/action-providers/cdp/cdpApiActionProvider.test.js +2 -8
  17. package/dist/action-providers/cdp/cdpEvmWalletActionProvider.js +2 -1
  18. package/dist/action-providers/cdp/cdpEvmWalletActionProvider.test.js +3 -1
  19. package/dist/action-providers/cdp/cdpSmartWalletActionProvider.js +2 -1
  20. package/dist/action-providers/cdp/cdpSmartWalletActionProvider.test.js +3 -1
  21. package/dist/action-providers/cdp/faucetUtils.d.ts +38 -0
  22. package/dist/action-providers/cdp/faucetUtils.js +81 -0
  23. package/dist/action-providers/cdp/swapUtils.d.ts +0 -9
  24. package/dist/action-providers/cdp/swapUtils.js +0 -36
  25. package/dist/action-providers/clanker/schemas.d.ts +6 -6
  26. package/dist/action-providers/enso/constants.d.ts +4 -0
  27. package/dist/action-providers/enso/constants.js +10 -0
  28. package/dist/action-providers/enso/ensoActionProvider.d.ts +34 -0
  29. package/dist/action-providers/enso/ensoActionProvider.js +125 -0
  30. package/dist/action-providers/enso/ensoActionProvider.test.d.ts +1 -0
  31. package/dist/action-providers/enso/ensoActionProvider.test.js +141 -0
  32. package/dist/action-providers/enso/index.d.ts +1 -0
  33. package/dist/action-providers/enso/index.js +17 -0
  34. package/dist/action-providers/enso/schemas.d.ts +23 -0
  35. package/dist/action-providers/enso/schemas.js +22 -0
  36. package/dist/action-providers/erc20/constants.d.ts +2 -0
  37. package/dist/action-providers/erc20/constants.js +2 -0
  38. package/dist/action-providers/erc20/erc20ActionProvider.d.ts +17 -1
  39. package/dist/action-providers/erc20/erc20ActionProvider.js +103 -1
  40. package/dist/action-providers/erc20/erc20ActionProvider.test.js +201 -0
  41. package/dist/action-providers/erc20/schemas.d.ts +29 -0
  42. package/dist/action-providers/erc20/schemas.js +34 -1
  43. package/dist/action-providers/flaunch/client_utils.d.ts +25 -0
  44. package/dist/action-providers/flaunch/client_utils.js +62 -0
  45. package/dist/action-providers/flaunch/constants.d.ts +41 -20
  46. package/dist/action-providers/flaunch/constants.js +111 -36
  47. package/dist/action-providers/flaunch/flaunchActionProvider.d.ts +4 -43
  48. package/dist/action-providers/flaunch/flaunchActionProvider.js +132 -200
  49. package/dist/action-providers/flaunch/flaunchActionProvider.test.js +108 -13
  50. package/dist/action-providers/flaunch/metadata_utils.d.ts +12 -0
  51. package/dist/action-providers/flaunch/metadata_utils.js +216 -0
  52. package/dist/action-providers/flaunch/schemas.d.ts +39 -3
  53. package/dist/action-providers/flaunch/schemas.js +62 -10
  54. package/dist/action-providers/flaunch/{utils.d.ts → swap_utils.d.ts} +17 -19
  55. package/dist/action-providers/flaunch/{utils.js → swap_utils.js} +137 -172
  56. package/dist/action-providers/index.d.ts +4 -1
  57. package/dist/action-providers/index.js +4 -1
  58. package/dist/action-providers/pyth/pythActionProvider.d.ts +2 -2
  59. package/dist/action-providers/pyth/pythActionProvider.js +83 -31
  60. package/dist/action-providers/pyth/pythActionProvider.test.js +178 -26
  61. package/dist/action-providers/pyth/schemas.d.ts +6 -0
  62. package/dist/action-providers/pyth/schemas.js +9 -1
  63. package/dist/action-providers/superfluid/superfluidSuperTokenCreatorActionProvider.js +5 -4
  64. package/dist/action-providers/superfluid/utils/parseLogs.d.ts +2 -1
  65. package/dist/action-providers/superfluid/utils/parseLogs.js +6 -3
  66. package/dist/action-providers/wallet/walletActionProvider.js +4 -1
  67. package/dist/action-providers/weth/constants.d.ts +0 -1
  68. package/dist/action-providers/weth/constants.js +1 -2
  69. package/dist/action-providers/weth/schemas.js +6 -2
  70. package/dist/action-providers/weth/wethActionProvider.d.ts +7 -0
  71. package/dist/action-providers/weth/wethActionProvider.js +57 -32
  72. package/dist/action-providers/weth/wethActionProvider.test.js +60 -11
  73. package/dist/action-providers/x402/schemas.d.ts +7 -0
  74. package/dist/action-providers/x402/schemas.js +11 -1
  75. package/dist/action-providers/x402/utils.d.ts +55 -0
  76. package/dist/action-providers/x402/utils.js +197 -0
  77. package/dist/action-providers/x402/x402ActionProvider.d.ts +14 -14
  78. package/dist/action-providers/x402/x402ActionProvider.js +179 -45
  79. package/dist/action-providers/x402/x402ActionProvider.test.js +162 -12
  80. package/dist/action-providers/yelay/constants.d.ts +64 -0
  81. package/dist/action-providers/yelay/constants.js +137 -0
  82. package/dist/action-providers/yelay/index.d.ts +2 -0
  83. package/dist/action-providers/yelay/index.js +18 -0
  84. package/dist/action-providers/yelay/schemas.d.ts +47 -0
  85. package/dist/action-providers/yelay/schemas.js +59 -0
  86. package/dist/action-providers/yelay/types.d.ts +24 -0
  87. package/dist/action-providers/yelay/types.js +2 -0
  88. package/dist/action-providers/yelay/yelayActionProvider.d.ts +70 -0
  89. package/dist/action-providers/yelay/yelayActionProvider.js +329 -0
  90. package/dist/action-providers/yelay/yelayActionProvider.test.d.ts +1 -0
  91. package/dist/action-providers/yelay/yelayActionProvider.test.js +302 -0
  92. package/dist/utils.d.ts +10 -0
  93. package/dist/utils.js +43 -13
  94. package/dist/wallet-providers/cdpEvmWalletProvider.d.ts +7 -0
  95. package/dist/wallet-providers/cdpEvmWalletProvider.js +14 -21
  96. package/dist/wallet-providers/cdpEvmWalletProvider.test.js +7 -0
  97. package/dist/wallet-providers/cdpSmartWalletProvider.d.ts +7 -0
  98. package/dist/wallet-providers/cdpSmartWalletProvider.js +23 -8
  99. package/dist/wallet-providers/cdpSmartWalletProvider.test.js +6 -10
  100. package/dist/wallet-providers/cdpSolanaWalletProvider.d.ts +14 -0
  101. package/dist/wallet-providers/cdpSolanaWalletProvider.js +39 -3
  102. package/dist/wallet-providers/cdpSolanaWalletProvider.test.js +16 -0
  103. package/dist/wallet-providers/evmWalletProvider.d.ts +9 -2
  104. package/dist/wallet-providers/evmWalletProvider.js +4 -0
  105. package/dist/wallet-providers/legacyCdpSmartWalletProvider.d.ts +9 -0
  106. package/dist/wallet-providers/legacyCdpSmartWalletProvider.js +11 -0
  107. package/dist/wallet-providers/legacyCdpWalletProvider.d.ts +7 -0
  108. package/dist/wallet-providers/legacyCdpWalletProvider.js +16 -0
  109. package/dist/wallet-providers/legacyCdpWalletProvider.test.js +6 -0
  110. package/dist/wallet-providers/privyEvmDelegatedEmbeddedWalletProvider.d.ts +7 -0
  111. package/dist/wallet-providers/privyEvmDelegatedEmbeddedWalletProvider.js +27 -0
  112. package/dist/wallet-providers/privyEvmWalletProvider.test.js +11 -0
  113. package/dist/wallet-providers/privySvmWalletProvider.d.ts +14 -0
  114. package/dist/wallet-providers/privySvmWalletProvider.js +17 -0
  115. package/dist/wallet-providers/privySvmWalletProvider.test.js +10 -0
  116. package/dist/wallet-providers/solanaKeypairWalletProvider.d.ts +14 -0
  117. package/dist/wallet-providers/solanaKeypairWalletProvider.js +17 -0
  118. package/dist/wallet-providers/svmWalletProvider.d.ts +34 -0
  119. package/dist/wallet-providers/svmWalletProvider.js +43 -0
  120. package/dist/wallet-providers/svmWalletProvider.test.js +10 -0
  121. package/dist/wallet-providers/viemWalletProvider.d.ts +8 -1
  122. package/dist/wallet-providers/viemWalletProvider.js +21 -1
  123. package/dist/wallet-providers/viemWalletProvider.test.js +21 -1
  124. package/dist/wallet-providers/zeroDevWalletProvider.d.ts +7 -0
  125. package/dist/wallet-providers/zeroDevWalletProvider.js +12 -0
  126. package/dist/wallet-providers/zeroDevWalletProvider.test.js +10 -0
  127. package/package.json +8 -4
@@ -20,7 +20,10 @@ const schemas_1 = require("./schemas");
20
20
  const wallet_providers_1 = require("../../wallet-providers");
21
21
  const axios_1 = __importDefault(require("axios"));
22
22
  const x402_axios_1 = require("x402-axios");
23
- const SUPPORTED_NETWORKS = ["base-mainnet", "base-sepolia"];
23
+ const verify_1 = require("x402/verify");
24
+ const x402_1 = require("@coinbase/x402");
25
+ const utils_1 = require("./utils");
26
+ const SUPPORTED_NETWORKS = ["base-mainnet", "base-sepolia", "solana-mainnet", "solana-devnet"];
24
27
  /**
25
28
  * X402ActionProvider provides actions for making HTTP requests, with optional x402 payment handling.
26
29
  */
@@ -37,7 +40,117 @@ class X402ActionProvider extends actionProvider_1.ActionProvider {
37
40
  * @param network - The network to check support for
38
41
  * @returns True if the network is supported, false otherwise
39
42
  */
40
- this.supportsNetwork = (network) => network.protocolFamily === "evm" && SUPPORTED_NETWORKS.includes(network.networkId);
43
+ this.supportsNetwork = (network) => SUPPORTED_NETWORKS.includes(network.networkId);
44
+ }
45
+ /**
46
+ * Discovers available x402 services with optional filtering.
47
+ *
48
+ * @param walletProvider - The wallet provider to use for network filtering
49
+ * @param args - Optional filters: maxUsdcPrice
50
+ * @returns JSON string with the list of services (filtered by network and description)
51
+ */
52
+ async discoverX402Services(walletProvider, args) {
53
+ try {
54
+ const { list } = (0, verify_1.useFacilitator)(x402_1.facilitator);
55
+ const services = await list();
56
+ if (!services || !services.items) {
57
+ return JSON.stringify({
58
+ error: true,
59
+ message: "No services found",
60
+ });
61
+ }
62
+ // Get the current wallet network
63
+ const walletNetwork = (0, utils_1.getX402Network)(walletProvider.getNetwork());
64
+ // Filter services by network, description, and optional USDC price
65
+ const hasValidMaxUsdcPrice = typeof args.maxUsdcPrice === "number" &&
66
+ Number.isFinite(args.maxUsdcPrice) &&
67
+ args.maxUsdcPrice > 0;
68
+ const filteredServices = services.items.filter(item => {
69
+ // Filter by network - only include services that accept the current wallet network
70
+ const accepts = Array.isArray(item.accepts) ? item.accepts : [];
71
+ const hasMatchingNetwork = accepts.some(req => req.network === walletNetwork);
72
+ // Filter out services with empty or default descriptions
73
+ const hasDescription = accepts.some(req => req.description &&
74
+ req.description.trim() !== "" &&
75
+ req.description.trim() !== "Access to protected content");
76
+ return hasMatchingNetwork && hasDescription;
77
+ });
78
+ // Apply USDC price filtering if maxUsdcPrice is provided (only consider USDC assets)
79
+ let priceFilteredServices = filteredServices;
80
+ if (hasValidMaxUsdcPrice) {
81
+ priceFilteredServices = [];
82
+ for (const item of filteredServices) {
83
+ const accepts = Array.isArray(item.accepts) ? item.accepts : [];
84
+ let shouldInclude = false;
85
+ for (const req of accepts) {
86
+ if (req.network === walletNetwork && req.asset && req.maxAmountRequired) {
87
+ // Only consider USDC assets when maxUsdcPrice filter is applied
88
+ if ((0, utils_1.isUsdcAsset)(req.asset, walletProvider)) {
89
+ try {
90
+ const maxUsdcPriceAtomic = await (0, utils_1.convertWholeUnitsToAtomic)(args.maxUsdcPrice, req.asset, walletProvider);
91
+ if (maxUsdcPriceAtomic) {
92
+ const requirement = BigInt(req.maxAmountRequired);
93
+ const maxUsdcPriceAtomicBigInt = BigInt(maxUsdcPriceAtomic);
94
+ if (requirement <= maxUsdcPriceAtomicBigInt) {
95
+ shouldInclude = true;
96
+ break;
97
+ }
98
+ }
99
+ }
100
+ catch {
101
+ // If conversion fails, skip this requirement
102
+ continue;
103
+ }
104
+ }
105
+ }
106
+ }
107
+ if (shouldInclude) {
108
+ priceFilteredServices.push(item);
109
+ }
110
+ }
111
+ }
112
+ // Format the filtered services
113
+ const filtered = await Promise.all(priceFilteredServices.map(async (item) => {
114
+ const accepts = Array.isArray(item.accepts) ? item.accepts : [];
115
+ const matchingAccept = accepts.find(req => req.network === walletNetwork);
116
+ // Format amount if available
117
+ let formattedMaxAmount = matchingAccept?.maxAmountRequired;
118
+ if (matchingAccept?.maxAmountRequired && matchingAccept?.asset) {
119
+ formattedMaxAmount = await (0, utils_1.formatPaymentOption)({
120
+ asset: matchingAccept.asset,
121
+ maxAmountRequired: matchingAccept.maxAmountRequired,
122
+ network: matchingAccept.network,
123
+ }, walletProvider);
124
+ }
125
+ return {
126
+ resource: item.resource,
127
+ description: matchingAccept?.description || "",
128
+ cost: formattedMaxAmount,
129
+ ...(matchingAccept?.outputSchema?.input && {
130
+ input: matchingAccept.outputSchema.input,
131
+ }),
132
+ ...(matchingAccept?.outputSchema?.output && {
133
+ output: matchingAccept.outputSchema.output,
134
+ }),
135
+ ...(item.metadata && item.metadata.length > 0 && { metadata: item.metadata }),
136
+ };
137
+ }));
138
+ return JSON.stringify({
139
+ success: true,
140
+ walletNetwork,
141
+ total: services.items.length,
142
+ returned: filtered.length,
143
+ items: filtered,
144
+ }, null, 2);
145
+ }
146
+ catch (error) {
147
+ const message = error instanceof Error ? error.message : String(error);
148
+ return JSON.stringify({
149
+ error: true,
150
+ message: "Failed to list x402 services",
151
+ details: message,
152
+ }, null, 2);
153
+ }
41
154
  }
42
155
  /**
43
156
  * Makes a basic HTTP request to an API endpoint.
@@ -64,19 +177,32 @@ class X402ActionProvider extends actionProvider_1.ActionProvider {
64
177
  data: response.data,
65
178
  }, null, 2);
66
179
  }
180
+ // Check if wallet network matches any available payment options
181
+ const walletNetwork = (0, utils_1.getX402Network)(walletProvider.getNetwork());
182
+ const availableNetworks = response.data.accepts.map(option => option.network);
183
+ const hasMatchingNetwork = availableNetworks.includes(walletNetwork);
184
+ let paymentOptionsText = `The wallet network ${walletNetwork} does not match any available payment options (${availableNetworks.join(", ")}).`;
185
+ // Format payment options for matching networks
186
+ if (hasMatchingNetwork) {
187
+ const matchingOptions = response.data.accepts.filter(option => option.network === walletNetwork);
188
+ const formattedOptions = await Promise.all(matchingOptions.map(option => (0, utils_1.formatPaymentOption)(option, walletProvider)));
189
+ paymentOptionsText = `The payment options are: ${formattedOptions.join(", ")}`;
190
+ }
67
191
  return JSON.stringify({
68
192
  status: "error_402_payment_required",
69
193
  acceptablePaymentOptions: response.data.accepts,
70
194
  nextSteps: [
71
195
  "Inform the user that the requested server replied with a 402 Payment Required response.",
72
- `The payment options are: ${response.data.accepts.map(option => `${option.asset} ${option.maxAmountRequired} ${option.network}`).join(", ")}`,
73
- "Ask the user if they want to retry the request with payment.",
74
- `Use retry_http_request_with_x402 to retry the request with payment.`,
196
+ paymentOptionsText,
197
+ hasMatchingNetwork ? "Ask the user if they want to retry the request with payment." : "",
198
+ hasMatchingNetwork
199
+ ? `Use retry_http_request_with_x402 to retry the request with payment.`
200
+ : "",
75
201
  ],
76
202
  });
77
203
  }
78
204
  catch (error) {
79
- return this.handleHttpError(error, args.url);
205
+ return (0, utils_1.handleHttpError)(error, args.url);
80
206
  }
81
207
  }
82
208
  /**
@@ -88,8 +214,26 @@ class X402ActionProvider extends actionProvider_1.ActionProvider {
88
214
  */
89
215
  async retryWithX402(walletProvider, args) {
90
216
  try {
217
+ // Check network compatibility before attempting payment
218
+ const walletNetwork = (0, utils_1.getX402Network)(walletProvider.getNetwork());
219
+ const selectedNetwork = args.selectedPaymentOption.network;
220
+ if (walletNetwork !== selectedNetwork) {
221
+ return JSON.stringify({
222
+ error: true,
223
+ message: "Network mismatch",
224
+ details: `Wallet is on ${walletNetwork} but payment requires ${selectedNetwork}`,
225
+ }, null, 2);
226
+ }
227
+ // Check if wallet provider is supported
228
+ if (!(walletProvider instanceof wallet_providers_1.SvmWalletProvider || walletProvider instanceof wallet_providers_1.EvmWalletProvider)) {
229
+ return JSON.stringify({
230
+ error: true,
231
+ message: "Unsupported wallet provider",
232
+ details: "Only SvmWalletProvider and EvmWalletProvider are supported",
233
+ }, null, 2);
234
+ }
91
235
  // Make the request with payment handling
92
- const account = walletProvider.toSigner();
236
+ const account = await walletProvider.toSigner();
93
237
  const paymentSelector = (accepts) => {
94
238
  const { scheme, network, maxAmountRequired, asset } = args.selectedPaymentOption;
95
239
  let paymentRequirements = accepts.find(accept => accept.scheme === scheme &&
@@ -108,7 +252,9 @@ class X402ActionProvider extends actionProvider_1.ActionProvider {
108
252
  }
109
253
  return accepts[0];
110
254
  };
111
- const api = (0, x402_axios_1.withPaymentInterceptor)(axios_1.default.create({}), account, paymentSelector);
255
+ const api = (0, x402_axios_1.withPaymentInterceptor)(axios_1.default.create({}),
256
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
257
+ account, paymentSelector);
112
258
  const response = await api.request({
113
259
  url: args.url,
114
260
  method: args.method ?? "GET",
@@ -142,7 +288,7 @@ class X402ActionProvider extends actionProvider_1.ActionProvider {
142
288
  });
143
289
  }
144
290
  catch (error) {
145
- return this.handleHttpError(error, args.url);
291
+ return (0, utils_1.handleHttpError)(error, args.url);
146
292
  }
147
293
  }
148
294
  /**
@@ -154,7 +300,15 @@ class X402ActionProvider extends actionProvider_1.ActionProvider {
154
300
  */
155
301
  async makeHttpRequestWithX402(walletProvider, args) {
156
302
  try {
157
- const account = walletProvider.toSigner();
303
+ if (!(walletProvider instanceof wallet_providers_1.SvmWalletProvider || walletProvider instanceof wallet_providers_1.EvmWalletProvider)) {
304
+ return JSON.stringify({
305
+ error: true,
306
+ message: "Unsupported wallet provider",
307
+ details: "Only SvmWalletProvider and EvmWalletProvider are supported",
308
+ }, null, 2);
309
+ }
310
+ const account = await walletProvider.toSigner();
311
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
158
312
  const api = (0, x402_axios_1.withPaymentInterceptor)(axios_1.default.create({}), account);
159
313
  const response = await api.request({
160
314
  url: args.url,
@@ -183,42 +337,21 @@ class X402ActionProvider extends actionProvider_1.ActionProvider {
183
337
  }, null, 2);
184
338
  }
185
339
  catch (error) {
186
- return this.handleHttpError(error, args.url);
340
+ return (0, utils_1.handleHttpError)(error, args.url);
187
341
  }
188
342
  }
189
- /**
190
- * Helper method to handle HTTP errors consistently.
191
- *
192
- * @param error - The axios error to handle
193
- * @param url - The URL that was being accessed when the error occurred
194
- * @returns A JSON string containing formatted error details
195
- */
196
- handleHttpError(error, url) {
197
- if (error.response) {
198
- return JSON.stringify({
199
- error: true,
200
- message: `HTTP ${error.response.status} error when accessing ${url}`,
201
- details: error.response.data?.error || error.response.statusText,
202
- suggestion: "Check if the URL is correct and the API is available.",
203
- }, null, 2);
204
- }
205
- if (error.request) {
206
- return JSON.stringify({
207
- error: true,
208
- message: `Network error when accessing ${url}`,
209
- details: error.message,
210
- suggestion: "Check your internet connection and verify the API endpoint is accessible.",
211
- }, null, 2);
212
- }
213
- return JSON.stringify({
214
- error: true,
215
- message: `Error making request to ${url}`,
216
- details: error.message,
217
- suggestion: "Please check the request parameters and try again.",
218
- }, null, 2);
219
- }
220
343
  }
221
344
  exports.X402ActionProvider = X402ActionProvider;
345
+ __decorate([
346
+ (0, actionDecorator_1.CreateAction)({
347
+ name: "discover_x402_services",
348
+ description: "Discover available x402 services. Only services available on the current network will be returned. Optionally filter by a maximum price in whole units of USDC (only USDC payment options will be considered when filter is applied).",
349
+ schema: schemas_1.ListX402ServicesSchema,
350
+ }),
351
+ __metadata("design:type", Function),
352
+ __metadata("design:paramtypes", [wallet_providers_1.WalletProvider, void 0]),
353
+ __metadata("design:returntype", Promise)
354
+ ], X402ActionProvider.prototype, "discoverX402Services", null);
222
355
  __decorate([
223
356
  (0, actionDecorator_1.CreateAction)({
224
357
  name: "make_http_request",
@@ -235,7 +368,7 @@ If you receive a 402 Payment Required response, use retry_http_request_with_x402
235
368
  schema: schemas_1.HttpRequestSchema,
236
369
  }),
237
370
  __metadata("design:type", Function),
238
- __metadata("design:paramtypes", [wallet_providers_1.EvmWalletProvider, void 0]),
371
+ __metadata("design:paramtypes", [wallet_providers_1.WalletProvider, void 0]),
239
372
  __metadata("design:returntype", Promise)
240
373
  ], X402ActionProvider.prototype, "makeHttpRequest", null);
241
374
  __decorate([
@@ -254,7 +387,7 @@ DO NOT use this action directly without first trying make_http_request!`,
254
387
  schema: schemas_1.RetryWithX402Schema,
255
388
  }),
256
389
  __metadata("design:type", Function),
257
- __metadata("design:paramtypes", [wallet_providers_1.EvmWalletProvider, void 0]),
390
+ __metadata("design:paramtypes", [wallet_providers_1.WalletProvider, void 0]),
258
391
  __metadata("design:returntype", Promise)
259
392
  ], X402ActionProvider.prototype, "retryWithX402", null);
260
393
  __decorate([
@@ -272,6 +405,7 @@ This action combines both steps into one, which means:
272
405
  - No chance to review payment details before paying
273
406
  - No confirmation step
274
407
  - Automatic payment processing
408
+ - Assumes payment option is compatible with wallet network
275
409
 
276
410
  EXAMPLES:
277
411
  - Production: make_http_request_with_x402("https://api.example.com/data")
@@ -281,7 +415,7 @@ Unless specifically instructed otherwise, prefer the two-step approach with make
281
415
  schema: schemas_1.DirectX402RequestSchema,
282
416
  }),
283
417
  __metadata("design:type", Function),
284
- __metadata("design:paramtypes", [wallet_providers_1.EvmWalletProvider, void 0]),
418
+ __metadata("design:paramtypes", [wallet_providers_1.WalletProvider, void 0]),
285
419
  __metadata("design:returntype", Promise)
286
420
  ], X402ActionProvider.prototype, "makeHttpRequestWithX402", null);
287
421
  const x402ActionProvider = () => new X402ActionProvider();
@@ -37,11 +37,20 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
37
37
  };
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
39
  const x402ActionProvider_1 = require("./x402ActionProvider");
40
+ const wallet_providers_1 = require("../../wallet-providers");
40
41
  const axios_1 = __importDefault(require("axios"));
41
42
  const x402axios = __importStar(require("x402-axios"));
43
+ const x402Verify = __importStar(require("x402/verify"));
44
+ const utils = __importStar(require("./utils"));
45
+ // Mock external facilitator dependency
46
+ jest.mock("@coinbase/x402", () => ({
47
+ facilitator: {},
48
+ }));
42
49
  // Mock modules
43
50
  jest.mock("axios");
44
51
  jest.mock("x402-axios");
52
+ jest.mock("x402/verify");
53
+ jest.mock("./utils");
45
54
  // Create mock functions
46
55
  const mockRequest = jest.fn();
47
56
  // Create a complete mock axios instance
@@ -83,6 +92,11 @@ const mockAxios = {
83
92
  };
84
93
  const mockWithPaymentInterceptor = jest.fn().mockReturnValue(mockAxiosInstance);
85
94
  const mockDecodeXPaymentResponse = jest.fn();
95
+ const mockUseFacilitator = jest.fn();
96
+ const mockIsUsdcAsset = jest.fn();
97
+ const mockConvertWholeUnitsToAtomic = jest.fn();
98
+ const mockFormatPaymentOption = jest.fn();
99
+ const mockGetX402Network = jest.fn();
86
100
  // Override the mocked modules
87
101
  axios_1.default.create = mockAxios.create;
88
102
  axios_1.default.request = mockRequest;
@@ -90,9 +104,25 @@ axios_1.default.isAxiosError = mockAxios.isAxiosError;
90
104
  // Mock x402-axios functions
91
105
  jest.mocked(x402axios.withPaymentInterceptor).mockImplementation(mockWithPaymentInterceptor);
92
106
  jest.mocked(x402axios.decodeXPaymentResponse).mockImplementation(mockDecodeXPaymentResponse);
107
+ jest.mocked(x402Verify.useFacilitator).mockImplementation(mockUseFacilitator);
108
+ // Mock utils functions
109
+ jest.mocked(utils.isUsdcAsset).mockImplementation(mockIsUsdcAsset);
110
+ jest.mocked(utils.convertWholeUnitsToAtomic).mockImplementation(mockConvertWholeUnitsToAtomic);
111
+ jest.mocked(utils.formatPaymentOption).mockImplementation(mockFormatPaymentOption);
112
+ jest.mocked(utils.getX402Network).mockImplementation(mockGetX402Network);
113
+ jest.mocked(utils.handleHttpError).mockImplementation((error, url) => {
114
+ return JSON.stringify({
115
+ error: true,
116
+ message: error instanceof Error ? error.message : "Network error",
117
+ url: url,
118
+ });
119
+ });
93
120
  // Mock wallet provider
94
- const mockWalletProvider = {
95
- toSigner: jest.fn().mockReturnValue("mock-signer"),
121
+ const makeMockWalletProvider = (networkId) => {
122
+ const mockProvider = Object.create(wallet_providers_1.EvmWalletProvider.prototype);
123
+ mockProvider.toSigner = jest.fn().mockReturnValue("mock-signer");
124
+ mockProvider.getNetwork = jest.fn().mockReturnValue({ protocolFamily: "evm", networkId });
125
+ return mockProvider;
96
126
  };
97
127
  // Sample responses based on real examples
98
128
  const MOCK_PAYMENT_INFO_RESPONSE = {
@@ -141,6 +171,11 @@ describe("X402ActionProvider", () => {
141
171
  .mockImplementation((error) => Boolean(error &&
142
172
  typeof error === "object" &&
143
173
  ("isAxiosError" in error || "response" in error || "request" in error)));
174
+ // Reset all utility mocks to default behavior
175
+ mockGetX402Network.mockImplementation(network => network.networkId);
176
+ mockIsUsdcAsset.mockReturnValue(false);
177
+ mockConvertWholeUnitsToAtomic.mockResolvedValue("100000");
178
+ mockFormatPaymentOption.mockResolvedValue("mocked payment option");
144
179
  });
145
180
  afterEach(() => {
146
181
  jest.clearAllMocks();
@@ -158,8 +193,12 @@ describe("X402ActionProvider", () => {
158
193
  const network = { protocolFamily: "evm", networkId: "ethereum" };
159
194
  expect(provider.supportsNetwork(network)).toBe(false);
160
195
  });
161
- it("should not support non-EVM networks", () => {
162
- const network = { protocolFamily: "solana", networkId: "mainnet" };
196
+ it("should support SVM networks", () => {
197
+ const network = { protocolFamily: "svm", networkId: "solana-mainnet" };
198
+ expect(provider.supportsNetwork(network)).toBe(true);
199
+ });
200
+ it("should not support non-EVM/SVM networks", () => {
201
+ const network = { protocolFamily: "bitcoin", networkId: "mainnet" };
163
202
  expect(provider.supportsNetwork(network)).toBe(false);
164
203
  });
165
204
  });
@@ -171,7 +210,7 @@ describe("X402ActionProvider", () => {
171
210
  headers: {},
172
211
  config: {},
173
212
  });
174
- const result = await provider.makeHttpRequest(mockWalletProvider, {
213
+ const result = await provider.makeHttpRequest(makeMockWalletProvider("base-sepolia"), {
175
214
  url: "https://api.example.com/free",
176
215
  method: "GET",
177
216
  });
@@ -181,13 +220,15 @@ describe("X402ActionProvider", () => {
181
220
  expect(parsedResult.data).toEqual({ message: "Success" });
182
221
  });
183
222
  it("should handle 402 responses with payment options", async () => {
223
+ mockGetX402Network.mockReturnValue("base-sepolia");
224
+ mockFormatPaymentOption.mockResolvedValue("10000 USDC on base-sepolia network");
184
225
  mockRequest.mockResolvedValue({
185
226
  status: 402,
186
227
  data: MOCK_PAYMENT_INFO_RESPONSE.data,
187
228
  headers: {},
188
229
  config: {},
189
230
  });
190
- const result = await provider.makeHttpRequest(mockWalletProvider, {
231
+ const result = await provider.makeHttpRequest(makeMockWalletProvider("base-sepolia"), {
191
232
  url: "https://www.x402.org/protected",
192
233
  method: "GET",
193
234
  });
@@ -201,7 +242,7 @@ describe("X402ActionProvider", () => {
201
242
  error.isAxiosError = true;
202
243
  error.request = {};
203
244
  mockRequest.mockRejectedValue(error);
204
- const result = await provider.makeHttpRequest(mockWalletProvider, {
245
+ const result = await provider.makeHttpRequest(makeMockWalletProvider("base-sepolia"), {
205
246
  url: "https://api.example.com/endpoint",
206
247
  method: "GET",
207
248
  });
@@ -210,9 +251,116 @@ describe("X402ActionProvider", () => {
210
251
  expect(parsedResult.message).toContain("Network error");
211
252
  });
212
253
  });
254
+ describe("listX402Services", () => {
255
+ it("should list services without filters", async () => {
256
+ const mockList = jest.fn().mockResolvedValue({
257
+ items: [
258
+ {
259
+ resource: "https://example.com/service1",
260
+ metadata: { category: "test" },
261
+ accepts: [
262
+ {
263
+ asset: "0xUSDC",
264
+ maxAmountRequired: "90000",
265
+ network: "base-sepolia",
266
+ scheme: "exact",
267
+ description: "Test service 1",
268
+ outputSchema: { type: "object" },
269
+ extra: { name: "USDC" },
270
+ },
271
+ ],
272
+ },
273
+ ],
274
+ });
275
+ mockUseFacilitator.mockReturnValue({ list: mockList });
276
+ mockGetX402Network.mockReturnValue("base-sepolia");
277
+ const result = await provider.discoverX402Services(makeMockWalletProvider("base-sepolia"), {});
278
+ const parsed = JSON.parse(result);
279
+ expect(parsed.success).toBe(true);
280
+ expect(parsed.total).toBe(1);
281
+ expect(parsed.returned).toBe(1);
282
+ expect(parsed.items.length).toBe(1);
283
+ });
284
+ it("should filter services by asset and maxPrice", async () => {
285
+ const mockList = jest.fn().mockResolvedValue({
286
+ items: [
287
+ {
288
+ resource: "https://example.com/service1",
289
+ metadata: { category: "test" },
290
+ accepts: [
291
+ {
292
+ asset: "0x036CbD53842c5426634e7929541eC2318f3dCF7e", // Real USDC address for base-sepolia
293
+ maxAmountRequired: "90000", // 0.09 USDC (should pass 0.1 filter)
294
+ network: "base-sepolia",
295
+ scheme: "exact",
296
+ description: "Test service 1",
297
+ outputSchema: { type: "object" },
298
+ extra: { name: "USDC" },
299
+ },
300
+ ],
301
+ },
302
+ {
303
+ resource: "https://example.com/service2",
304
+ metadata: { category: "test" },
305
+ accepts: [
306
+ {
307
+ asset: "0x036CbD53842c5426634e7929541eC2318f3dCF7e", // Real USDC address for base-sepolia
308
+ maxAmountRequired: "150000", // 0.15 USDC (should fail 0.1 filter)
309
+ network: "base-sepolia",
310
+ scheme: "exact",
311
+ description: "Test service 2",
312
+ outputSchema: { type: "object" },
313
+ extra: { name: "USDC" },
314
+ },
315
+ ],
316
+ },
317
+ {
318
+ resource: "https://example.com/service3",
319
+ metadata: { category: "test" },
320
+ accepts: [
321
+ {
322
+ asset: "0x036CbD53842c5426634e7929541eC2318f3dCF7e", // Real USDC address for base-sepolia
323
+ maxAmountRequired: "50000", // 0.05 USDC (should pass 0.1 filter)
324
+ network: "base-sepolia",
325
+ scheme: "exact",
326
+ description: "Test service 3",
327
+ outputSchema: { type: "object" },
328
+ extra: { name: "USDC" },
329
+ },
330
+ ],
331
+ },
332
+ ],
333
+ });
334
+ mockUseFacilitator.mockReturnValue({ list: mockList });
335
+ // Mock the utility functions for this test
336
+ mockGetX402Network.mockReturnValue("base-sepolia");
337
+ mockIsUsdcAsset.mockReturnValue(true); // All assets are USDC
338
+ mockConvertWholeUnitsToAtomic
339
+ .mockResolvedValueOnce("100000") // 0.1 USDC in atomic units
340
+ .mockResolvedValueOnce("100000")
341
+ .mockResolvedValueOnce("100000");
342
+ mockFormatPaymentOption.mockResolvedValue("formatted payment option");
343
+ const result = await provider.discoverX402Services(makeMockWalletProvider("base-sepolia"), {
344
+ maxUsdcPrice: 0.1,
345
+ });
346
+ const parsed = JSON.parse(result);
347
+ expect(parsed.success).toBe(true);
348
+ expect(parsed.returned).toBe(2);
349
+ expect(parsed.items.map(item => item.resource)).toEqual(expect.arrayContaining(["https://example.com/service1", "https://example.com/service3"]));
350
+ });
351
+ it("should handle errors from facilitator", async () => {
352
+ const mockList = jest.fn().mockRejectedValue(new Error("boom"));
353
+ mockUseFacilitator.mockReturnValue({ list: mockList });
354
+ const result = await provider.discoverX402Services(makeMockWalletProvider("base-sepolia"), {});
355
+ const parsed = JSON.parse(result);
356
+ expect(parsed.error).toBe(true);
357
+ expect(parsed.message).toContain("Failed to list x402 services");
358
+ });
359
+ });
213
360
  describe("retryHttpRequestWithX402", () => {
214
361
  it("should successfully retry with payment", async () => {
215
362
  mockDecodeXPaymentResponse.mockReturnValue(MOCK_PAYMENT_RESPONSE);
363
+ mockGetX402Network.mockReturnValue("base-sepolia");
216
364
  mockRequest.mockResolvedValue({
217
365
  status: 200,
218
366
  statusText: "OK",
@@ -222,7 +370,7 @@ describe("X402ActionProvider", () => {
222
370
  },
223
371
  config: {},
224
372
  });
225
- const result = await provider.retryWithX402(mockWalletProvider, {
373
+ const result = await provider.retryWithX402(makeMockWalletProvider("base-sepolia"), {
226
374
  url: "https://www.x402.org/protected",
227
375
  method: "GET",
228
376
  selectedPaymentOption: {
@@ -247,7 +395,8 @@ describe("X402ActionProvider", () => {
247
395
  error.isAxiosError = true;
248
396
  error.request = {};
249
397
  mockRequest.mockRejectedValue(error);
250
- const result = await provider.retryWithX402(mockWalletProvider, {
398
+ mockGetX402Network.mockReturnValue("base-sepolia");
399
+ const result = await provider.retryWithX402(makeMockWalletProvider("base-sepolia"), {
251
400
  url: "https://www.x402.org/protected",
252
401
  method: "GET",
253
402
  selectedPaymentOption: {
@@ -274,7 +423,7 @@ describe("X402ActionProvider", () => {
274
423
  },
275
424
  config: {},
276
425
  });
277
- const result = await provider.makeHttpRequestWithX402(mockWalletProvider, {
426
+ const result = await provider.makeHttpRequestWithX402(makeMockWalletProvider("base-sepolia"), {
278
427
  url: "https://www.x402.org/protected",
279
428
  method: "GET",
280
429
  });
@@ -289,6 +438,7 @@ describe("X402ActionProvider", () => {
289
438
  });
290
439
  });
291
440
  it("should handle successful non-payment requests", async () => {
441
+ mockDecodeXPaymentResponse.mockReturnValue(null); // No payment made
292
442
  mockRequest.mockResolvedValue({
293
443
  status: 200,
294
444
  statusText: "OK",
@@ -296,7 +446,7 @@ describe("X402ActionProvider", () => {
296
446
  headers: {},
297
447
  config: {},
298
448
  });
299
- const result = await provider.makeHttpRequestWithX402(mockWalletProvider, {
449
+ const result = await provider.makeHttpRequestWithX402(makeMockWalletProvider("base-sepolia"), {
300
450
  url: "https://api.example.com/free",
301
451
  method: "GET",
302
452
  });
@@ -310,7 +460,7 @@ describe("X402ActionProvider", () => {
310
460
  error.isAxiosError = true;
311
461
  error.request = {};
312
462
  mockRequest.mockRejectedValue(error);
313
- const result = await provider.makeHttpRequestWithX402(mockWalletProvider, {
463
+ const result = await provider.makeHttpRequestWithX402(makeMockWalletProvider("base-sepolia"), {
314
464
  url: "https://api.example.com/endpoint",
315
465
  method: "GET",
316
466
  });
@@ -0,0 +1,64 @@
1
+ export declare const YELAY_BACKEND_URL = "https://lite.api.yelay.io/v2";
2
+ export declare const RETAIL_POOL_ID = 10;
3
+ export declare const YELAY_VAULT_ABI: {
4
+ type: string;
5
+ name: string;
6
+ inputs: {
7
+ name: string;
8
+ type: string;
9
+ internalType: string;
10
+ }[];
11
+ outputs: {
12
+ name: string;
13
+ type: string;
14
+ internalType: string;
15
+ }[];
16
+ stateMutability: string;
17
+ }[];
18
+ export declare const YIELD_EXTRACTOR_ABI: ({
19
+ inputs: {
20
+ components: {
21
+ internalType: string;
22
+ name: string;
23
+ type: string;
24
+ }[];
25
+ internalType: string;
26
+ name: string;
27
+ type: string;
28
+ }[];
29
+ name: string;
30
+ outputs: never[];
31
+ stateMutability: string;
32
+ type: string;
33
+ } | {
34
+ inputs: {
35
+ internalType: string;
36
+ name: string;
37
+ type: string;
38
+ }[];
39
+ name: string;
40
+ outputs: {
41
+ internalType: string;
42
+ name: string;
43
+ type: string;
44
+ }[];
45
+ stateMutability: string;
46
+ type: string;
47
+ })[];
48
+ export declare const CONTRACTS_BY_CHAIN: {
49
+ readonly 1: {
50
+ readonly YieldExtractor: "0x226239384EB7d78Cdf279BA6Fb458E2A4945E275";
51
+ };
52
+ readonly 146: {
53
+ readonly YieldExtractor: "0xB84B621D3da3E5e47A1927883C685455Ad731D7C";
54
+ };
55
+ readonly 8453: {
56
+ readonly YieldExtractor: "0x4d6a89dc55d8bacc0cbc3824bd7e44fa051c3958";
57
+ };
58
+ readonly 42161: {
59
+ readonly YieldExtractor: "0x79b7e90F1BAe837362DBD2c83Bd0715c2De5E47f";
60
+ };
61
+ readonly 43114: {
62
+ readonly YieldExtractor: "0x98732e2FEb854bAd400D4b5336f4439E7E53fe88";
63
+ };
64
+ };