@nevermined-io/payments 1.5.0 → 1.7.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 (56) hide show
  1. package/README.md +121 -93
  2. package/dist/api/agents-api.d.ts.map +1 -1
  3. package/dist/api/agents-api.js +2 -2
  4. package/dist/api/agents-api.js.map +1 -1
  5. package/dist/api/base-payments.d.ts +6 -4
  6. package/dist/api/base-payments.d.ts.map +1 -1
  7. package/dist/api/base-payments.js +10 -0
  8. package/dist/api/base-payments.js.map +1 -1
  9. package/dist/api/contracts-api.js +1 -1
  10. package/dist/api/contracts-api.js.map +1 -1
  11. package/dist/api/plans-api.d.ts.map +1 -1
  12. package/dist/api/plans-api.js +3 -10
  13. package/dist/api/plans-api.js.map +1 -1
  14. package/dist/common/api-version.d.ts +24 -0
  15. package/dist/common/api-version.d.ts.map +1 -0
  16. package/dist/common/api-version.js +24 -0
  17. package/dist/common/api-version.js.map +1 -0
  18. package/dist/common/types.d.ts +73 -18
  19. package/dist/common/types.d.ts.map +1 -1
  20. package/dist/common/types.js.map +1 -1
  21. package/dist/index.d.ts +1 -0
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +1 -0
  24. package/dist/index.js.map +1 -1
  25. package/dist/payments.d.ts +4 -3
  26. package/dist/payments.d.ts.map +1 -1
  27. package/dist/payments.js +5 -3
  28. package/dist/payments.js.map +1 -1
  29. package/dist/x402/index.d.ts +1 -1
  30. package/dist/x402/index.d.ts.map +1 -1
  31. package/dist/x402/index.js.map +1 -1
  32. package/dist/x402/langchain/agent.d.ts +96 -0
  33. package/dist/x402/langchain/agent.d.ts.map +1 -0
  34. package/dist/x402/langchain/agent.js +121 -0
  35. package/dist/x402/langchain/agent.js.map +1 -0
  36. package/dist/x402/langchain/decorator.d.ts +43 -4
  37. package/dist/x402/langchain/decorator.d.ts.map +1 -1
  38. package/dist/x402/langchain/decorator.js +173 -6
  39. package/dist/x402/langchain/decorator.js.map +1 -1
  40. package/dist/x402/langchain/index.d.ts +2 -1
  41. package/dist/x402/langchain/index.d.ts.map +1 -1
  42. package/dist/x402/langchain/index.js +2 -1
  43. package/dist/x402/langchain/index.js.map +1 -1
  44. package/dist/x402/langsmith/index.d.ts +15 -0
  45. package/dist/x402/langsmith/index.d.ts.map +1 -0
  46. package/dist/x402/langsmith/index.js +15 -0
  47. package/dist/x402/langsmith/index.js.map +1 -0
  48. package/dist/x402/langsmith/spans.d.ts +163 -0
  49. package/dist/x402/langsmith/spans.d.ts.map +1 -0
  50. package/dist/x402/langsmith/spans.js +341 -0
  51. package/dist/x402/langsmith/spans.js.map +1 -0
  52. package/dist/x402/token.d.ts +13 -10
  53. package/dist/x402/token.d.ts.map +1 -1
  54. package/dist/x402/token.js +46 -16
  55. package/dist/x402/token.js.map +1 -1
  56. package/package.json +16 -2
package/README.md CHANGED
@@ -19,16 +19,15 @@ The Nevermined Payments Library is a TypeScript SDK that allows AI Builders and
19
19
 
20
20
  The Payments Library enables:
21
21
 
22
- * Easy registration and discovery of AI agents and the payment plans required to access them. All agents registered in Nevermined expose their metadata in a generic way, making them searchable and discoverable for specific purposes.
23
- * Flexible definition of pricing options and how AI agents can be queried. This is achieved through payment plans (based on time or credits) and consumption costs (fixed per request or dynamic). All of this can be defined by the AI builder or agent during the registration process.
24
- * Subscribers (humans or other agents) to purchase credits that grant access to AI agent services. Payments can be made in crypto or fiat via Stripe integration. The protocol registers the payment and credits distribution settlement on-chain.
25
- * Agents or users with access credits to query other AI agents. Nevermined authorizes only users with sufficient balance and keeps track of their credit usage.
26
-
22
+ - Easy registration and discovery of AI agents and the payment plans required to access them. All agents registered in Nevermined expose their metadata in a generic way, making them searchable and discoverable for specific purposes.
23
+ - Flexible definition of pricing options and how AI agents can be queried. This is achieved through payment plans (based on time or credits) and consumption costs (fixed per request or dynamic). All of this can be defined by the AI builder or agent during the registration process.
24
+ - Subscribers (humans or other agents) to purchase credits that grant access to AI agent services. Payments can be made in crypto or fiat via Stripe integration. The protocol registers the payment and credits distribution settlement on-chain.
25
+ - Agents or users with access credits to query other AI agents. Nevermined authorizes only users with sufficient balance and keeps track of their credit usage.
27
26
 
28
27
  The library is designed for use in browser environments or as part of AI Agents:
29
28
 
30
- * In a browser, the library provides a simple way to connect to the Nevermined protocol, allowing users to query AI Agents or publish their own.
31
- * As part of an AI Agent, the library allows the agent to query other agents programmatically. Additionally, agents can use the library to expose their own services and make them available to other agents or humans.
29
+ - In a browser, the library provides a simple way to connect to the Nevermined protocol, allowing users to query AI Agents or publish their own.
30
+ - As part of an AI Agent, the library allows the agent to query other agents programmatically. Additionally, agents can use the library to expose their own services and make them available to other agents or humans.
32
31
 
33
32
  ## Quickstart
34
33
 
@@ -41,6 +40,7 @@ npm install @nevermined-io/payments@^1.1
41
40
  ```
42
41
 
43
42
  > Pin the major version (or rely on a committed lockfile) so SDK upgrades are explicit. Always commit `package-lock.json` / `pnpm-lock.yaml`.
43
+
44
44
  ## A2A Integration (Agents‑to‑Agents)
45
45
 
46
46
  Nevermined Payments integrates with the A2A protocol to authorize and charge per request between agents:
@@ -78,13 +78,13 @@ Add a payment extension under `capabilities.extensions` carrying Nevermined meta
78
78
  ```
79
79
 
80
80
  Important notes:
81
+
81
82
  - The `url` must match exactly the URL registered in Nevermined for the agent/plan.
82
83
  - The final streaming event must include `metadata.creditsUsed` with the consumed cost.
83
84
 
84
-
85
85
  ## Requirements
86
86
 
87
- To use the Nevermined Payments Library, you need to get your Nevermined API key. You can get yours freely from the [Nevermined App](https://nevermined.app).
87
+ To use the Nevermined Payments Library, you need to get your Nevermined API key. You can get yours freely from the [Nevermined App](https://nevermined.app).
88
88
 
89
89
  ### Environments
90
90
 
@@ -92,6 +92,15 @@ To use the Nevermined Payments Library, you need to get your Nevermined API key.
92
92
 
93
93
  Pick the environment that matches where your agent and plans are registered. The agent card `url` must belong to that environment.
94
94
 
95
+ ### Optional peer dependencies
96
+
97
+ The core SDK has no required runtime peers. Some integrations are gated behind optional peer dependencies you install only if you use them:
98
+
99
+ - **LangChain tool protection** (`@nevermined-io/payments/langchain`) — requires `@langchain/core` and `@langchain/langgraph >=1.0.0 <2`.
100
+ - **LangSmith observability** (`@nevermined-io/payments/langsmith`, and the spans the `requiresPayment` wrapper emits when `LANGSMITH_TRACING=true`) — requires **`langsmith >=0.7`**. The spans rely on `getCurrentRunTree` (exported from `langsmith/singletons/traceable`) and the merging `RunTree.metadata` setter, both of which are only reliably present from `0.7` onward. Install it yourself: `pnpm add langsmith`.
101
+
102
+ These are declared as optional peers, so npm/pnpm will not pull them in automatically and the SDK no-ops cleanly when they are absent.
103
+
95
104
  ### Initialize the Payments library in the Browser
96
105
 
97
106
  This is a browser only method. Here we have an example using react.
@@ -124,7 +133,7 @@ export default function Home() {
124
133
  ### Initialize the Payments library in an AI Agent
125
134
 
126
135
  ```typescript
127
- import { Payments } from "@nevermined-io/payments";
136
+ import { Payments } from '@nevermined-io/payments'
128
137
 
129
138
  const payments = Payments.getInstance({
130
139
  nvmApiKey,
@@ -138,19 +147,29 @@ Once the app is initialized we can create a payment plan:
138
147
 
139
148
  ```typescript
140
149
  const planMetadata: PlanMetadata = {
141
- name: 'E2E test Payments Plan',
142
- }
150
+ name: 'E2E test Payments Plan',
151
+ }
143
152
  const priceConfig = payments.plans.getERC20PriceConfig(20n, ERC20_ADDRESS, builderAddress)
144
153
  const creditsConfig = payments.plans.getFixedCreditsConfig(100n)
145
- const { planId } = await payments.plans.registerCreditsPlan(planMetadata, priceConfig, creditsConfig)
154
+ const { planId } = await payments.plans.registerCreditsPlan(
155
+ planMetadata,
156
+ priceConfig,
157
+ creditsConfig,
158
+ )
146
159
  ```
147
160
 
148
161
  Or register a plan limited by time:
149
162
 
150
163
  ```typescript
151
164
  const priceConfig = payments.plans.getERC20PriceConfig(50n, ERC20_ADDRESS, builderAddress)
152
- const expirablePlanConfig = payments.plans.getExpirableDurationConfig(payments.plans.ONE_DAY_DURATION) // 1 day
153
- const response = await payments.plans.registerTimePlan(planMetadata, priceConfig, expirablePlanConfig)
165
+ const expirablePlanConfig = payments.plans.getExpirableDurationConfig(
166
+ payments.plans.ONE_DAY_DURATION,
167
+ ) // 1 day
168
+ const response = await payments.plans.registerTimePlan(
169
+ planMetadata,
170
+ priceConfig,
171
+ expirablePlanConfig,
172
+ )
154
173
  ```
155
174
 
156
175
  You can also create trial plans (free plans that can only be purchased once):
@@ -166,7 +185,7 @@ const trialCreditsConfig = payments.plans.getFixedCreditsConfig(10n)
166
185
  const trialPlan = await payments.plans.registerCreditsTrialPlan(
167
186
  trialPlanMetadata,
168
187
  freePriceConfig,
169
- trialCreditsConfig
188
+ trialCreditsConfig,
170
189
  )
171
190
 
172
191
  // Time-based trial plan
@@ -174,7 +193,7 @@ const timeTrialConfig = payments.plans.getExpirableDurationConfig(ONE_DAY_DURATI
174
193
  const timeTrialPlan = await payments.plans.registerTimeTrialPlan(
175
194
  trialPlanMetadata,
176
195
  freePriceConfig,
177
- timeTrialConfig
196
+ timeTrialConfig,
178
197
  )
179
198
  ```
180
199
 
@@ -192,12 +211,13 @@ const agentMetadata = {
192
211
  // The API that the agent will expose
193
212
  const agentApi = {
194
213
  endpoints: [
195
- { 'POST': `https://example.com/api/v1/agents/:agentId/tasks` },
196
- { 'GET': `https://example.com/api/v1/agents/:agentId/tasks/invoke` }
197
- ]}
214
+ { POST: `https://example.com/api/v1/agents/:agentId/tasks` },
215
+ { GET: `https://example.com/api/v1/agents/:agentId/tasks/invoke` },
216
+ ],
217
+ }
198
218
 
199
219
  // This is the list of payment plans that the agent will accept
200
- const paymentPlans = [ creditsPlanId, expirablePlanId ]
220
+ const paymentPlans = [creditsPlanId, expirablePlanId]
201
221
  const result = await payments.agents.registerAgent(agentMetadata, agentApi, paymentPlans)
202
222
  ```
203
223
 
@@ -212,9 +232,7 @@ const agentMetadata = {
212
232
  }
213
233
 
214
234
  const agentApi = {
215
- endpoints: [
216
- { 'POST': 'https://example.com/api/v1/agents/:agentId/tasks' }
217
- ]
235
+ endpoints: [{ POST: 'https://example.com/api/v1/agents/:agentId/tasks' }],
218
236
  }
219
237
 
220
238
  const planMetadata = { name: 'Basic Plan' }
@@ -228,11 +246,12 @@ const { agentId, planId, txHash } = await payments.agents.registerAgentAndPlan(
228
246
  planMetadata,
229
247
  priceConfig,
230
248
  creditsConfig,
231
- 'time' // Optionally set access limit to 'time' or 'credits'
249
+ 'time', // Optionally set access limit to 'time' or 'credits'
232
250
  )
233
251
  ```
234
252
 
235
253
  The `accessLimit` parameter is optional. If not specified, it's automatically inferred:
254
+
236
255
  - `'credits'` if `creditsConfig.durationSecs === 0n` (non-expirable)
237
256
  - `'time'` if `creditsConfig.durationSecs > 0n` (expirable)
238
257
 
@@ -261,7 +280,7 @@ const agentHTTPOptions = {
261
280
  headers: {
262
281
  Accept: 'application/json',
263
282
  'Content-Type': 'application/json',
264
- 'payment-signature': accessToken
283
+ 'payment-signature': accessToken,
265
284
  },
266
285
  }
267
286
  const response = await fetch(new URL(agentURL), agentHTTPOptions)
@@ -281,7 +300,7 @@ MCP servers expose handlers (tools/resources/prompts) with their logical URLs, s
281
300
 
282
301
  ### Why Nevermined Payments?
283
302
 
284
- While MCP defines *what* an agent can do, it doesn't specify *who* can access it or *how* to charge for it. **Nevermined Payments** adds:
303
+ While MCP defines _what_ an agent can do, it doesn't specify _who_ can access it or _how_ to charge for it. **Nevermined Payments** adds:
285
304
 
286
305
  - **Authentication**: Validates user tokens via `Authorization` header
287
306
  - **Credit System**: Checks and deducts credits per request
@@ -292,77 +311,77 @@ While MCP defines *what* an agent can do, it doesn't specify *who* can access it
292
311
  #### 1. Initialize Nevermined Payments
293
312
 
294
313
  ```typescript
295
- import { Payments, EnvironmentName } from "@nevermined-io/payments";
314
+ import { Payments, EnvironmentName } from '@nevermined-io/payments'
296
315
 
297
316
  const payments = Payments.getInstance({
298
317
  nvmApiKey: process.env.NVM_API_KEY!,
299
318
  environment: process.env.NVM_ENVIRONMENT! as EnvironmentName,
300
- });
319
+ })
301
320
  ```
302
321
 
303
322
  #### 2. Register Protected Tools
304
323
 
305
324
  ```typescript
306
- import { z } from "zod";
325
+ import { z } from 'zod'
307
326
 
308
327
  const schema = z.object({
309
- city: z.string().describe("City name"),
310
- }) as any;
328
+ city: z.string().describe('City name'),
329
+ }) as any
311
330
 
312
331
  payments.mcp.registerTool(
313
- "weather.today",
332
+ 'weather.today',
314
333
  {
315
334
  title: "Today's Weather",
316
- description: "Get weather for a city",
335
+ description: 'Get weather for a city',
317
336
  inputSchema: schema,
318
337
  },
319
338
  async (args) => {
320
- const { city } = args as { city: string };
339
+ const { city } = args as { city: string }
321
340
  return {
322
- content: [{ type: "text", text: `Weather for ${city}: Sunny, 25C` }],
323
- };
341
+ content: [{ type: 'text', text: `Weather for ${city}: Sunny, 25C` }],
342
+ }
324
343
  },
325
- { credits: 1n }
326
- );
344
+ { credits: 1n },
345
+ )
327
346
  ```
328
347
 
329
348
  #### 3. Register Protected Resources
330
349
 
331
350
  ```typescript
332
351
  payments.mcp.registerResource(
333
- "Weather Data",
334
- "weather://today",
352
+ 'Weather Data',
353
+ 'weather://today',
335
354
  {
336
355
  title: "Today's Weather",
337
- description: "JSON weather data",
338
- mimeType: "application/json",
356
+ description: 'JSON weather data',
357
+ mimeType: 'application/json',
339
358
  },
340
359
  async (uri) => {
341
360
  return {
342
- contents: [{ uri: uri.href, text: "{...}", mimeType: "application/json" }],
343
- };
361
+ contents: [{ uri: uri.href, text: '{...}', mimeType: 'application/json' }],
362
+ }
344
363
  },
345
- { credits: 5n }
346
- );
364
+ { credits: 5n },
365
+ )
347
366
  ```
348
367
 
349
368
  #### 4. Register Protected Prompts
350
369
 
351
370
  ```typescript
352
371
  payments.mcp.registerPrompt(
353
- "weather.ensureCity",
372
+ 'weather.ensureCity',
354
373
  {
355
- title: "Ensure city",
356
- description: "Guide to call weather.today",
374
+ title: 'Ensure city',
375
+ description: 'Guide to call weather.today',
357
376
  argsSchema: schema,
358
377
  },
359
378
  (args) => {
360
379
  return {
361
- messages: [{ role: "user", content: { type: "text", text: "..." } }],
362
- };
380
+ messages: [{ role: 'user', content: { type: 'text', text: '...' } }],
381
+ }
363
382
  },
364
- { credits: (ctx) => ctx.result.length > 100 ? 2n : 1n } // Dynamic credits
365
- );
383
+ { credits: (ctx) => (ctx.result.length > 100 ? 2n : 1n) }, // Dynamic credits
384
+ )
366
385
  ```
367
386
 
368
387
  #### 5. Start the Server
@@ -371,9 +390,9 @@ payments.mcp.registerPrompt(
371
390
  const { info, stop } = await payments.mcp.start({
372
391
  port: 3002,
373
392
  agentId: process.env.NVM_AGENT_ID!,
374
- serverName: "weather-mcp",
375
- version: "0.1.0",
376
- });
393
+ serverName: 'weather-mcp',
394
+ version: '0.1.0',
395
+ })
377
396
  ```
378
397
 
379
398
  ### Credit Configuration
@@ -382,22 +401,32 @@ All registration functions support fixed or dynamic credits:
382
401
 
383
402
  ```typescript
384
403
  // Fixed credits
385
- { credits: 1n }
386
- { credits: 5n }
404
+ {
405
+ credits: 1n
406
+ }
407
+ {
408
+ credits: 5n
409
+ }
387
410
 
388
411
  // Dynamic credits based on input
389
- { credits: (ctx) => ctx.args.premium ? 5n : 1n }
412
+ {
413
+ credits: (ctx) => (ctx.args.premium ? 5n : 1n)
414
+ }
390
415
 
391
416
  // Dynamic credits based on result
392
- { credits: (ctx) => ctx.result.length > 1000 ? 3n : 1n }
417
+ {
418
+ credits: (ctx) => (ctx.result.length > 1000 ? 3n : 1n)
419
+ }
393
420
 
394
421
  // Tiered pricing
395
- { credits: (ctx) => {
396
- const size = JSON.stringify(ctx.result).length;
397
- if (size > 1000) return 5n;
398
- if (size > 500) return 3n;
399
- return 1n;
400
- }}
422
+ {
423
+ credits: (ctx) => {
424
+ const size = JSON.stringify(ctx.result).length
425
+ if (size > 1000) return 5n
426
+ if (size > 500) return 3n
427
+ return 1n
428
+ }
429
+ }
401
430
  ```
402
431
 
403
432
  ### Client Usage
@@ -405,55 +434,54 @@ All registration functions support fixed or dynamic credits:
405
434
  #### Get Access Token
406
435
 
407
436
  ```typescript
408
- import { Payments } from "@nevermined-io/payments";
437
+ import { Payments } from '@nevermined-io/payments'
409
438
 
410
439
  const payments = Payments.getInstance({
411
440
  nvmApiKey: process.env.NVM_API_KEY!,
412
- environment: "sandbox",
413
- });
441
+ environment: 'sandbox',
442
+ })
414
443
 
415
444
  const { accessToken } = await payments.x402.getX402AccessToken(
416
445
  process.env.NVM_PLAN_ID!,
417
- process.env.NVM_AGENT_ID!
418
- );
446
+ process.env.NVM_AGENT_ID!,
447
+ )
419
448
  ```
420
449
 
421
450
  #### Call Protected Tools
422
451
 
423
452
  ```typescript
424
- import { Client } from "@modelcontextprotocol/sdk/client";
425
- import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp";
453
+ import { Client } from '@modelcontextprotocol/sdk/client'
454
+ import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp'
426
455
 
427
- const transport = new StreamableHTTPClientTransport(
428
- new URL("http://localhost:3002/mcp"),
429
- { requestInit: { headers: { Authorization: `Bearer ${accessToken}` } } }
430
- );
456
+ const transport = new StreamableHTTPClientTransport(new URL('http://localhost:3002/mcp'), {
457
+ requestInit: { headers: { Authorization: `Bearer ${accessToken}` } },
458
+ })
431
459
 
432
- const client = new Client({ name: "my-client" });
433
- await client.connect(transport);
460
+ const client = new Client({ name: 'my-client' })
461
+ await client.connect(transport)
434
462
 
435
463
  const result = await client.callTool({
436
- name: "weather.today",
437
- arguments: { city: "London" },
438
- });
464
+ name: 'weather.today',
465
+ arguments: { city: 'London' },
466
+ })
439
467
  ```
440
468
 
441
469
  ### Endpoints
442
470
 
443
- | Endpoint | Description |
444
- |----------|-------------|
445
- | `POST /mcp` | MCP JSON-RPC requests |
446
- | `GET /mcp` | SSE stream for notifications |
447
- | `DELETE /mcp` | Session termination |
448
- | `GET /health` | Health check |
449
- | `GET /` | Server info |
471
+ | Endpoint | Description |
472
+ | ------------- | ---------------------------- |
473
+ | `POST /mcp` | MCP JSON-RPC requests |
474
+ | `GET /mcp` | SSE stream for notifications |
475
+ | `DELETE /mcp` | Session termination |
476
+ | `GET /health` | Health check |
477
+ | `GET /` | Server info |
450
478
 
451
479
  ### Error Codes
452
480
 
453
- | Code | Description |
454
- |------|-------------|
481
+ | Code | Description |
482
+ | -------- | ---------------------------------------------------------------- |
455
483
  | `-32003` | Authorization required / Payment required / Insufficient credits |
456
- | `-32002` | Server error |
484
+ | `-32002` | Server error |
457
485
 
458
486
  ### Notes
459
487
 
@@ -1 +1 @@
1
- {"version":3,"file":"agents-api.d.ts","sourceRoot":"","sources":["../../src/api/agents-api.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,kBAAkB,EAClB,aAAa,EACb,YAAY,EACZ,iBAAiB,EACjB,cAAc,EACd,iBAAiB,EACjB,YAAY,EACZ,eAAe,EAChB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAA6B,MAAM,oBAAoB,CAAA;AAWnG,YAAY,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AAE5D;;GAEG;AACH,qBAAa,SAAU,SAAQ,eAAe;IAC5C;;;;;OAKG;IACH,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE,cAAc,GAAG,SAAS;IAItD;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;IACU,aAAa,CACxB,aAAa,EAAE,aAAa,EAC5B,QAAQ,EAAE,kBAAkB,EAC5B,YAAY,EAAE,MAAM,EAAE,EACtB,kBAAkB,CAAC,EAAE,kBAAkB,GACtC,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAsB/B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAiCG;IACU,oBAAoB,CAC/B,aAAa,EAAE,aAAa,EAC5B,QAAQ,EAAE,kBAAkB,EAC5B,YAAY,EAAE,YAAY,EAC1B,WAAW,EAAE,eAAe,EAC5B,aAAa,EAAE,iBAAiB,EAChC,WAAW,CAAC,EAAE,SAAS,GAAG,MAAM,EAChC,kBAAkB,CAAC,EAAE,kBAAkB,GACtC,OAAO,CAAC;QACT,OAAO,EAAE,MAAM,CAAA;QACf,MAAM,EAAE,MAAM,CAAA;QACd,MAAM,EAAE,MAAM,CAAA;KACf,CAAC;IAyCF;;;;;;;;;;;OAWG;IACU,QAAQ,CAAC,OAAO,EAAE,MAAM;IASrC;;;;;;;;;;;;;;;;OAgBG;IACU,mBAAmB,CAC9B,OAAO,EAAE,MAAM,EACf,aAAa,EAAE,aAAa,EAC5B,QAAQ,EAAE,kBAAkB,GAC3B,OAAO,CAAC,YAAY,CAAC;IAcxB;;;;;;;;;;;;;;;;;;OAkBG;IACU,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,oBAA0B;IAWhF;;;;;;;;;;;;;;;;;;;;OAoBG;IACU,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAYnF;;;;;;;;;;;;;;;;;;;;OAoBG;IACU,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;CAczF"}
1
+ {"version":3,"file":"agents-api.d.ts","sourceRoot":"","sources":["../../src/api/agents-api.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,kBAAkB,EAClB,aAAa,EACb,YAAY,EACZ,iBAAiB,EACjB,cAAc,EACd,iBAAiB,EACjB,YAAY,EACZ,eAAe,EAChB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAA6B,MAAM,oBAAoB,CAAA;AAWnG,YAAY,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AAE5D;;GAEG;AACH,qBAAa,SAAU,SAAQ,eAAe;IAC5C;;;;;OAKG;IACH,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE,cAAc,GAAG,SAAS;IAItD;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;IACU,aAAa,CACxB,aAAa,EAAE,aAAa,EAC5B,QAAQ,EAAE,kBAAkB,EAC5B,YAAY,EAAE,MAAM,EAAE,EACtB,kBAAkB,CAAC,EAAE,kBAAkB,GACtC,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAsB/B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAiCG;IACU,oBAAoB,CAC/B,aAAa,EAAE,aAAa,EAC5B,QAAQ,EAAE,kBAAkB,EAC5B,YAAY,EAAE,YAAY,EAC1B,WAAW,EAAE,eAAe,EAC5B,aAAa,EAAE,iBAAiB,EAChC,WAAW,CAAC,EAAE,SAAS,GAAG,MAAM,EAChC,kBAAkB,CAAC,EAAE,kBAAkB,GACtC,OAAO,CAAC;QACT,OAAO,EAAE,MAAM,CAAA;QACf,MAAM,EAAE,MAAM,CAAA;QACd,MAAM,EAAE,MAAM,CAAA;KACf,CAAC;IA4CF;;;;;;;;;;;OAWG;IACU,QAAQ,CAAC,OAAO,EAAE,MAAM;IASrC;;;;;;;;;;;;;;;;OAgBG;IACU,mBAAmB,CAC9B,OAAO,EAAE,MAAM,EACf,aAAa,EAAE,aAAa,EAC5B,QAAQ,EAAE,kBAAkB,GAC3B,OAAO,CAAC,YAAY,CAAC;IAcxB;;;;;;;;;;;;;;;;;;OAkBG;IACU,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,oBAA0B;IAWhF;;;;;;;;;;;;;;;;;;;;OAoBG;IACU,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAYnF;;;;;;;;;;;;;;;;;;;;OAoBG;IACU,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;CAiBzF"}
@@ -138,7 +138,7 @@ export class AgentsAPI extends BasePaymentsAPI {
138
138
  */
139
139
  async getAgent(agentId) {
140
140
  const url = new URL(API_URL_GET_AGENT.replace(':agentId', agentId), this.environment.backend);
141
- const response = await fetch(url);
141
+ const response = await fetch(url, this.getPublicHTTPOptions('GET'));
142
142
  if (!response.ok) {
143
143
  throw PaymentsError.fromBackend('Agent not found', await safeParseJson(response));
144
144
  }
@@ -196,7 +196,7 @@ export class AgentsAPI extends BasePaymentsAPI {
196
196
  async getAgentPlans(agentId, pagination = new PaginationOptions()) {
197
197
  const query = API_URL_GET_AGENT_PLANS.replace(':agentId', agentId) + '?' + pagination.asQueryParams();
198
198
  const url = new URL(query, this.environment.backend);
199
- const response = await fetch(url);
199
+ const response = await fetch(url, this.getPublicHTTPOptions('GET'));
200
200
  if (!response.ok) {
201
201
  throw PaymentsError.fromBackend('Agent not found', await safeParseJson(response));
202
202
  }
@@ -1 +1 @@
1
- {"version":3,"file":"agents-api.js","sourceRoot":"","sources":["../../src/api/agents-api.ts"],"names":[],"mappings":"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","sourcesContent":["import { safeParseJson } from '../common/helper.js'\nimport { PaymentsError } from '../common/payments.error.js'\nimport {\n AgentAPIAttributes,\n AgentMetadata,\n NvmAPIResult,\n PaginationOptions,\n PaymentOptions,\n PlanCreditsConfig,\n PlanMetadata,\n PlanPriceConfig,\n} from '../common/types.js'\nimport { BasePaymentsAPI, PublicationOptions, resolvePublicationHeaders } from './base-payments.js'\nimport {\n API_URL_ADD_PLAN_AGENT,\n API_URL_GET_AGENT,\n API_URL_GET_AGENT_PLANS,\n API_URL_REGISTER_AGENT,\n API_URL_REGISTER_AGENTS_AND_PLAN,\n API_URL_REMOVE_PLAN_AGENT,\n API_URL_UPDATE_AGENT,\n} from './nvm-api.js'\n\nexport type { PublicationOptions } from './base-payments.js'\n\n/**\n * The AgentsAPI class provides methods to register and interact with AI Agents on Nevermined.\n */\nexport class AgentsAPI extends BasePaymentsAPI {\n /**\n * This method is used to create a singleton instance of the AgentsAPI class.\n *\n * @param options - The options to initialize the payments class.\n * @returns The instance of the AgentsAPI class.\n */\n static getInstance(options: PaymentOptions): AgentsAPI {\n return new AgentsAPI(options)\n }\n\n /**\n *\n * It registers a new AI Agent on Nevermined.\n * The agent must be associated to one or multiple Payment Plans. Users that are subscribers of a payment plan can query the agent.\n * Depending on the Payment Plan and the configuration of the agent, the usage of the agent/service will consume credits.\n * When the plan expires (because the time is over or the credits are consumed), the user needs to renew the plan to continue using the agent.\n *\n * @remarks This method is oriented to AI Builders\n * @remarks To call this method, the NVM API Key must have publication permissions\n *\n * @see https://nevermined.ai/docs/tutorials/builders/register-agent\n *\n * @param agentMetadata - @see {@link AgentMetadata}\n * @param agentApi - @see {@link AgentAPIAttributes}\n * @param paymentPlans - the list of payment plans giving access to the agent.\n *\n * @example\n * ```\n * const agentMetadata = { name: 'My AI Payments Agent', tags: ['test'] }\n * const agentApi = { endpoints: [{ 'POST': 'https://example.com/api/v1/agents/:agentId/tasks' }] }\n * const paymentPlans = [planId]\n *\n * const { agentId } = await payments.agents.registerAgent(agentMetadata, agentApi, paymentPlans)\n * ```\n *\n * @returns The unique identifier of the newly created agent (Agent Id).\n */\n public async registerAgent(\n agentMetadata: AgentMetadata,\n agentApi: AgentAPIAttributes,\n paymentPlans: string[],\n publicationOptions?: PublicationOptions,\n ): Promise<{ agentId: string }> {\n const body = {\n metadataAttributes: agentMetadata,\n agentApiAttributes: agentApi,\n plans: paymentPlans,\n }\n\n const options = this.getBackendHTTPOptions(\n 'POST',\n body,\n resolvePublicationHeaders(publicationOptions),\n )\n const url = new URL(API_URL_REGISTER_AGENT, this.environment.backend)\n\n const response = await fetch(url, options)\n if (!response.ok) {\n throw PaymentsError.fromBackend('Unable to register agent', await safeParseJson(response))\n }\n const agentData = await response.json()\n return { agentId: agentData.data.agentId }\n }\n\n /**\n *\n * It registers a new AI Agent and a Payment Plan associated to this new agent.\n * Depending on the Payment Plan and the configuration of the agent, the usage of the agent/service will consume credits.\n * When the plan expires (because the time is over or the credits are consumed), the user needs to renew the plan to continue using the agent.\n *\n * @remarks This method is oriented to AI Builders\n * @remarks To call this method, the NVM API Key must have publication permissions\n *\n * @see https://nevermined.ai/docs/tutorials/builders/register-agent\n *\n * @param agentMetadata - @see {@link AgentMetadata}\n * @param agentApi - @see {@link AgentAPIAttributes}\n * @param planMetadata - @see {@link PlanMetadata}\n * @param priceConfig - @see {@link PlanPriceConfig}\n * @param creditsConfig - @see {@link PlanCreditsConfig}\n *\n * @example\n * ```\n * const agentMetadata = { name: 'My AI Payments Agent', tags: ['test'] }\n * const agentApi { endpoints: [{ 'POST': 'https://example.com/api/v1/agents/:agentId/tasks' }] }\n * const cryptoPriceConfig = getNativeTokenPriceConfig(100n, builderAddress)\n * const 1dayDurationPlan = getExpirableDurationConfig(ONE_DAY_DURATION)\n * const { agentId, planId } = await payments.agents.registerAgentAndPlan(\n * agentMetadata,\n * agentApi,\n * cryptoPriceConfig,\n * 1dayDurationPlan\n * )\n * ```\n *\n * @returns The unique identifier of the newly created agent (agentId).\n * @returns The unique identifier of the newly created plan (planId).\n */\n public async registerAgentAndPlan(\n agentMetadata: AgentMetadata,\n agentApi: AgentAPIAttributes,\n planMetadata: PlanMetadata,\n priceConfig: PlanPriceConfig,\n creditsConfig: PlanCreditsConfig,\n accessLimit?: 'credits' | 'time',\n publicationOptions?: PublicationOptions,\n ): Promise<{\n agentId: string\n planId: string\n txHash: string\n }> {\n if (accessLimit && !['credits', 'time'].includes(accessLimit)) {\n throw new PaymentsError(\n 'Invalid access limit',\n 'accessLimit must be either \"credits\" or \"time\"',\n )\n }\n if (!accessLimit) {\n accessLimit = creditsConfig.durationSecs > 0n ? 'time' : 'credits'\n }\n const body = {\n plan: {\n metadataAttributes: planMetadata,\n priceConfig: priceConfig,\n creditsConfig: creditsConfig,\n accessLimit,\n },\n agent: {\n metadataAttributes: agentMetadata,\n agentApiAttributes: agentApi,\n },\n }\n const options = this.getBackendHTTPOptions(\n 'POST',\n body,\n resolvePublicationHeaders(publicationOptions),\n )\n const url = new URL(API_URL_REGISTER_AGENTS_AND_PLAN, this.environment.backend)\n\n const response = await fetch(url, options)\n if (!response.ok) {\n throw PaymentsError.fromBackend('Unable to register agent & plan', await safeParseJson(response))\n }\n const result = await response.json()\n return {\n agentId: result.data.agentId,\n planId: result.data.planId,\n txHash: result.txHash,\n }\n }\n\n /**\n * Gets the metadata for a given Agent identifier.\n *\n * @param agentId - The unique identifier of the agent.\n * @returns A promise that resolves to the agent's metadata.\n * @throws PaymentsError if the agent is not found.\n *\n * @example\n * ```\n * const plan = payments.agents.getAgent(agentId)\n * ```\n */\n public async getAgent(agentId: string) {\n const url = new URL(API_URL_GET_AGENT.replace(':agentId', agentId), this.environment.backend)\n const response = await fetch(url)\n if (!response.ok) {\n throw PaymentsError.fromBackend('Agent not found', await safeParseJson(response))\n }\n return response.json()\n }\n\n /**\n * Updates the metadata and API attributes of an existing AI Agent.\n *\n * @param agentId - The unique identifier of the agent.\n * @param agentMetadata - The new metadata attributes for the agent.\n * @param agentApi - The new API attributes for the agent.\n * @returns @see {@link NvmAPIResult} A promise that resolves indicating if the operation was successful.\n * @throws PaymentsError if the agent is not found or if the update fails.\n *\n * @example\n * ```\n * const agentMetadata = { name: 'My Updated Agent', tags: ['test'] }\n * const agentApi = { endpoints: [{ 'POST': 'https://nevermined.app/api/v1/agents/:agentId/tasks' }] }\n *\n * await payments.agents.updateAgentMetadata(agentId, agentMetadata, agentApi)\n * ```\n */\n public async updateAgentMetadata(\n agentId: string,\n agentMetadata: AgentMetadata,\n agentApi: AgentAPIAttributes,\n ): Promise<NvmAPIResult> {\n const body = {\n metadataAttributes: agentMetadata,\n agentApiAttributes: agentApi,\n }\n const url = new URL(API_URL_UPDATE_AGENT.replace(':agentId', agentId), this.environment.backend)\n const options = this.getBackendHTTPOptions('PUT', body)\n const response = await fetch(url, options)\n if (!response.ok) {\n throw PaymentsError.fromBackend('Error updating agent', await safeParseJson(response))\n }\n return response.json()\n }\n\n /**\n * Gets the list of plans that can be ordered to get access to an agent.\n *\n * @param agentId - The unique identifier of the agent.\n * @param pagination - Optional pagination options to control the number of results returned.p\n * @returns A promise that resolves to the list of all different plans giving access to the agent.\n * @throws PaymentsError if the agent is not found.\n *\n * @example\n * ```\n * const result = payments.agents.getAgentPlans(planId)\n * // {\n * // total: 10,\n * // page: 1,\n * // offset: 5,\n * // plans: [ ..]\n * // }\n * ```\n */\n public async getAgentPlans(agentId: string, pagination = new PaginationOptions()) {\n const query =\n API_URL_GET_AGENT_PLANS.replace(':agentId', agentId) + '?' + pagination.asQueryParams()\n const url = new URL(query, this.environment.backend)\n const response = await fetch(url)\n if (!response.ok) {\n throw PaymentsError.fromBackend('Agent not found', await safeParseJson(response))\n }\n return response.json()\n }\n\n /**\n * Adds an existing Payment Plan to an AI Agent.\n * After this operation, users with access to the Payment Plan will be able to access the AI Agent.\n *\n * @remarks\n * Only the owner of the Payment Plan can call this method.\n *\n * @param planId - The unique identifier of the Payment Plan.\n * @param agentId - The unique identifier of the AI Agent.\n * @returns @see {@link NvmAPIResult} A promise that resolves indicating if the operation was successful.\n * @throws PaymentsError if unable to add the plan to the agent.\n *\n * @example\n * ```\n * const result = await payments.agents.addPlanToAgent(planId, agentId)\n * // {\n * // txHash: '0x8d29d5769e832a35e53f80cd4e8890d941c50a09c33dbd975533debc894f2535',\n * // success: true\n * // }\n * ```\n */\n public async addPlanToAgent(planId: string, agentId: string): Promise<NvmAPIResult> {\n const options = this.getBackendHTTPOptions('POST')\n const endpoint = API_URL_ADD_PLAN_AGENT.replace(':planId', planId).replace(':agentId', agentId)\n const url = new URL(endpoint, this.environment.backend)\n const response = await fetch(url, options)\n if (!response.ok) {\n throw PaymentsError.fromBackend('Unable to add plan to agent', await safeParseJson(response))\n }\n\n return response.json()\n }\n\n /**\n * Removes a Payment Plan from an AI Agent.\n * After this operation, users with access to the Payment Plan will no longer be able to access the AI Agent.\n *\n * @remarks\n * Only the owner of the Payment Plan can call this method.\n *\n * @param planId - The unique identifier of the Payment Plan.\n * @param agentId - The unique identifier of the AI Agent.\n * @returns @see {@link NvmAPIResult} A promise that resolves indicating if the operation was successful.\n * @throws PaymentsError if unable to remove the plan from the agent.\n *\n * @example\n * ```\n * const result = await payments.agents.removePlanFromAgent(planId, agentId)\n * // {\n * // txHash: '0x8d29d5769e832a35e53f80cd4e8890d941c50a09c33dbd975533debc894f2535',\n * // success: true\n * // }\n * ```\n */\n public async removePlanFromAgent(planId: string, agentId: string): Promise<NvmAPIResult> {\n const options = this.getBackendHTTPOptions('DELETE')\n const endpoint = API_URL_REMOVE_PLAN_AGENT.replace(':planId', planId).replace(\n ':agentId',\n agentId,\n )\n const url = new URL(endpoint, this.environment.backend)\n const response = await fetch(url, options)\n if (!response.ok) {\n throw PaymentsError.fromBackend('Unable to remove plan from agent', await safeParseJson(response))\n }\n\n return response.json()\n }\n}\n"]}
1
+ {"version":3,"file":"agents-api.js","sourceRoot":"","sources":["../../src/api/agents-api.ts"],"names":[],"mappings":"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","sourcesContent":["import { safeParseJson } from '../common/helper.js'\nimport { PaymentsError } from '../common/payments.error.js'\nimport {\n AgentAPIAttributes,\n AgentMetadata,\n NvmAPIResult,\n PaginationOptions,\n PaymentOptions,\n PlanCreditsConfig,\n PlanMetadata,\n PlanPriceConfig,\n} from '../common/types.js'\nimport { BasePaymentsAPI, PublicationOptions, resolvePublicationHeaders } from './base-payments.js'\nimport {\n API_URL_ADD_PLAN_AGENT,\n API_URL_GET_AGENT,\n API_URL_GET_AGENT_PLANS,\n API_URL_REGISTER_AGENT,\n API_URL_REGISTER_AGENTS_AND_PLAN,\n API_URL_REMOVE_PLAN_AGENT,\n API_URL_UPDATE_AGENT,\n} from './nvm-api.js'\n\nexport type { PublicationOptions } from './base-payments.js'\n\n/**\n * The AgentsAPI class provides methods to register and interact with AI Agents on Nevermined.\n */\nexport class AgentsAPI extends BasePaymentsAPI {\n /**\n * This method is used to create a singleton instance of the AgentsAPI class.\n *\n * @param options - The options to initialize the payments class.\n * @returns The instance of the AgentsAPI class.\n */\n static getInstance(options: PaymentOptions): AgentsAPI {\n return new AgentsAPI(options)\n }\n\n /**\n *\n * It registers a new AI Agent on Nevermined.\n * The agent must be associated to one or multiple Payment Plans. Users that are subscribers of a payment plan can query the agent.\n * Depending on the Payment Plan and the configuration of the agent, the usage of the agent/service will consume credits.\n * When the plan expires (because the time is over or the credits are consumed), the user needs to renew the plan to continue using the agent.\n *\n * @remarks This method is oriented to AI Builders\n * @remarks To call this method, the NVM API Key must have publication permissions\n *\n * @see https://nevermined.ai/docs/tutorials/builders/register-agent\n *\n * @param agentMetadata - @see {@link AgentMetadata}\n * @param agentApi - @see {@link AgentAPIAttributes}\n * @param paymentPlans - the list of payment plans giving access to the agent.\n *\n * @example\n * ```\n * const agentMetadata = { name: 'My AI Payments Agent', tags: ['test'] }\n * const agentApi = { endpoints: [{ 'POST': 'https://example.com/api/v1/agents/:agentId/tasks' }] }\n * const paymentPlans = [planId]\n *\n * const { agentId } = await payments.agents.registerAgent(agentMetadata, agentApi, paymentPlans)\n * ```\n *\n * @returns The unique identifier of the newly created agent (Agent Id).\n */\n public async registerAgent(\n agentMetadata: AgentMetadata,\n agentApi: AgentAPIAttributes,\n paymentPlans: string[],\n publicationOptions?: PublicationOptions,\n ): Promise<{ agentId: string }> {\n const body = {\n metadataAttributes: agentMetadata,\n agentApiAttributes: agentApi,\n plans: paymentPlans,\n }\n\n const options = this.getBackendHTTPOptions(\n 'POST',\n body,\n resolvePublicationHeaders(publicationOptions),\n )\n const url = new URL(API_URL_REGISTER_AGENT, this.environment.backend)\n\n const response = await fetch(url, options)\n if (!response.ok) {\n throw PaymentsError.fromBackend('Unable to register agent', await safeParseJson(response))\n }\n const agentData = await response.json()\n return { agentId: agentData.data.agentId }\n }\n\n /**\n *\n * It registers a new AI Agent and a Payment Plan associated to this new agent.\n * Depending on the Payment Plan and the configuration of the agent, the usage of the agent/service will consume credits.\n * When the plan expires (because the time is over or the credits are consumed), the user needs to renew the plan to continue using the agent.\n *\n * @remarks This method is oriented to AI Builders\n * @remarks To call this method, the NVM API Key must have publication permissions\n *\n * @see https://nevermined.ai/docs/tutorials/builders/register-agent\n *\n * @param agentMetadata - @see {@link AgentMetadata}\n * @param agentApi - @see {@link AgentAPIAttributes}\n * @param planMetadata - @see {@link PlanMetadata}\n * @param priceConfig - @see {@link PlanPriceConfig}\n * @param creditsConfig - @see {@link PlanCreditsConfig}\n *\n * @example\n * ```\n * const agentMetadata = { name: 'My AI Payments Agent', tags: ['test'] }\n * const agentApi { endpoints: [{ 'POST': 'https://example.com/api/v1/agents/:agentId/tasks' }] }\n * const cryptoPriceConfig = getNativeTokenPriceConfig(100n, builderAddress)\n * const 1dayDurationPlan = getExpirableDurationConfig(ONE_DAY_DURATION)\n * const { agentId, planId } = await payments.agents.registerAgentAndPlan(\n * agentMetadata,\n * agentApi,\n * cryptoPriceConfig,\n * 1dayDurationPlan\n * )\n * ```\n *\n * @returns The unique identifier of the newly created agent (agentId).\n * @returns The unique identifier of the newly created plan (planId).\n */\n public async registerAgentAndPlan(\n agentMetadata: AgentMetadata,\n agentApi: AgentAPIAttributes,\n planMetadata: PlanMetadata,\n priceConfig: PlanPriceConfig,\n creditsConfig: PlanCreditsConfig,\n accessLimit?: 'credits' | 'time',\n publicationOptions?: PublicationOptions,\n ): Promise<{\n agentId: string\n planId: string\n txHash: string\n }> {\n if (accessLimit && !['credits', 'time'].includes(accessLimit)) {\n throw new PaymentsError(\n 'Invalid access limit',\n 'accessLimit must be either \"credits\" or \"time\"',\n )\n }\n if (!accessLimit) {\n accessLimit = creditsConfig.durationSecs > 0n ? 'time' : 'credits'\n }\n const body = {\n plan: {\n metadataAttributes: planMetadata,\n priceConfig: priceConfig,\n creditsConfig: creditsConfig,\n accessLimit,\n },\n agent: {\n metadataAttributes: agentMetadata,\n agentApiAttributes: agentApi,\n },\n }\n const options = this.getBackendHTTPOptions(\n 'POST',\n body,\n resolvePublicationHeaders(publicationOptions),\n )\n const url = new URL(API_URL_REGISTER_AGENTS_AND_PLAN, this.environment.backend)\n\n const response = await fetch(url, options)\n if (!response.ok) {\n throw PaymentsError.fromBackend(\n 'Unable to register agent & plan',\n await safeParseJson(response),\n )\n }\n const result = await response.json()\n return {\n agentId: result.data.agentId,\n planId: result.data.planId,\n txHash: result.txHash,\n }\n }\n\n /**\n * Gets the metadata for a given Agent identifier.\n *\n * @param agentId - The unique identifier of the agent.\n * @returns A promise that resolves to the agent's metadata.\n * @throws PaymentsError if the agent is not found.\n *\n * @example\n * ```\n * const plan = payments.agents.getAgent(agentId)\n * ```\n */\n public async getAgent(agentId: string) {\n const url = new URL(API_URL_GET_AGENT.replace(':agentId', agentId), this.environment.backend)\n const response = await fetch(url, this.getPublicHTTPOptions('GET'))\n if (!response.ok) {\n throw PaymentsError.fromBackend('Agent not found', await safeParseJson(response))\n }\n return response.json()\n }\n\n /**\n * Updates the metadata and API attributes of an existing AI Agent.\n *\n * @param agentId - The unique identifier of the agent.\n * @param agentMetadata - The new metadata attributes for the agent.\n * @param agentApi - The new API attributes for the agent.\n * @returns @see {@link NvmAPIResult} A promise that resolves indicating if the operation was successful.\n * @throws PaymentsError if the agent is not found or if the update fails.\n *\n * @example\n * ```\n * const agentMetadata = { name: 'My Updated Agent', tags: ['test'] }\n * const agentApi = { endpoints: [{ 'POST': 'https://nevermined.app/api/v1/agents/:agentId/tasks' }] }\n *\n * await payments.agents.updateAgentMetadata(agentId, agentMetadata, agentApi)\n * ```\n */\n public async updateAgentMetadata(\n agentId: string,\n agentMetadata: AgentMetadata,\n agentApi: AgentAPIAttributes,\n ): Promise<NvmAPIResult> {\n const body = {\n metadataAttributes: agentMetadata,\n agentApiAttributes: agentApi,\n }\n const url = new URL(API_URL_UPDATE_AGENT.replace(':agentId', agentId), this.environment.backend)\n const options = this.getBackendHTTPOptions('PUT', body)\n const response = await fetch(url, options)\n if (!response.ok) {\n throw PaymentsError.fromBackend('Error updating agent', await safeParseJson(response))\n }\n return response.json()\n }\n\n /**\n * Gets the list of plans that can be ordered to get access to an agent.\n *\n * @param agentId - The unique identifier of the agent.\n * @param pagination - Optional pagination options to control the number of results returned.p\n * @returns A promise that resolves to the list of all different plans giving access to the agent.\n * @throws PaymentsError if the agent is not found.\n *\n * @example\n * ```\n * const result = payments.agents.getAgentPlans(planId)\n * // {\n * // total: 10,\n * // page: 1,\n * // offset: 5,\n * // plans: [ ..]\n * // }\n * ```\n */\n public async getAgentPlans(agentId: string, pagination = new PaginationOptions()) {\n const query =\n API_URL_GET_AGENT_PLANS.replace(':agentId', agentId) + '?' + pagination.asQueryParams()\n const url = new URL(query, this.environment.backend)\n const response = await fetch(url, this.getPublicHTTPOptions('GET'))\n if (!response.ok) {\n throw PaymentsError.fromBackend('Agent not found', await safeParseJson(response))\n }\n return response.json()\n }\n\n /**\n * Adds an existing Payment Plan to an AI Agent.\n * After this operation, users with access to the Payment Plan will be able to access the AI Agent.\n *\n * @remarks\n * Only the owner of the Payment Plan can call this method.\n *\n * @param planId - The unique identifier of the Payment Plan.\n * @param agentId - The unique identifier of the AI Agent.\n * @returns @see {@link NvmAPIResult} A promise that resolves indicating if the operation was successful.\n * @throws PaymentsError if unable to add the plan to the agent.\n *\n * @example\n * ```\n * const result = await payments.agents.addPlanToAgent(planId, agentId)\n * // {\n * // txHash: '0x8d29d5769e832a35e53f80cd4e8890d941c50a09c33dbd975533debc894f2535',\n * // success: true\n * // }\n * ```\n */\n public async addPlanToAgent(planId: string, agentId: string): Promise<NvmAPIResult> {\n const options = this.getBackendHTTPOptions('POST')\n const endpoint = API_URL_ADD_PLAN_AGENT.replace(':planId', planId).replace(':agentId', agentId)\n const url = new URL(endpoint, this.environment.backend)\n const response = await fetch(url, options)\n if (!response.ok) {\n throw PaymentsError.fromBackend('Unable to add plan to agent', await safeParseJson(response))\n }\n\n return response.json()\n }\n\n /**\n * Removes a Payment Plan from an AI Agent.\n * After this operation, users with access to the Payment Plan will no longer be able to access the AI Agent.\n *\n * @remarks\n * Only the owner of the Payment Plan can call this method.\n *\n * @param planId - The unique identifier of the Payment Plan.\n * @param agentId - The unique identifier of the AI Agent.\n * @returns @see {@link NvmAPIResult} A promise that resolves indicating if the operation was successful.\n * @throws PaymentsError if unable to remove the plan from the agent.\n *\n * @example\n * ```\n * const result = await payments.agents.removePlanFromAgent(planId, agentId)\n * // {\n * // txHash: '0x8d29d5769e832a35e53f80cd4e8890d941c50a09c33dbd975533debc894f2535',\n * // success: true\n * // }\n * ```\n */\n public async removePlanFromAgent(planId: string, agentId: string): Promise<NvmAPIResult> {\n const options = this.getBackendHTTPOptions('DELETE')\n const endpoint = API_URL_REMOVE_PLAN_AGENT.replace(':planId', planId).replace(\n ':agentId',\n agentId,\n )\n const url = new URL(endpoint, this.environment.backend)\n const response = await fetch(url, options)\n if (!response.ok) {\n throw PaymentsError.fromBackend(\n 'Unable to remove plan from agent',\n await safeParseJson(response),\n )\n }\n\n return response.json()\n }\n}\n"]}
@@ -38,6 +38,11 @@ export declare abstract class BasePaymentsAPI {
38
38
  protected environmentName: EnvironmentName;
39
39
  protected returnUrl: string;
40
40
  protected appId?: string;
41
+ /**
42
+ * Backend API version (MAJOR.MINOR) pinned by this instance, set from
43
+ * `options.version`. When unset, every request defaults to
44
+ * {@link LOCKED_API_VERSION}.
45
+ */
41
46
  protected version?: string;
42
47
  protected accountAddress: string;
43
48
  protected heliconeApiKey: string;
@@ -101,10 +106,7 @@ export declare abstract class BasePaymentsAPI {
101
106
  */
102
107
  protected getPublicHTTPOptions(method: string, body?: any): {
103
108
  method: string;
104
- headers: {
105
- Accept: string;
106
- "Content-Type": string;
107
- };
109
+ headers: Record<string, string>;
108
110
  body?: string;
109
111
  };
110
112
  }
@@ -1 +1 @@
1
- {"version":3,"file":"base-payments.d.ts","sourceRoot":"","sources":["../../src/api/base-payments.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAClE,OAAO,EAAE,eAAe,EAAE,eAAe,EAAgB,MAAM,oBAAoB,CAAA;AAEnF;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,qBAAqB,CAAA;AAUvD;;;;GAIG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B;;;;;OAKG;IACH,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB,CAAA;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,CAAC,EAAE,kBAAkB,GAC3B,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAKpC;AAED;;;GAGG;AACH,8BAAsB,eAAe;IACnC,SAAS,CAAC,SAAS,EAAE,MAAM,CAAA;IAC3B,SAAS,CAAC,MAAM,EAAE,aAAa,CAAA;IAC/B,SAAS,CAAC,WAAW,EAAE,eAAe,CAAA;IACtC,SAAS,CAAC,eAAe,EAAE,eAAe,CAAA;IAC1C,SAAS,CAAC,SAAS,EAAE,MAAM,CAAA;IAC3B,SAAS,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;IACxB,SAAS,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;IAC1B,SAAS,CAAC,cAAc,EAAE,MAAM,CAAA;IAChC,SAAS,CAAC,cAAc,EAAE,MAAM,CAAA;IAChC,SAAS,CAAC,qBAAqB,EAAE,MAAM,GAAG,IAAI,CAAA;IACvC,iBAAiB,UAAO;gBAEnB,OAAO,EAAE,cAAc;IA0BnC;;;OAGG;IACH,SAAS,CAAC,cAAc,IAAI;QAAE,cAAc,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,CAAA;KAAE;IAc9E;;;OAGG;IACI,kBAAkB,IAAI,eAAe;IAI5C;;;OAGG;IACI,iBAAiB,IAAI,MAAM,GAAG,SAAS;IAI9C;;;;;;OAMG;IACI,iBAAiB,IAAI,MAAM,GAAG,IAAI;IAIzC;;;;;;;OAOG;IACI,iBAAiB,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAI7D;;;;;;;;;OASG;IACH,SAAS,CAAC,qBAAqB,CAC7B,MAAM,EAAE,MAAM,EACd,IAAI,CAAC,EAAE,GAAG,EACV,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IA2BvC;;;;;;;;OAQG;IACH,SAAS,CAAC,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG;gBAE7C,MAAM;iBACL;YACP,MAAM,EAAE,MAAM,CAAA;YACd,cAAc,EAAE,MAAM,CAAA;SACvB;eACM,MAAM;;CAelB"}
1
+ {"version":3,"file":"base-payments.d.ts","sourceRoot":"","sources":["../../src/api/base-payments.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAClE,OAAO,EAAE,eAAe,EAAE,eAAe,EAAgB,MAAM,oBAAoB,CAAA;AAEnF;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,qBAAqB,CAAA;AAUvD;;;;GAIG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B;;;;;OAKG;IACH,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB,CAAA;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,CAAC,EAAE,kBAAkB,GAC3B,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAKpC;AAED;;;GAGG;AACH,8BAAsB,eAAe;IACnC,SAAS,CAAC,SAAS,EAAE,MAAM,CAAA;IAC3B,SAAS,CAAC,MAAM,EAAE,aAAa,CAAA;IAC/B,SAAS,CAAC,WAAW,EAAE,eAAe,CAAA;IACtC,SAAS,CAAC,eAAe,EAAE,eAAe,CAAA;IAC1C,SAAS,CAAC,SAAS,EAAE,MAAM,CAAA;IAC3B,SAAS,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;IACxB;;;;OAIG;IACH,SAAS,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;IAC1B,SAAS,CAAC,cAAc,EAAE,MAAM,CAAA;IAChC,SAAS,CAAC,cAAc,EAAE,MAAM,CAAA;IAChC,SAAS,CAAC,qBAAqB,EAAE,MAAM,GAAG,IAAI,CAAA;IACvC,iBAAiB,UAAO;gBAEnB,OAAO,EAAE,cAAc;IAmCnC;;;OAGG;IACH,SAAS,CAAC,cAAc,IAAI;QAAE,cAAc,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,CAAA;KAAE;IAc9E;;;OAGG;IACI,kBAAkB,IAAI,eAAe;IAI5C;;;OAGG;IACI,iBAAiB,IAAI,MAAM,GAAG,SAAS;IAI9C;;;;;;OAMG;IACI,iBAAiB,IAAI,MAAM,GAAG,IAAI;IAIzC;;;;;;;OAOG;IACI,iBAAiB,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAI7D;;;;;;;;;OASG;IACH,SAAS,CAAC,qBAAqB,CAC7B,MAAM,EAAE,MAAM,EACd,IAAI,CAAC,EAAE,GAAG,EACV,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IA4BvC;;;;;;;;OAQG;IACH,SAAS,CAAC,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG;gBAE7C,MAAM;iBACL,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;eACxB,MAAM;;CAgBlB"}
@@ -1,4 +1,5 @@
1
1
  import { decodeJwt } from 'jose';
2
+ import { API_VERSION_HEADER, LOCKED_API_VERSION } from '../common/api-version.js';
2
3
  import { jsonReplacer } from '../common/helper.js';
3
4
  import { PaymentsError } from '../common/payments.error.js';
4
5
  import { Environments } from '../environments.js';
@@ -49,6 +50,13 @@ export class BasePaymentsAPI {
49
50
  this.environment = Environments[options.environment];
50
51
  this.environmentName = options.environment;
51
52
  this.appId = options.appId;
53
+ // `version` is the backend API pin (MAJOR.MINOR) sent verbatim as
54
+ // Nevermined-Version. Fail fast on a malformed value rather than shipping
55
+ // an invalid header (e.g. an SDK package version '1.0.0', 'v1.1', or '')
56
+ // that the backend rejects with 400 on every call.
57
+ if (options.version !== undefined && !/^\d+\.\d+$/.test(options.version)) {
58
+ throw new PaymentsError(`Invalid 'version' option '${options.version}': expected a backend API version as MAJOR.MINOR (e.g. '1.1'). Omit it to use the SDK's default pin.`);
59
+ }
52
60
  this.version = options.version;
53
61
  this.currentOrganizationId = options.organizationId ?? null;
54
62
  const { accountAddress, heliconeApiKey } = this.parseNvmApiKey();
@@ -123,6 +131,7 @@ export class BasePaymentsAPI {
123
131
  Accept: 'application/json',
124
132
  'Content-Type': 'application/json',
125
133
  Authorization: `Bearer ${this.nvmApiKey}`,
134
+ [API_VERSION_HEADER]: this.version ?? LOCKED_API_VERSION,
126
135
  };
127
136
  if (this.currentOrganizationId) {
128
137
  headers[CURRENT_ORG_ID_HEADER] = this.currentOrganizationId;
@@ -158,6 +167,7 @@ export class BasePaymentsAPI {
158
167
  headers: {
159
168
  Accept: 'application/json',
160
169
  'Content-Type': 'application/json',
170
+ [API_VERSION_HEADER]: this.version ?? LOCKED_API_VERSION,
161
171
  },
162
172
  };
163
173
  if (body) {