@nevermined-io/payments 1.4.1 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/README.md +121 -93
  2. package/dist/api/agents-api.d.ts.map +1 -1
  3. package/dist/api/agents-api.js +8 -7
  4. package/dist/api/agents-api.js.map +1 -1
  5. package/dist/api/plans-api.d.ts +5 -1
  6. package/dist/api/plans-api.d.ts.map +1 -1
  7. package/dist/api/plans-api.js +14 -9
  8. package/dist/api/plans-api.js.map +1 -1
  9. package/dist/api/requests-api.d.ts.map +1 -1
  10. package/dist/api/requests-api.js +4 -3
  11. package/dist/api/requests-api.js.map +1 -1
  12. package/dist/common/helper.d.ts +11 -0
  13. package/dist/common/helper.d.ts.map +1 -1
  14. package/dist/common/helper.js +32 -0
  15. package/dist/common/helper.js.map +1 -1
  16. package/dist/environments.d.ts +8 -0
  17. package/dist/environments.d.ts.map +1 -1
  18. package/dist/environments.js +10 -0
  19. package/dist/environments.js.map +1 -1
  20. package/dist/plans.d.ts +24 -0
  21. package/dist/plans.d.ts.map +1 -1
  22. package/dist/plans.js +24 -0
  23. package/dist/plans.js.map +1 -1
  24. package/dist/x402/delegation-api.d.ts +9 -0
  25. package/dist/x402/delegation-api.d.ts.map +1 -1
  26. package/dist/x402/delegation-api.js +4 -0
  27. package/dist/x402/delegation-api.js.map +1 -1
  28. package/dist/x402/express/middleware.d.ts.map +1 -1
  29. package/dist/x402/express/middleware.js +48 -25
  30. package/dist/x402/express/middleware.js.map +1 -1
  31. package/dist/x402/facilitator-api.d.ts.map +1 -1
  32. package/dist/x402/facilitator-api.js +10 -2
  33. package/dist/x402/facilitator-api.js.map +1 -1
  34. package/dist/x402/langchain/agent.d.ts +96 -0
  35. package/dist/x402/langchain/agent.d.ts.map +1 -0
  36. package/dist/x402/langchain/agent.js +121 -0
  37. package/dist/x402/langchain/agent.js.map +1 -0
  38. package/dist/x402/langchain/decorator.d.ts +43 -4
  39. package/dist/x402/langchain/decorator.d.ts.map +1 -1
  40. package/dist/x402/langchain/decorator.js +173 -6
  41. package/dist/x402/langchain/decorator.js.map +1 -1
  42. package/dist/x402/langchain/index.d.ts +2 -1
  43. package/dist/x402/langchain/index.d.ts.map +1 -1
  44. package/dist/x402/langchain/index.js +2 -1
  45. package/dist/x402/langchain/index.js.map +1 -1
  46. package/dist/x402/langsmith/index.d.ts +15 -0
  47. package/dist/x402/langsmith/index.d.ts.map +1 -0
  48. package/dist/x402/langsmith/index.js +15 -0
  49. package/dist/x402/langsmith/index.js.map +1 -0
  50. package/dist/x402/langsmith/spans.d.ts +163 -0
  51. package/dist/x402/langsmith/spans.d.ts.map +1 -0
  52. package/dist/x402/langsmith/spans.js +341 -0
  53. package/dist/x402/langsmith/spans.js.map +1 -0
  54. package/package.json +16 -2
@@ -1,3 +1,4 @@
1
+ import { safeParseJson } from '../common/helper.js';
1
2
  import { PaymentsError } from '../common/payments.error.js';
2
3
  import { Currency, EURC_TOKEN_ADDRESS, PaginationOptions, } from '../common/types.js';
3
4
  import { ZeroAddress } from '../environments.js';
@@ -18,7 +19,11 @@ export class PlansAPI extends BasePaymentsAPI {
18
19
  /**
19
20
  * Builds a Fiat price configuration for a plan.
20
21
  *
21
- * @param amount - Amount to charge in minor units (e.g., cents) as bigint.
22
+ * `amount` is in **6-decimal units** (USDC convention, NOT cents). To
23
+ * charge $2.00, pass `2_000_000n`. Minimum is `1_000_000n` ($1.00) —
24
+ * lower values are rejected server-side with `BCK.PROTOCOL.0047`.
25
+ *
26
+ * @param amount - Amount to charge in 6-decimal units (e.g. `2_000_000n` for $2.00) as bigint.
22
27
  * @param receiver - Wallet address that will receive the payment.
23
28
  * @param currency - Fiat currency code (default: 'USD'). Any ISO 4217 code accepted by Stripe.
24
29
  * @returns The PlanPriceConfig representing a fiat price.
@@ -373,7 +378,7 @@ export class PlansAPI extends BasePaymentsAPI {
373
378
  const url = new URL(query, this.environment.backend);
374
379
  const response = await fetch(url);
375
380
  if (!response.ok) {
376
- throw PaymentsError.fromBackend('Plan not found', await response.json());
381
+ throw PaymentsError.fromBackend('Plan not found', await safeParseJson(response));
377
382
  }
378
383
  return response.json();
379
384
  }
@@ -394,7 +399,7 @@ export class PlansAPI extends BasePaymentsAPI {
394
399
  const options = this.getBackendHTTPOptions('GET');
395
400
  const response = await fetch(url, options);
396
401
  if (!response.ok) {
397
- throw PaymentsError.fromBackend('Unable to get plans', await response.json());
402
+ throw PaymentsError.fromBackend('Unable to get plans', await safeParseJson(response));
398
403
  }
399
404
  const data = await response.json();
400
405
  return data;
@@ -424,7 +429,7 @@ export class PlansAPI extends BasePaymentsAPI {
424
429
  const url = new URL(query, this.environment.backend);
425
430
  const response = await fetch(url);
426
431
  if (!response.ok) {
427
- throw PaymentsError.fromBackend('Plan not found', await response.json());
432
+ throw PaymentsError.fromBackend('Plan not found', await safeParseJson(response));
428
433
  }
429
434
  return response.json();
430
435
  }
@@ -467,7 +472,7 @@ export class PlansAPI extends BasePaymentsAPI {
467
472
  const url = new URL(balanceUrl, this.environment.backend);
468
473
  const response = await fetch(url, options);
469
474
  if (!response.ok) {
470
- throw PaymentsError.fromBackend('Unable to get balance', await response.json());
475
+ throw PaymentsError.fromBackend('Unable to get balance', await safeParseJson(response));
471
476
  }
472
477
  return response.json();
473
478
  }
@@ -495,7 +500,7 @@ export class PlansAPI extends BasePaymentsAPI {
495
500
  const url = new URL(API_URL_ORDER_PLAN.replace(':planId', planId), this.environment.backend);
496
501
  const response = await fetch(url, options);
497
502
  if (!response.ok) {
498
- throw PaymentsError.fromBackend('Unable to order plan', await response.json());
503
+ throw PaymentsError.fromBackend('Unable to order plan', await safeParseJson(response));
499
504
  }
500
505
  return response.json();
501
506
  }
@@ -525,7 +530,7 @@ export class PlansAPI extends BasePaymentsAPI {
525
530
  const url = new URL(API_URL_STRIPE_CHECKOUT, this.environment.backend);
526
531
  const response = await fetch(url, options);
527
532
  if (!response.ok) {
528
- throw PaymentsError.fromBackend('Unable to order fiat plan', await response.json());
533
+ throw PaymentsError.fromBackend('Unable to order fiat plan', await safeParseJson(response));
529
534
  }
530
535
  return response.json();
531
536
  }
@@ -556,7 +561,7 @@ export class PlansAPI extends BasePaymentsAPI {
556
561
  const url = new URL(API_URL_MINT_PLAN, this.environment.backend);
557
562
  const response = await fetch(url, options);
558
563
  if (!response.ok) {
559
- throw PaymentsError.fromBackend('Unable to mint plan credits', await response.json());
564
+ throw PaymentsError.fromBackend('Unable to mint plan credits', await safeParseJson(response));
560
565
  }
561
566
  return response.json();
562
567
  }
@@ -593,7 +598,7 @@ export class PlansAPI extends BasePaymentsAPI {
593
598
  const url = new URL(API_URL_MINT_EXPIRABLE_PLAN, this.environment.backend);
594
599
  const response = await fetch(url, options);
595
600
  if (!response.ok) {
596
- throw PaymentsError.fromBackend('Unable to mint expirable credits', await response.json());
601
+ throw PaymentsError.fromBackend('Unable to mint expirable credits', await safeParseJson(response));
597
602
  }
598
603
  return response.json();
599
604
  }
@@ -1 +1 @@
1
- {"version":3,"file":"plans-api.js","sourceRoot":"","sources":["../../src/api/plans-api.ts"],"names":[],"mappings":"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","sourcesContent":["import { PaymentsError } from '../common/payments.error.js'\nimport {\n Address,\n Currency,\n EURC_TOKEN_ADDRESS,\n NvmAPIResult,\n PaginationOptions,\n PaymentOptions,\n PlanBalance,\n PlanCreditsConfig,\n PlanRedemptionType,\n PlanMetadata,\n PlanPriceConfig,\n StripeCheckoutResult,\n} from '../common/types.js'\nimport { ZeroAddress } from '../environments.js'\nimport { getRandomBigInt, isEthereumAddress } from '../utils.js'\nimport { BasePaymentsAPI, PublicationOptions, resolvePublicationHeaders } from './base-payments.js'\nimport * as Plans from '../plans.js'\nimport { ContractsAPI } from './contracts-api.js'\nimport {\n API_URL_GET_PLAN,\n API_URL_GET_PLAN_AGENTS,\n API_URL_MINT_EXPIRABLE_PLAN,\n API_URL_MINT_PLAN,\n API_URL_ORDER_PLAN,\n API_URL_PLAN_BALANCE,\n API_URL_REGISTER_PLAN,\n API_URL_STRIPE_CHECKOUT,\n API_URL_GET_PLANS,\n} from './nvm-api.js'\n\n/**\n * The PlansAPI class provides methods to register and interact with payment plans on Nevermined.\n */\nexport class PlansAPI extends BasePaymentsAPI {\n private contractsApi: ContractsAPI\n\n constructor(options: PaymentOptions) {\n super(options)\n this.contractsApi = new ContractsAPI(options)\n }\n /** Price helpers */\n /**\n * Builds a Fiat price configuration for a plan.\n *\n * @param amount - Amount to charge in minor units (e.g., cents) as bigint.\n * @param receiver - Wallet address that will receive the payment.\n * @param currency - Fiat currency code (default: 'USD'). Any ISO 4217 code accepted by Stripe.\n * @returns The PlanPriceConfig representing a fiat price.\n */\n public getFiatPriceConfig(\n amount: bigint,\n receiver: Address,\n currency: Currency | string = Currency.USD,\n ): PlanPriceConfig {\n return Plans.getFiatPriceConfig(amount, receiver, currency)\n }\n\n /**\n * Builds a Pay-As-You-Go price configuration using the template address from the API.\n */\n public async getPayAsYouGoPriceConfig(\n amount: bigint,\n receiver: Address,\n tokenAddress: Address = ZeroAddress,\n ): Promise<PlanPriceConfig> {\n const templateAddress = await this.contractsApi.getPayAsYouGoTemplateAddress()\n return Plans.getPayAsYouGoPriceConfig(amount, receiver, tokenAddress, templateAddress)\n }\n\n /**\n * Builds a Pay-As-You-Go credits configuration.\n */\n public getPayAsYouGoCreditsConfig(): PlanCreditsConfig {\n return Plans.getPayAsYouGoCreditsConfig()\n }\n\n /**\n * Builds a crypto price configuration for a plan.\n *\n * @param amount - Amount to charge in token minor units as bigint.\n * @param receiver - Wallet address that will receive the payment.\n * @param tokenAddress - Optional ERC20 token address. If omitted, native token is assumed.\n * @returns The PlanPriceConfig representing a crypto price.\n */\n public getCryptoPriceConfig(\n amount: bigint,\n receiver: Address,\n tokenAddress?: Address,\n ): PlanPriceConfig {\n return Plans.getCryptoPriceConfig(amount, receiver, tokenAddress)\n }\n\n /**\n * Builds an ERC20 price configuration for a plan.\n *\n * @param amount - Amount to charge in token minor units as bigint.\n * @param tokenAddress - ERC20 token contract address.\n * @param receiver - Wallet address that will receive the payment.\n * @returns The PlanPriceConfig representing an ERC20 price.\n */\n public getERC20PriceConfig(\n amount: bigint,\n tokenAddress: Address,\n receiver: Address,\n ): PlanPriceConfig {\n return Plans.getERC20PriceConfig(amount, tokenAddress, receiver)\n }\n\n /**\n * Builds an EURC (Euro stablecoin) price configuration for a plan.\n *\n * @param amount - Amount to charge in EURC minor units (6 decimals) as bigint.\n * @param receiver - Wallet address that will receive the payment.\n * @param eurcAddress - Optional EURC token address. Defaults to Base Mainnet EURC.\n * @returns The PlanPriceConfig representing an EURC price.\n */\n public getEURCPriceConfig(\n amount: bigint,\n receiver: Address,\n eurcAddress: Address = EURC_TOKEN_ADDRESS,\n ): PlanPriceConfig {\n return Plans.getEURCPriceConfig(amount, receiver, eurcAddress)\n }\n\n /**\n * Builds a FREE price configuration (no payment required).\n * @returns The PlanPriceConfig representing a free plan.\n */\n public getFreePriceConfig(): PlanPriceConfig {\n return Plans.getFreePriceConfig()\n }\n\n /**\n * Builds a native token price configuration for a plan.\n *\n * @param amount - Amount to charge in native token minor units as bigint.\n * @param receiver - Wallet address that will receive the payment.\n * @returns The PlanPriceConfig representing a native token price.\n */\n public getNativeTokenPriceConfig(amount: bigint, receiver: Address): PlanPriceConfig {\n return Plans.getNativeTokenPriceConfig(amount, receiver)\n }\n\n /** Credits helpers */\n /**\n * Builds an EXPIRABLE credits configuration (time-based access).\n *\n * @param durationOfPlan - Duration in seconds.\n * @returns The PlanCreditsConfig representing expirable credits.\n */\n public getExpirableDurationConfig(durationOfPlan: bigint): PlanCreditsConfig {\n return Plans.getExpirableDurationConfig(durationOfPlan)\n }\n\n /**\n * Builds a NON-EXPIRABLE credits configuration (no expiration).\n * @returns The PlanCreditsConfig representing non-expirable credits.\n */\n public getNonExpirableDurationConfig(): PlanCreditsConfig {\n return Plans.getNonExpirableDurationConfig()\n }\n\n /**\n * Builds a FIXED credits configuration.\n *\n * @param creditsGranted - Total credits granted by the plan.\n * @param creditsPerRequest - Credits spent per request (default 1n).\n * @returns The PlanCreditsConfig representing fixed credits.\n */\n public getFixedCreditsConfig(creditsGranted: bigint, creditsPerRequest = 1n): PlanCreditsConfig {\n return Plans.getFixedCreditsConfig(creditsGranted, creditsPerRequest)\n }\n\n /**\n * Builds a DYNAMIC credits configuration (range-limited per request).\n *\n * @param creditsGranted - Total credits granted by the plan.\n * @param minCreditsPerRequest - Minimum credits per request.\n * @param maxCreditsPerRequest - Maximum credits per request.\n * @returns The PlanCreditsConfig representing dynamic credits.\n */\n public getDynamicCreditsConfig(\n creditsGranted: bigint,\n minCreditsPerRequest = 1n,\n maxCreditsPerRequest = 1n,\n ): PlanCreditsConfig {\n return Plans.getDynamicCreditsConfig(creditsGranted, minCreditsPerRequest, maxCreditsPerRequest)\n }\n\n /**\n * Sets the redemption type in a credits configuration.\n *\n * @param creditsConfig - Credits configuration to modify.\n * @param redemptionType - Redemption type to set.\n * @returns The updated PlanCreditsConfig.\n */\n public setRedemptionType(\n creditsConfig: PlanCreditsConfig,\n redemptionType: PlanRedemptionType,\n ): PlanCreditsConfig {\n return Plans.setRedemptionType(creditsConfig, redemptionType)\n }\n\n /**\n * Marks whether burns of these credits are mirrored on-chain.\n *\n * @param creditsConfig - Credits configuration to modify.\n * @param onchainMirror - Whether on-chain mirroring is enabled. Defaults\n * to `true` so calling `setOnchainMirror(config)` enables the mirror;\n * pass `false` explicitly to disable it. The `PlanCreditsConfig`\n * field itself defaults to `false` (set by all credits-config\n * builders) — when `false` the credits ledger lives in the API's\n * Postgres and burns are recorded off-chain only; when `true`, an\n * on-chain audit mirror replays each burn to `NFT1155Credits`.\n * @returns The updated PlanCreditsConfig.\n */\n public setOnchainMirror(\n creditsConfig: PlanCreditsConfig,\n onchainMirror = true,\n ): PlanCreditsConfig {\n return Plans.setOnchainMirror(creditsConfig, onchainMirror)\n }\n /**\n * This method is used to create a singleton instance of the PlansAPI class.\n *\n * @param options - The options to initialize the payments class.\n * @returns The instance of the PlansAPI class.\n */\n static getInstance(options: PaymentOptions): PlansAPI {\n return new PlansAPI(options)\n }\n\n /**\n *\n * It allows to an AI Builder to register a Payment Plan on Nevermined in a flexible manner.\n * A Payment Plan defines 2 main aspects:\n * 1. What a subscriber needs to pay to get the plan (i.e. 100 USDC, 5 USD, etc).\n * 2. What the subscriber gets in return to access the AI agents associated to the plan (i.e. 100 credits, 1 week of usage, etc).\n *\n * With Payment Plans, AI Builders control the usage to their AI Agents.\n *\n * Every time a user accesses an AI Agent to the Payment Plan, the usage consumes from a capped amount of credits (or when the plan duration expires).\n * When the user consumes all the credits, the plan automatically expires and the user needs to top up to continue using the service.\n *\n * @remarks\n * This method is oriented to AI Builders.\n * The NVM API Key must have publication permissions.\n *\n * @see https://nevermined.ai/docs/tutorials/builders/create-plan\n *\n * @param planMetadata - @see {@link PlanMetadata}\n * @param priceConfig - @see {@link PlanPriceConfig}\n * @param creditsConfig - @see {@link PlanCreditsConfig}\n * @param nonce - Optional nonce to prevent replay attacks. Default is a random BigInt.\n * @example\n * ```\n * const cryptoPriceConfig = getNativeTokenPriceConfig(100n, builderAddress)\n * const creditsConfig = getFixedCreditsConfig(100n)\n * const { planId } = await payments.plans.registerPlan({ name: 'AI Assistants Plan'}, cryptoPriceConfig, creditsConfig)\n * ```\n *\n * @returns The unique identifier of the plan (Plan ID) of the newly created plan.\n */\n public async registerPlan(\n planMetadata: PlanMetadata,\n priceConfig: PlanPriceConfig,\n creditsConfig: PlanCreditsConfig,\n nonce = getRandomBigInt(),\n accessLimit?: 'credits' | 'time',\n publicationOptions?: PublicationOptions,\n ): Promise<{ planId: string }> {\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 = BigInt(creditsConfig.durationSecs) > 0n ? 'time' : 'credits'\n }\n const body = {\n metadataAttributes: planMetadata,\n priceConfig,\n creditsConfig,\n nonce,\n isTrialPlan: planMetadata.isTrialPlan || false,\n accessLimit,\n ...(priceConfig.currency && { currency: priceConfig.currency }),\n }\n const options = this.getBackendHTTPOptions(\n 'POST',\n body,\n resolvePublicationHeaders(publicationOptions),\n )\n const url = new URL(API_URL_REGISTER_PLAN, this.environment.backend)\n\n const response = await fetch(url, options)\n if (!response.ok) {\n throw Error(`${response.statusText} - ${await response.text()}`)\n }\n\n return response.json()\n }\n\n /**\n *\n * It allows to an AI Builder to create a Payment Plan on Nevermined based on Credits.\n * A Nevermined Credits Plan limits the access by the access/usage of the Plan.\n * With them, AI Builders control the number of requests that can be made to an agent or service.\n * Every time a user accesses any resouce associated to the Payment Plan, the usage consumes from a capped amount of credits.\n * When the user consumes all the credits, the plan automatically expires and the user needs to top up to continue using the service.\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/create-plan\n *\n * @param planMetadata - @see {@link PlanMetadata}\n * @param priceConfig - @see {@link PlanPriceConfig}\n * @param creditsConfig - @see {@link PlanCreditsConfig}\n *\n * @example\n * ```\n * const cryptoPriceConfig = getNativeTokenPriceConfig(100n, builderAddress)\n * const creditsConfig = getFixedCreditsConfig(100n)\n * const { planId } = await payments.plans.registerCreditsPlan(\n * { name: 'AI Credits Plan'},\n * cryptoPriceConfig,\n * creditsConfig\n * )\n * ```\n *\n * @returns The unique identifier of the plan (Plan ID) of the newly created plan.\n */\n public async registerCreditsPlan(\n planMetadata: PlanMetadata,\n priceConfig: PlanPriceConfig,\n creditsConfig: PlanCreditsConfig,\n publicationOptions?: PublicationOptions,\n ): Promise<{ planId: string }> {\n // Credits plans must have durationSecs = 0 (non-expirable) and either fixed or dynamic redemption\n if (BigInt(creditsConfig.durationSecs) !== 0n)\n throw new PaymentsError(\n 'The creditsConfig.durationSecs must be 0 for credits plans (non-expirable)',\n )\n\n if (creditsConfig.minAmount > creditsConfig.maxAmount)\n throw new PaymentsError(\n 'The creditsConfig.minAmount can not be more than creditsConfig.maxAmount',\n )\n\n return this.registerPlan(\n planMetadata,\n priceConfig,\n creditsConfig,\n undefined,\n 'credits',\n publicationOptions,\n )\n }\n\n /**\n *\n * It allows to an AI Builder to create a Payment Plan on Nevermined limited by duration.\n * A Nevermined Credits Plan limits the access by the access/usage of the Plan.\n * With them, AI Builders control the number of requests that can be made to an agent or service.\n * Every time a user accesses any resouce associated to the Payment Plan, the usage consumes from a capped amount of credits.\n * When the user consumes all the credits, the plan automatically expires and the user needs to top up to continue using the service.\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/create-plan\n *\n * @param planMetadata - @see {@link PlanMetadata}\n * @param priceConfig - @see {@link PlanPriceConfig}\n * @param creditsConfig - @see {@link PlanCreditsConfig}\n *\n * @example\n * ```\n * const cryptoPriceConfig = getNativeTokenPriceConfig(100n, builderAddress)\n * const 1dayDurationPlan = getExpirableDurationConfig(ONE_DAY_DURATION)\n * const { planId } = await payments.plans.registerTimePlan(\n * { name: 'Just for today plan'},\n * cryptoPriceConfig,\n * 1dayDurationPlan\n * )\n * ```\n *\n * @returns The unique identifier of the plan (Plan ID) of the newly created plan.\n */\n public async registerTimePlan(\n planMetadata: PlanMetadata,\n priceConfig: PlanPriceConfig,\n creditsConfig: PlanCreditsConfig,\n publicationOptions?: PublicationOptions,\n ): Promise<{ planId: string }> {\n // Time plans must have durationSecs > 0 (expirable) and isRedemptionAmountFixed = false\n if (BigInt(creditsConfig.durationSecs) === 0n)\n throw new PaymentsError(\n 'The creditsConfig.durationSecs must be greater than 0 for time plans (expirable)',\n )\n\n if (creditsConfig.isRedemptionAmountFixed)\n throw new PaymentsError(\n 'The creditsConfig.isRedemptionAmountFixed must be false for time plans',\n )\n\n return this.registerPlan(\n planMetadata,\n priceConfig,\n creditsConfig,\n undefined,\n 'time',\n publicationOptions,\n )\n }\n\n /**\n *\n * It allows to an AI Builder to create a Trial Payment Plan on Nevermined limited by duration.\n * A Nevermined Trial Plan allow subscribers of that plan to test the Agents associated to it.\n * A Trial plan is a plan that only can be purchased once by a user.\n * Trial plans, as regular plans, can be limited by duration (i.e 1 week of usage) or by credits (i.e 100 credits to use the agent).\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/create-plan\n *\n * @param planMetadata - @see {@link PlanMetadata}\n * @param priceConfig - @see {@link PlanPriceConfig}\n * @param creditsConfig - @see {@link PlanCreditsConfig}\n *\n * @example\n * ```\n * const freePriceConfig = getFreePriceConfig()\n * const 1dayDurationPlan = getExpirableDurationConfig(ONE_DAY_DURATION)\n * const { planId } = await payments.plans.registerCreditsTrialPlan(\n * {name: 'Trial plan'},\n * freePriceConfig,\n * 1dayDurationPlan\n * )\n * ```\n *\n * @returns The unique identifier of the plan (Plan ID) of the newly created plan.\n */\n public async registerCreditsTrialPlan(\n planMetadata: PlanMetadata,\n priceConfig: PlanPriceConfig,\n creditsConfig: PlanCreditsConfig,\n publicationOptions?: PublicationOptions,\n ): Promise<{ planId: string }> {\n planMetadata.isTrialPlan = true\n return this.registerCreditsPlan(planMetadata, priceConfig, creditsConfig, publicationOptions)\n }\n\n /**\n *\n * It allows to an AI Builder to create a Trial Payment Plan on Nevermined limited by duration.\n * A Nevermined Trial Plan allow subscribers of that plan to test the Agents associated to it.\n * A Trial plan is a plan that only can be purchased once by a user.\n * Trial plans, as regular plans, can be limited by duration (i.e 1 week of usage) or by credits (i.e 100 credits to use the agent).\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/create-plan\n *\n * @param planMetadata - @see {@link PlanMetadata}\n * @param priceConfig - @see {@link PlanPriceConfig}\n * @param creditsConfig - @see {@link PlanCreditsConfig}\n *\n * @example\n * ```\n * const freePriceConfig = getFreePriceConfig()\n * const 1dayDurationPlan = getExpirableDurationConfig(ONE_DAY_DURATION)\n * const { planId } = await payments.plans.registerTimeTrialPlan(\n * {name: '1 day Trial plan'},\n * freePriceConfig,\n * 1dayDurationPlan\n * )\n * ```\n *\n * @returns The unique identifier of the plan (Plan ID) of the newly created plan.\n */\n public async registerTimeTrialPlan(\n planMetadata: PlanMetadata,\n priceConfig: PlanPriceConfig,\n creditsConfig: PlanCreditsConfig,\n publicationOptions?: PublicationOptions,\n ): Promise<{ planId: string }> {\n planMetadata.isTrialPlan = true\n return this.registerTimePlan(planMetadata, priceConfig, creditsConfig, publicationOptions)\n }\n\n /**\n * Gets the information about a Payment Plan by its identifier.\n *\n * @param planId - The unique identifier of the plan.\n * @returns A promise that resolves to the plan's description.\n * @throws PaymentsError if the plan is not found.\n * @example\n * ```\n * const plan = payments.plans.getPlan(planId)\n * ```\n */\n public async getPlan(planId: string) {\n const query = API_URL_GET_PLAN.replace(':planId', planId)\n const url = new URL(query, this.environment.backend)\n const response = await fetch(url)\n if (!response.ok) {\n throw PaymentsError.fromBackend('Plan not found', await response.json())\n }\n return response.json()\n }\n\n /**\n *\n * @param page - The page number to retrieve.\n * @param offset - The number of items per page.\n * @param sortBy - The field to sort the results by.\n * @param sortOrder - The order in which to sort the results.\n * @returns A promise that resolves to the list of all different plans.\n */\n public async getPlans(page = 1, offset = 100, sortBy = 'created', sortOrder = 'desc') {\n const url = new URL(API_URL_GET_PLANS, this.environment.backend)\n url.searchParams.set('page', page.toString())\n url.searchParams.set('offset', offset.toString())\n url.searchParams.set('sortBy', sortBy)\n url.searchParams.set('sortOrder', sortOrder)\n const options = this.getBackendHTTPOptions('GET')\n const response = await fetch(url, options)\n if (!response.ok) {\n throw PaymentsError.fromBackend('Unable to get plans', await response.json())\n }\n\n const data = await response.json()\n return data\n }\n\n /**\n * Gets the list of Agents that have associated a specific Payment Plan.\n * All the agents returned can be accessed by the users that are subscribed to the Payment Plan.\n *\n * @param planId - The unique identifier of the plan.\n * @param pagination - Optional pagination options to control the number of results returned.\n * @returns A promise that resolves to the list of agents associated with the plan.\n * @throws PaymentsError if the plan is not found.\n *\n * @example\n * ```\n * const result = payments.plans.getAgentsAssociatedToAPlan(planId)\n * // {\n * // total: 10,\n * // page: 1,\n * // offset: 5,\n * // agents: [ ..]\n * // }\n * ```\n */\n public async getAgentsAssociatedToAPlan(planId: string, pagination = new PaginationOptions()) {\n const query =\n API_URL_GET_PLAN_AGENTS.replace(':planId', planId) + '?' + 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('Plan not found', await response.json())\n }\n return response.json()\n }\n\n /**\n * Gets the balance of an account for a Payment Plan.\n *\n * @param planId - The identifier of the Payment Plan.\n * @param accountAddress - The address of the account to get the balance for.\n * @returns @see {@link PlanBalance} A promise that resolves to the balance result.\n * @throws PaymentsError if unable to get the balance.\n *\n * ```\n * const balance = payments.plans.getPlanBalance(planId)\n * // {\n * // planId: '105906633592154016712415751065660953070604027297000423385655551747721326921578',\n * // planType: 'credits',\n * // holderAddress: '0x505384192Ba6a4D4b50EAB846ee67db3b9A93359',\n * // creditsContract: '0xdd0240858fE744C3BF245DD377abBC04d1FDA443',\n * // balance: '100',\n * // isSubscriber: true\n * // }\n * ```\n *\n */\n public async getPlanBalance(planId: string, accountAddress?: Address): Promise<PlanBalance> {\n const holderAddress = isEthereumAddress(accountAddress)\n ? accountAddress\n : this.getAccountAddress()\n\n if (!holderAddress) {\n throw new PaymentsError('Holder address is required')\n }\n\n const balanceUrl = API_URL_PLAN_BALANCE.replace(':planId', planId).replace(\n ':holderAddress',\n holderAddress,\n )\n\n const options = {\n method: 'GET',\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n },\n }\n const url = new URL(balanceUrl, this.environment.backend)\n const response = await fetch(url, options)\n if (!response.ok) {\n throw PaymentsError.fromBackend('Unable to get balance', await response.json())\n }\n\n return response.json()\n }\n\n /**\n * Orders a Payment Plan requiring the payment in crypto. The user must have enough balance in the selected token.\n *\n * @remarks\n * The payment is done using crypto in the token (ERC20 or native) defined in the plan.\n *\n * @param planId - The unique identifier of the plan.\n * @returns @see {@link NvmAPIResult} A promise that resolves indicating if the operation was successful.\n * @throws PaymentsError if unable to order the plan.\n *\n * @example\n * ```\n * const result = await payments.plans.orderPlan(planId)\n * // {\n * // txHash: '0x8d29d5769e832a35e53f80cd4e8890d941c50a09c33dbd975533debc894f2535',\n * // success: true\n * // }\n * ```\n */\n public async orderPlan(planId: string): Promise<NvmAPIResult> {\n const options = this.getBackendHTTPOptions('POST')\n const url = new URL(API_URL_ORDER_PLAN.replace(':planId', planId), this.environment.backend)\n const response = await fetch(url, options)\n if (!response.ok) {\n throw PaymentsError.fromBackend('Unable to order plan', await response.json())\n }\n\n return response.json()\n }\n\n /**\n * Initiates the purchase of a Plan requiring the payment in Fiat. This method will return a URL where the user can complete the payment.\n *\n * @remarks\n * The payment is completed using a credit card in a external website (Stripe).\n * @remarks\n * This method is only valid for plans with price in Fiat.\n *\n * @param planId - The unique identifier of the plan.\n * @returns A promise that resolves indicating the URL to complete the payment.\n * @throws PaymentsError if unable to order the plan.\n *\n * @example\n * ```\n * const result = await payments.plans.orderFiatPlan(planId)\n * ```\n */\n public async orderFiatPlan(planId: string): Promise<{ result: StripeCheckoutResult }> {\n const body = {\n sessionType: 'embedded',\n planId,\n }\n const options = this.getBackendHTTPOptions('POST', body)\n const url = new URL(API_URL_STRIPE_CHECKOUT, this.environment.backend)\n const response = await fetch(url, options)\n if (!response.ok) {\n throw PaymentsError.fromBackend('Unable to order fiat plan', await response.json())\n }\n\n return response.json()\n }\n\n /**\n * Mints credits for a given Payment Plan and transfers them to a receiver.\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 creditsAmount - The number of credits to mint.\n * @param creditsReceiver - The address of the receiver.\n * @returns @see {@link NvmAPIResult} A promise that resolves to the result of the operation.\n * @throws PaymentsError if unable to mint credits.\n *\n * @example\n * ```\n * const result = await payments.plans.mintPlanCredits(planId, 5n, '0x505384192Ba6a4D4b50EAB846ee67db3b9A93359')\n * // {\n * // txHash: '0x8d29d5769e832a35e53f80cd4e8890d941c50a09c33dbd975533debc894f2535',\n * // success: true\n * // }\n * ```\n */\n public async mintPlanCredits(\n planId: string,\n creditsAmount: bigint,\n creditsReceiver: Address,\n ): Promise<NvmAPIResult> {\n const body = { planId, amount: creditsAmount, creditsReceiver }\n const options = this.getBackendHTTPOptions('POST', body)\n const url = new URL(API_URL_MINT_PLAN, this.environment.backend)\n const response = await fetch(url, options)\n if (!response.ok) {\n throw PaymentsError.fromBackend('Unable to mint plan credits', await response.json())\n }\n\n return response.json()\n }\n\n /**\n * Mints expirable credits for a given Payment Plan and transfers them to a receiver.\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 creditsAmount - The number of credits to mint.\n * @param creditsReceiver - The address of the receiver.\n * @param creditsDuration - The duration of the credits in seconds. Default is 0 (no expiration).\n * @returns @see {@link NvmAPIResult} A promise that resolves to the result of the operation.\n * @throws PaymentsError if unable to mint expirable credits.\n *\n * @example\n * ```\n * const result = await payments.plans.mintPlanExpirable(\n * planId,\n * 1n,\n * '0x505384192Ba6a4D4b50EAB846ee67db3b9A93359',\n * 86_400n // 1 day in seconds\n * )\n * // {\n * // txHash: '0x8d29d5769e832a35e53f80cd4e8890d941c50a09c33dbd975533debc894f2535',\n * // success: true\n * // }\n * ```\n */\n public async mintPlanExpirable(\n planId: string,\n creditsAmount: bigint,\n creditsReceiver: Address,\n creditsDuration = 0n,\n ): Promise<NvmAPIResult> {\n const body = { planId, creditsAmount, creditsReceiver, creditsDuration }\n const options = this.getBackendHTTPOptions('POST', body)\n const url = new URL(API_URL_MINT_EXPIRABLE_PLAN, this.environment.backend)\n const response = await fetch(url, options)\n if (!response.ok) {\n throw PaymentsError.fromBackend('Unable to mint expirable credits', await response.json())\n }\n\n return response.json()\n }\n}\n"]}
1
+ {"version":3,"file":"plans-api.js","sourceRoot":"","sources":["../../src/api/plans-api.ts"],"names":[],"mappings":"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","sourcesContent":["import { safeParseJson } from '../common/helper.js'\nimport { PaymentsError } from '../common/payments.error.js'\nimport {\n Address,\n Currency,\n EURC_TOKEN_ADDRESS,\n NvmAPIResult,\n PaginationOptions,\n PaymentOptions,\n PlanBalance,\n PlanCreditsConfig,\n PlanRedemptionType,\n PlanMetadata,\n PlanPriceConfig,\n StripeCheckoutResult,\n} from '../common/types.js'\nimport { ZeroAddress } from '../environments.js'\nimport { getRandomBigInt, isEthereumAddress } from '../utils.js'\nimport { BasePaymentsAPI, PublicationOptions, resolvePublicationHeaders } from './base-payments.js'\nimport * as Plans from '../plans.js'\nimport { ContractsAPI } from './contracts-api.js'\nimport {\n API_URL_GET_PLAN,\n API_URL_GET_PLAN_AGENTS,\n API_URL_MINT_EXPIRABLE_PLAN,\n API_URL_MINT_PLAN,\n API_URL_ORDER_PLAN,\n API_URL_PLAN_BALANCE,\n API_URL_REGISTER_PLAN,\n API_URL_STRIPE_CHECKOUT,\n API_URL_GET_PLANS,\n} from './nvm-api.js'\n\n/**\n * The PlansAPI class provides methods to register and interact with payment plans on Nevermined.\n */\nexport class PlansAPI extends BasePaymentsAPI {\n private contractsApi: ContractsAPI\n\n constructor(options: PaymentOptions) {\n super(options)\n this.contractsApi = new ContractsAPI(options)\n }\n /** Price helpers */\n /**\n * Builds a Fiat price configuration for a plan.\n *\n * `amount` is in **6-decimal units** (USDC convention, NOT cents). To\n * charge $2.00, pass `2_000_000n`. Minimum is `1_000_000n` ($1.00) —\n * lower values are rejected server-side with `BCK.PROTOCOL.0047`.\n *\n * @param amount - Amount to charge in 6-decimal units (e.g. `2_000_000n` for $2.00) as bigint.\n * @param receiver - Wallet address that will receive the payment.\n * @param currency - Fiat currency code (default: 'USD'). Any ISO 4217 code accepted by Stripe.\n * @returns The PlanPriceConfig representing a fiat price.\n */\n public getFiatPriceConfig(\n amount: bigint,\n receiver: Address,\n currency: Currency | string = Currency.USD,\n ): PlanPriceConfig {\n return Plans.getFiatPriceConfig(amount, receiver, currency)\n }\n\n /**\n * Builds a Pay-As-You-Go price configuration using the template address from the API.\n */\n public async getPayAsYouGoPriceConfig(\n amount: bigint,\n receiver: Address,\n tokenAddress: Address = ZeroAddress,\n ): Promise<PlanPriceConfig> {\n const templateAddress = await this.contractsApi.getPayAsYouGoTemplateAddress()\n return Plans.getPayAsYouGoPriceConfig(amount, receiver, tokenAddress, templateAddress)\n }\n\n /**\n * Builds a Pay-As-You-Go credits configuration.\n */\n public getPayAsYouGoCreditsConfig(): PlanCreditsConfig {\n return Plans.getPayAsYouGoCreditsConfig()\n }\n\n /**\n * Builds a crypto price configuration for a plan.\n *\n * @param amount - Amount to charge in token minor units as bigint.\n * @param receiver - Wallet address that will receive the payment.\n * @param tokenAddress - Optional ERC20 token address. If omitted, native token is assumed.\n * @returns The PlanPriceConfig representing a crypto price.\n */\n public getCryptoPriceConfig(\n amount: bigint,\n receiver: Address,\n tokenAddress?: Address,\n ): PlanPriceConfig {\n return Plans.getCryptoPriceConfig(amount, receiver, tokenAddress)\n }\n\n /**\n * Builds an ERC20 price configuration for a plan.\n *\n * @param amount - Amount to charge in token minor units as bigint.\n * @param tokenAddress - ERC20 token contract address.\n * @param receiver - Wallet address that will receive the payment.\n * @returns The PlanPriceConfig representing an ERC20 price.\n */\n public getERC20PriceConfig(\n amount: bigint,\n tokenAddress: Address,\n receiver: Address,\n ): PlanPriceConfig {\n return Plans.getERC20PriceConfig(amount, tokenAddress, receiver)\n }\n\n /**\n * Builds an EURC (Euro stablecoin) price configuration for a plan.\n *\n * @param amount - Amount to charge in EURC minor units (6 decimals) as bigint.\n * @param receiver - Wallet address that will receive the payment.\n * @param eurcAddress - Optional EURC token address. Defaults to Base Mainnet EURC.\n * @returns The PlanPriceConfig representing an EURC price.\n */\n public getEURCPriceConfig(\n amount: bigint,\n receiver: Address,\n eurcAddress: Address = EURC_TOKEN_ADDRESS,\n ): PlanPriceConfig {\n return Plans.getEURCPriceConfig(amount, receiver, eurcAddress)\n }\n\n /**\n * Builds a FREE price configuration (no payment required).\n * @returns The PlanPriceConfig representing a free plan.\n */\n public getFreePriceConfig(): PlanPriceConfig {\n return Plans.getFreePriceConfig()\n }\n\n /**\n * Builds a native token price configuration for a plan.\n *\n * @param amount - Amount to charge in native token minor units as bigint.\n * @param receiver - Wallet address that will receive the payment.\n * @returns The PlanPriceConfig representing a native token price.\n */\n public getNativeTokenPriceConfig(amount: bigint, receiver: Address): PlanPriceConfig {\n return Plans.getNativeTokenPriceConfig(amount, receiver)\n }\n\n /** Credits helpers */\n /**\n * Builds an EXPIRABLE credits configuration (time-based access).\n *\n * @param durationOfPlan - Duration in seconds.\n * @returns The PlanCreditsConfig representing expirable credits.\n */\n public getExpirableDurationConfig(durationOfPlan: bigint): PlanCreditsConfig {\n return Plans.getExpirableDurationConfig(durationOfPlan)\n }\n\n /**\n * Builds a NON-EXPIRABLE credits configuration (no expiration).\n * @returns The PlanCreditsConfig representing non-expirable credits.\n */\n public getNonExpirableDurationConfig(): PlanCreditsConfig {\n return Plans.getNonExpirableDurationConfig()\n }\n\n /**\n * Builds a FIXED credits configuration.\n *\n * @param creditsGranted - Total credits granted by the plan.\n * @param creditsPerRequest - Credits spent per request (default 1n).\n * @returns The PlanCreditsConfig representing fixed credits.\n */\n public getFixedCreditsConfig(creditsGranted: bigint, creditsPerRequest = 1n): PlanCreditsConfig {\n return Plans.getFixedCreditsConfig(creditsGranted, creditsPerRequest)\n }\n\n /**\n * Builds a DYNAMIC credits configuration (range-limited per request).\n *\n * @param creditsGranted - Total credits granted by the plan.\n * @param minCreditsPerRequest - Minimum credits per request.\n * @param maxCreditsPerRequest - Maximum credits per request.\n * @returns The PlanCreditsConfig representing dynamic credits.\n */\n public getDynamicCreditsConfig(\n creditsGranted: bigint,\n minCreditsPerRequest = 1n,\n maxCreditsPerRequest = 1n,\n ): PlanCreditsConfig {\n return Plans.getDynamicCreditsConfig(creditsGranted, minCreditsPerRequest, maxCreditsPerRequest)\n }\n\n /**\n * Sets the redemption type in a credits configuration.\n *\n * @param creditsConfig - Credits configuration to modify.\n * @param redemptionType - Redemption type to set.\n * @returns The updated PlanCreditsConfig.\n */\n public setRedemptionType(\n creditsConfig: PlanCreditsConfig,\n redemptionType: PlanRedemptionType,\n ): PlanCreditsConfig {\n return Plans.setRedemptionType(creditsConfig, redemptionType)\n }\n\n /**\n * Marks whether burns of these credits are mirrored on-chain.\n *\n * @param creditsConfig - Credits configuration to modify.\n * @param onchainMirror - Whether on-chain mirroring is enabled. Defaults\n * to `true` so calling `setOnchainMirror(config)` enables the mirror;\n * pass `false` explicitly to disable it. The `PlanCreditsConfig`\n * field itself defaults to `false` (set by all credits-config\n * builders) — when `false` the credits ledger lives in the API's\n * Postgres and burns are recorded off-chain only; when `true`, an\n * on-chain audit mirror replays each burn to `NFT1155Credits`.\n * @returns The updated PlanCreditsConfig.\n */\n public setOnchainMirror(\n creditsConfig: PlanCreditsConfig,\n onchainMirror = true,\n ): PlanCreditsConfig {\n return Plans.setOnchainMirror(creditsConfig, onchainMirror)\n }\n /**\n * This method is used to create a singleton instance of the PlansAPI class.\n *\n * @param options - The options to initialize the payments class.\n * @returns The instance of the PlansAPI class.\n */\n static getInstance(options: PaymentOptions): PlansAPI {\n return new PlansAPI(options)\n }\n\n /**\n *\n * It allows to an AI Builder to register a Payment Plan on Nevermined in a flexible manner.\n * A Payment Plan defines 2 main aspects:\n * 1. What a subscriber needs to pay to get the plan (i.e. 100 USDC, 5 USD, etc).\n * 2. What the subscriber gets in return to access the AI agents associated to the plan (i.e. 100 credits, 1 week of usage, etc).\n *\n * With Payment Plans, AI Builders control the usage to their AI Agents.\n *\n * Every time a user accesses an AI Agent to the Payment Plan, the usage consumes from a capped amount of credits (or when the plan duration expires).\n * When the user consumes all the credits, the plan automatically expires and the user needs to top up to continue using the service.\n *\n * @remarks\n * This method is oriented to AI Builders.\n * The NVM API Key must have publication permissions.\n *\n * @see https://nevermined.ai/docs/tutorials/builders/create-plan\n *\n * @param planMetadata - @see {@link PlanMetadata}\n * @param priceConfig - @see {@link PlanPriceConfig}\n * @param creditsConfig - @see {@link PlanCreditsConfig}\n * @param nonce - Optional nonce to prevent replay attacks. Default is a random BigInt.\n * @example\n * ```\n * const cryptoPriceConfig = getNativeTokenPriceConfig(100n, builderAddress)\n * const creditsConfig = getFixedCreditsConfig(100n)\n * const { planId } = await payments.plans.registerPlan({ name: 'AI Assistants Plan'}, cryptoPriceConfig, creditsConfig)\n * ```\n *\n * @returns The unique identifier of the plan (Plan ID) of the newly created plan.\n */\n public async registerPlan(\n planMetadata: PlanMetadata,\n priceConfig: PlanPriceConfig,\n creditsConfig: PlanCreditsConfig,\n nonce = getRandomBigInt(),\n accessLimit?: 'credits' | 'time',\n publicationOptions?: PublicationOptions,\n ): Promise<{ planId: string }> {\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 = BigInt(creditsConfig.durationSecs) > 0n ? 'time' : 'credits'\n }\n const body = {\n metadataAttributes: planMetadata,\n priceConfig,\n creditsConfig,\n nonce,\n isTrialPlan: planMetadata.isTrialPlan || false,\n accessLimit,\n ...(priceConfig.currency && { currency: priceConfig.currency }),\n }\n const options = this.getBackendHTTPOptions(\n 'POST',\n body,\n resolvePublicationHeaders(publicationOptions),\n )\n const url = new URL(API_URL_REGISTER_PLAN, this.environment.backend)\n\n const response = await fetch(url, options)\n if (!response.ok) {\n throw Error(`${response.statusText} - ${await response.text()}`)\n }\n\n return response.json()\n }\n\n /**\n *\n * It allows to an AI Builder to create a Payment Plan on Nevermined based on Credits.\n * A Nevermined Credits Plan limits the access by the access/usage of the Plan.\n * With them, AI Builders control the number of requests that can be made to an agent or service.\n * Every time a user accesses any resouce associated to the Payment Plan, the usage consumes from a capped amount of credits.\n * When the user consumes all the credits, the plan automatically expires and the user needs to top up to continue using the service.\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/create-plan\n *\n * @param planMetadata - @see {@link PlanMetadata}\n * @param priceConfig - @see {@link PlanPriceConfig}\n * @param creditsConfig - @see {@link PlanCreditsConfig}\n *\n * @example\n * ```\n * const cryptoPriceConfig = getNativeTokenPriceConfig(100n, builderAddress)\n * const creditsConfig = getFixedCreditsConfig(100n)\n * const { planId } = await payments.plans.registerCreditsPlan(\n * { name: 'AI Credits Plan'},\n * cryptoPriceConfig,\n * creditsConfig\n * )\n * ```\n *\n * @returns The unique identifier of the plan (Plan ID) of the newly created plan.\n */\n public async registerCreditsPlan(\n planMetadata: PlanMetadata,\n priceConfig: PlanPriceConfig,\n creditsConfig: PlanCreditsConfig,\n publicationOptions?: PublicationOptions,\n ): Promise<{ planId: string }> {\n // Credits plans must have durationSecs = 0 (non-expirable) and either fixed or dynamic redemption\n if (BigInt(creditsConfig.durationSecs) !== 0n)\n throw new PaymentsError(\n 'The creditsConfig.durationSecs must be 0 for credits plans (non-expirable)',\n )\n\n if (creditsConfig.minAmount > creditsConfig.maxAmount)\n throw new PaymentsError(\n 'The creditsConfig.minAmount can not be more than creditsConfig.maxAmount',\n )\n\n return this.registerPlan(\n planMetadata,\n priceConfig,\n creditsConfig,\n undefined,\n 'credits',\n publicationOptions,\n )\n }\n\n /**\n *\n * It allows to an AI Builder to create a Payment Plan on Nevermined limited by duration.\n * A Nevermined Credits Plan limits the access by the access/usage of the Plan.\n * With them, AI Builders control the number of requests that can be made to an agent or service.\n * Every time a user accesses any resouce associated to the Payment Plan, the usage consumes from a capped amount of credits.\n * When the user consumes all the credits, the plan automatically expires and the user needs to top up to continue using the service.\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/create-plan\n *\n * @param planMetadata - @see {@link PlanMetadata}\n * @param priceConfig - @see {@link PlanPriceConfig}\n * @param creditsConfig - @see {@link PlanCreditsConfig}\n *\n * @example\n * ```\n * const cryptoPriceConfig = getNativeTokenPriceConfig(100n, builderAddress)\n * const 1dayDurationPlan = getExpirableDurationConfig(ONE_DAY_DURATION)\n * const { planId } = await payments.plans.registerTimePlan(\n * { name: 'Just for today plan'},\n * cryptoPriceConfig,\n * 1dayDurationPlan\n * )\n * ```\n *\n * @returns The unique identifier of the plan (Plan ID) of the newly created plan.\n */\n public async registerTimePlan(\n planMetadata: PlanMetadata,\n priceConfig: PlanPriceConfig,\n creditsConfig: PlanCreditsConfig,\n publicationOptions?: PublicationOptions,\n ): Promise<{ planId: string }> {\n // Time plans must have durationSecs > 0 (expirable) and isRedemptionAmountFixed = false\n if (BigInt(creditsConfig.durationSecs) === 0n)\n throw new PaymentsError(\n 'The creditsConfig.durationSecs must be greater than 0 for time plans (expirable)',\n )\n\n if (creditsConfig.isRedemptionAmountFixed)\n throw new PaymentsError(\n 'The creditsConfig.isRedemptionAmountFixed must be false for time plans',\n )\n\n return this.registerPlan(\n planMetadata,\n priceConfig,\n creditsConfig,\n undefined,\n 'time',\n publicationOptions,\n )\n }\n\n /**\n *\n * It allows to an AI Builder to create a Trial Payment Plan on Nevermined limited by duration.\n * A Nevermined Trial Plan allow subscribers of that plan to test the Agents associated to it.\n * A Trial plan is a plan that only can be purchased once by a user.\n * Trial plans, as regular plans, can be limited by duration (i.e 1 week of usage) or by credits (i.e 100 credits to use the agent).\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/create-plan\n *\n * @param planMetadata - @see {@link PlanMetadata}\n * @param priceConfig - @see {@link PlanPriceConfig}\n * @param creditsConfig - @see {@link PlanCreditsConfig}\n *\n * @example\n * ```\n * const freePriceConfig = getFreePriceConfig()\n * const 1dayDurationPlan = getExpirableDurationConfig(ONE_DAY_DURATION)\n * const { planId } = await payments.plans.registerCreditsTrialPlan(\n * {name: 'Trial plan'},\n * freePriceConfig,\n * 1dayDurationPlan\n * )\n * ```\n *\n * @returns The unique identifier of the plan (Plan ID) of the newly created plan.\n */\n public async registerCreditsTrialPlan(\n planMetadata: PlanMetadata,\n priceConfig: PlanPriceConfig,\n creditsConfig: PlanCreditsConfig,\n publicationOptions?: PublicationOptions,\n ): Promise<{ planId: string }> {\n planMetadata.isTrialPlan = true\n return this.registerCreditsPlan(planMetadata, priceConfig, creditsConfig, publicationOptions)\n }\n\n /**\n *\n * It allows to an AI Builder to create a Trial Payment Plan on Nevermined limited by duration.\n * A Nevermined Trial Plan allow subscribers of that plan to test the Agents associated to it.\n * A Trial plan is a plan that only can be purchased once by a user.\n * Trial plans, as regular plans, can be limited by duration (i.e 1 week of usage) or by credits (i.e 100 credits to use the agent).\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/create-plan\n *\n * @param planMetadata - @see {@link PlanMetadata}\n * @param priceConfig - @see {@link PlanPriceConfig}\n * @param creditsConfig - @see {@link PlanCreditsConfig}\n *\n * @example\n * ```\n * const freePriceConfig = getFreePriceConfig()\n * const 1dayDurationPlan = getExpirableDurationConfig(ONE_DAY_DURATION)\n * const { planId } = await payments.plans.registerTimeTrialPlan(\n * {name: '1 day Trial plan'},\n * freePriceConfig,\n * 1dayDurationPlan\n * )\n * ```\n *\n * @returns The unique identifier of the plan (Plan ID) of the newly created plan.\n */\n public async registerTimeTrialPlan(\n planMetadata: PlanMetadata,\n priceConfig: PlanPriceConfig,\n creditsConfig: PlanCreditsConfig,\n publicationOptions?: PublicationOptions,\n ): Promise<{ planId: string }> {\n planMetadata.isTrialPlan = true\n return this.registerTimePlan(planMetadata, priceConfig, creditsConfig, publicationOptions)\n }\n\n /**\n * Gets the information about a Payment Plan by its identifier.\n *\n * @param planId - The unique identifier of the plan.\n * @returns A promise that resolves to the plan's description.\n * @throws PaymentsError if the plan is not found.\n * @example\n * ```\n * const plan = payments.plans.getPlan(planId)\n * ```\n */\n public async getPlan(planId: string) {\n const query = API_URL_GET_PLAN.replace(':planId', planId)\n const url = new URL(query, this.environment.backend)\n const response = await fetch(url)\n if (!response.ok) {\n throw PaymentsError.fromBackend('Plan not found', await safeParseJson(response))\n }\n return response.json()\n }\n\n /**\n *\n * @param page - The page number to retrieve.\n * @param offset - The number of items per page.\n * @param sortBy - The field to sort the results by.\n * @param sortOrder - The order in which to sort the results.\n * @returns A promise that resolves to the list of all different plans.\n */\n public async getPlans(page = 1, offset = 100, sortBy = 'created', sortOrder = 'desc') {\n const url = new URL(API_URL_GET_PLANS, this.environment.backend)\n url.searchParams.set('page', page.toString())\n url.searchParams.set('offset', offset.toString())\n url.searchParams.set('sortBy', sortBy)\n url.searchParams.set('sortOrder', sortOrder)\n const options = this.getBackendHTTPOptions('GET')\n const response = await fetch(url, options)\n if (!response.ok) {\n throw PaymentsError.fromBackend('Unable to get plans', await safeParseJson(response))\n }\n\n const data = await response.json()\n return data\n }\n\n /**\n * Gets the list of Agents that have associated a specific Payment Plan.\n * All the agents returned can be accessed by the users that are subscribed to the Payment Plan.\n *\n * @param planId - The unique identifier of the plan.\n * @param pagination - Optional pagination options to control the number of results returned.\n * @returns A promise that resolves to the list of agents associated with the plan.\n * @throws PaymentsError if the plan is not found.\n *\n * @example\n * ```\n * const result = payments.plans.getAgentsAssociatedToAPlan(planId)\n * // {\n * // total: 10,\n * // page: 1,\n * // offset: 5,\n * // agents: [ ..]\n * // }\n * ```\n */\n public async getAgentsAssociatedToAPlan(planId: string, pagination = new PaginationOptions()) {\n const query =\n API_URL_GET_PLAN_AGENTS.replace(':planId', planId) + '?' + 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('Plan not found', await safeParseJson(response))\n }\n return response.json()\n }\n\n /**\n * Gets the balance of an account for a Payment Plan.\n *\n * @param planId - The identifier of the Payment Plan.\n * @param accountAddress - The address of the account to get the balance for.\n * @returns @see {@link PlanBalance} A promise that resolves to the balance result.\n * @throws PaymentsError if unable to get the balance.\n *\n * ```\n * const balance = payments.plans.getPlanBalance(planId)\n * // {\n * // planId: '105906633592154016712415751065660953070604027297000423385655551747721326921578',\n * // planType: 'credits',\n * // holderAddress: '0x505384192Ba6a4D4b50EAB846ee67db3b9A93359',\n * // creditsContract: '0xdd0240858fE744C3BF245DD377abBC04d1FDA443',\n * // balance: '100',\n * // isSubscriber: true\n * // }\n * ```\n *\n */\n public async getPlanBalance(planId: string, accountAddress?: Address): Promise<PlanBalance> {\n const holderAddress = isEthereumAddress(accountAddress)\n ? accountAddress\n : this.getAccountAddress()\n\n if (!holderAddress) {\n throw new PaymentsError('Holder address is required')\n }\n\n const balanceUrl = API_URL_PLAN_BALANCE.replace(':planId', planId).replace(\n ':holderAddress',\n holderAddress,\n )\n\n const options = {\n method: 'GET',\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n },\n }\n const url = new URL(balanceUrl, this.environment.backend)\n const response = await fetch(url, options)\n if (!response.ok) {\n throw PaymentsError.fromBackend('Unable to get balance', await safeParseJson(response))\n }\n\n return response.json()\n }\n\n /**\n * Orders a Payment Plan requiring the payment in crypto. The user must have enough balance in the selected token.\n *\n * @remarks\n * The payment is done using crypto in the token (ERC20 or native) defined in the plan.\n *\n * @param planId - The unique identifier of the plan.\n * @returns @see {@link NvmAPIResult} A promise that resolves indicating if the operation was successful.\n * @throws PaymentsError if unable to order the plan.\n *\n * @example\n * ```\n * const result = await payments.plans.orderPlan(planId)\n * // {\n * // txHash: '0x8d29d5769e832a35e53f80cd4e8890d941c50a09c33dbd975533debc894f2535',\n * // success: true\n * // }\n * ```\n */\n public async orderPlan(planId: string): Promise<NvmAPIResult> {\n const options = this.getBackendHTTPOptions('POST')\n const url = new URL(API_URL_ORDER_PLAN.replace(':planId', planId), this.environment.backend)\n const response = await fetch(url, options)\n if (!response.ok) {\n throw PaymentsError.fromBackend('Unable to order plan', await safeParseJson(response))\n }\n\n return response.json()\n }\n\n /**\n * Initiates the purchase of a Plan requiring the payment in Fiat. This method will return a URL where the user can complete the payment.\n *\n * @remarks\n * The payment is completed using a credit card in a external website (Stripe).\n * @remarks\n * This method is only valid for plans with price in Fiat.\n *\n * @param planId - The unique identifier of the plan.\n * @returns A promise that resolves indicating the URL to complete the payment.\n * @throws PaymentsError if unable to order the plan.\n *\n * @example\n * ```\n * const result = await payments.plans.orderFiatPlan(planId)\n * ```\n */\n public async orderFiatPlan(planId: string): Promise<{ result: StripeCheckoutResult }> {\n const body = {\n sessionType: 'embedded',\n planId,\n }\n const options = this.getBackendHTTPOptions('POST', body)\n const url = new URL(API_URL_STRIPE_CHECKOUT, this.environment.backend)\n const response = await fetch(url, options)\n if (!response.ok) {\n throw PaymentsError.fromBackend('Unable to order fiat plan', await safeParseJson(response))\n }\n\n return response.json()\n }\n\n /**\n * Mints credits for a given Payment Plan and transfers them to a receiver.\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 creditsAmount - The number of credits to mint.\n * @param creditsReceiver - The address of the receiver.\n * @returns @see {@link NvmAPIResult} A promise that resolves to the result of the operation.\n * @throws PaymentsError if unable to mint credits.\n *\n * @example\n * ```\n * const result = await payments.plans.mintPlanCredits(planId, 5n, '0x505384192Ba6a4D4b50EAB846ee67db3b9A93359')\n * // {\n * // txHash: '0x8d29d5769e832a35e53f80cd4e8890d941c50a09c33dbd975533debc894f2535',\n * // success: true\n * // }\n * ```\n */\n public async mintPlanCredits(\n planId: string,\n creditsAmount: bigint,\n creditsReceiver: Address,\n ): Promise<NvmAPIResult> {\n const body = { planId, amount: creditsAmount, creditsReceiver }\n const options = this.getBackendHTTPOptions('POST', body)\n const url = new URL(API_URL_MINT_PLAN, this.environment.backend)\n const response = await fetch(url, options)\n if (!response.ok) {\n throw PaymentsError.fromBackend('Unable to mint plan credits', await safeParseJson(response))\n }\n\n return response.json()\n }\n\n /**\n * Mints expirable credits for a given Payment Plan and transfers them to a receiver.\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 creditsAmount - The number of credits to mint.\n * @param creditsReceiver - The address of the receiver.\n * @param creditsDuration - The duration of the credits in seconds. Default is 0 (no expiration).\n * @returns @see {@link NvmAPIResult} A promise that resolves to the result of the operation.\n * @throws PaymentsError if unable to mint expirable credits.\n *\n * @example\n * ```\n * const result = await payments.plans.mintPlanExpirable(\n * planId,\n * 1n,\n * '0x505384192Ba6a4D4b50EAB846ee67db3b9A93359',\n * 86_400n // 1 day in seconds\n * )\n * // {\n * // txHash: '0x8d29d5769e832a35e53f80cd4e8890d941c50a09c33dbd975533debc894f2535',\n * // success: true\n * // }\n * ```\n */\n public async mintPlanExpirable(\n planId: string,\n creditsAmount: bigint,\n creditsReceiver: Address,\n creditsDuration = 0n,\n ): Promise<NvmAPIResult> {\n const body = { planId, creditsAmount, creditsReceiver, creditsDuration }\n const options = this.getBackendHTTPOptions('POST', body)\n const url = new URL(API_URL_MINT_EXPIRABLE_PLAN, this.environment.backend)\n const response = await fetch(url, options)\n if (!response.ok) {\n throw PaymentsError.fromBackend(\n 'Unable to mint expirable credits',\n await safeParseJson(response),\n )\n }\n\n return response.json()\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"requests-api.d.ts","sourceRoot":"","sources":["../../src/api/requests-api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AACpD,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,iBAAiB,EACjB,YAAY,EACZ,wBAAwB,EACzB,MAAM,oBAAoB,CAAA;AAQ3B;;;GAGG;AACH,qBAAa,gBAAiB,SAAQ,eAAe;IACnD;;;;;OAKG;IACH,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE,cAAc,GAAG,gBAAgB;IAK7D;;;;;;;;;;;;;;;;;;;;OAoBG;IACU,sBAAsB,CACjC,IAAI,GAAE,wBAA6B,GAClC,OAAO,CAAC,iBAAiB,CAAC;IAU7B;;;;;;;;;;;;;;;;;;;;;OAqBG;IACU,uBAAuB,CAClC,cAAc,EAAE,MAAM,EACtB,aAAa,SAAM,EACnB,KAAK,UAAQ,GACZ,OAAO,CAAC,YAAY,CAAC;IAiDxB;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;IACU,iBAAiB,CAAC,iBAAiB,EAAE,oBAAoB,GAAG,OAAO,CAAC,YAAY,CAAC;CAmB/F"}
1
+ {"version":3,"file":"requests-api.d.ts","sourceRoot":"","sources":["../../src/api/requests-api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AACpD,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,iBAAiB,EACjB,YAAY,EACZ,wBAAwB,EACzB,MAAM,oBAAoB,CAAA;AAS3B;;;GAGG;AACH,qBAAa,gBAAiB,SAAQ,eAAe;IACnD;;;;;OAKG;IACH,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE,cAAc,GAAG,gBAAgB;IAI7D;;;;;;;;;;;;;;;;;;;;OAoBG;IACU,sBAAsB,CACjC,IAAI,GAAE,wBAA6B,GAClC,OAAO,CAAC,iBAAiB,CAAC;IAa7B;;;;;;;;;;;;;;;;;;;;;OAqBG;IACU,uBAAuB,CAClC,cAAc,EAAE,MAAM,EACtB,aAAa,SAAM,EACnB,KAAK,UAAQ,GACZ,OAAO,CAAC,YAAY,CAAC;IAgDxB;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;IACU,iBAAiB,CAAC,iBAAiB,EAAE,oBAAoB,GAAG,OAAO,CAAC,YAAY,CAAC;CAsB/F"}
@@ -1,6 +1,7 @@
1
1
  import { BasePaymentsAPI } from './base-payments.js';
2
2
  import { API_URL_TRACK_AGENT_SUB_TASK, API_URL_SIMULATE_AGENT_REQUEST, API_URL_SIMULATE_REDEEM_AGENT_REQUEST, } from './nvm-api.js';
3
3
  import { PaymentsError } from '../common/payments.error.js';
4
+ import { safeParseJson } from '../common/helper.js';
4
5
  /**
5
6
  * The AgentRequestsAPI class provides methods to manage the requests received by AI Agents integrated with Nevermined.
6
7
  *
@@ -41,7 +42,7 @@ export class AgentRequestsAPI extends BasePaymentsAPI {
41
42
  const options = this.getBackendHTTPOptions('POST', opts);
42
43
  const response = await fetch(url, options);
43
44
  if (!response.ok) {
44
- throw PaymentsError.fromBackend('Unable to start simulation request', await response.json());
45
+ throw PaymentsError.fromBackend('Unable to start simulation request', await safeParseJson(response));
45
46
  }
46
47
  return response.json();
47
48
  }
@@ -82,7 +83,7 @@ export class AgentRequestsAPI extends BasePaymentsAPI {
82
83
  try {
83
84
  const response = await fetch(url, options);
84
85
  if (!response.ok) {
85
- lastError = PaymentsError.fromBackend('Unable to finish simulation request', await response.json());
86
+ lastError = PaymentsError.fromBackend('Unable to finish simulation request', await safeParseJson(response));
86
87
  if (attempt < maxRetries - 1) {
87
88
  await new Promise((resolve) => setTimeout(resolve, 1000));
88
89
  continue;
@@ -149,7 +150,7 @@ export class AgentRequestsAPI extends BasePaymentsAPI {
149
150
  const url = new URL(API_URL_TRACK_AGENT_SUB_TASK, this.environment.backend);
150
151
  const response = await fetch(url, options);
151
152
  if (!response.ok) {
152
- throw PaymentsError.fromBackend('Unable to track agent sub task', await response.json());
153
+ throw PaymentsError.fromBackend('Unable to track agent sub task', await safeParseJson(response));
153
154
  }
154
155
  return response.json();
155
156
  }
@@ -1 +1 @@
1
- {"version":3,"file":"requests-api.js","sourceRoot":"","sources":["../../src/api/requests-api.ts"],"names":[],"mappings":"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","sourcesContent":["import { BasePaymentsAPI } from './base-payments.js'\nimport {\n PaymentOptions,\n TrackAgentSubTaskDto,\n StartAgentRequest,\n NvmAPIResult,\n SimulationRequestOptions,\n} from '../common/types.js'\nimport {\n API_URL_TRACK_AGENT_SUB_TASK,\n API_URL_SIMULATE_AGENT_REQUEST,\n API_URL_SIMULATE_REDEEM_AGENT_REQUEST,\n} from './nvm-api.js'\nimport { PaymentsError } from '../common/payments.error.js'\n\n/**\n * The AgentRequestsAPI class provides methods to manage the requests received by AI Agents integrated with Nevermined.\n *\n */\nexport class AgentRequestsAPI extends BasePaymentsAPI {\n /**\n * This method is used to create a singleton instance of the AgentRequestsAPI class.\n *\n * @param options - The options to initialize the payments class.\n * @returns The instance of the AgentRequestsAPI class.\n */\n static getInstance(options: PaymentOptions): AgentRequestsAPI {\n return new AgentRequestsAPI(options)\n }\n\n\n /**\n * This method simulates an agent request.\n *\n * @remarks\n * This method is used to simulate an agent request.\n *\n * @param opts - The options for the simulation request.\n * @returns @see {@link StartAgentRequest} The information about the simulation of the request.\n * @throws PaymentsError if unable to simulate the agent request.\n *\n * @example\n * ```\n * const result = await payments.requests.startSimulationRequest()\n *\n * // {\n * // agentRequestId: '3921032910321',\n * // urlMatching: 'https://api.example.com/agent-endpoint/1234',\n * // verbMatching: 'POST'\n * // }\n * ```\n */\n public async startSimulationRequest(\n opts: SimulationRequestOptions = {},\n ): Promise<StartAgentRequest> {\n const url = new URL(API_URL_SIMULATE_AGENT_REQUEST, this.environment.backend).toString()\n const options = this.getBackendHTTPOptions('POST', opts)\n const response = await fetch(url, options)\n if (!response.ok) {\n throw PaymentsError.fromBackend('Unable to start simulation request', await response.json())\n }\n return response.json()\n }\n\n /**\n * This method simulates the redemption of credits for an agent request.\n *\n * @remarks\n * This method is used to simulate the redemption of credits for an agent request.\n *\n * @param agentRequestId - The unique identifier of the agent request.\n * @param marginPercent - The margin percentage to apply. Defaults to 20%.\n * @param batch - Whether the request is a batch request. Defaults to false.\n * @returns @see {@link NvmAPIResult} The result of the simulation.\n * @throws PaymentsError if unable to finish the simulation request.\n *\n * @example\n * ```\n * const result = await payments.requests.finishSimulationRequest('arId-3921032910321', 0.2, true)\n *\n * // {\n * // creditsToRedeem: '10',\n * // success: true\n * // }\n * ```\n */\n public async finishSimulationRequest(\n agentRequestId: string,\n marginPercent = 0.2,\n batch = false,\n ): Promise<NvmAPIResult> {\n const url = new URL(API_URL_SIMULATE_REDEEM_AGENT_REQUEST, this.environment.backend).toString()\n const options = this.getBackendHTTPOptions('POST', {\n agentRequestId,\n marginPercent,\n batch,\n })\n\n // Since this method is usually called immediately after the llm call\n // the request might not be immediately available on helicone, so we need to retry.\n const maxRetries = 3\n let lastError: Error | null = null\n\n for (let attempt = 0; attempt < maxRetries; attempt++) {\n try {\n const response = await fetch(url, options)\n if (!response.ok) {\n lastError = PaymentsError.fromBackend(\n 'Unable to finish simulation request',\n await response.json(),\n )\n if (attempt < maxRetries - 1) {\n await new Promise((resolve) => setTimeout(resolve, 1000))\n continue\n }\n throw lastError\n }\n return response.json()\n } catch (error) {\n if (error instanceof PaymentsError) {\n lastError = error\n } else {\n lastError = PaymentsError.fromBackend('Unable to finish simulation request', {\n error: String(error),\n })\n }\n if (attempt < maxRetries - 1) {\n await new Promise((resolve) => setTimeout(resolve, 1000))\n continue\n }\n throw lastError\n }\n }\n\n // This should never be reached, but TypeScript requires it\n throw lastError || new PaymentsError('Unable to finish simulation request')\n }\n\n\n /**\n * Tracks an agent sub task.\n *\n * @remarks\n * This method is used by agent owners to track agent sub tasks for agent tasks.\n * It records information about credit redemption, categorization tags, and processing descriptions.\n *\n * @param trackAgentSubTask - @see {@link TrackAgentSubTaskDto} The agent sub task data to track\n * @returns @see {@link NvmAPIResult} A promise that resolves to the result of the operation.\n * @throws PaymentsError if unable to track the agent sub task\n *\n * @example\n * ```\n * const result = await payments.requests.trackAgentSubTask({\n * agentRequestId: 'atx-12345',\n * creditsToRedeem: 5,\n * tag: 'high-priority',\n * description: 'Processing high-priority data request',\n * status: AgentTaskStatus.SUCCESS\n * })\n *\n * // {\n * // txHash: '0x8d29d5769e832a35e53f80cd4e8890d941c50a09c33dbd975533debc894f2535',\n * // success: true\n * // }\n * ```\n */\n public async trackAgentSubTask(trackAgentSubTask: TrackAgentSubTaskDto): Promise<NvmAPIResult> {\n const body = {\n agentRequestId: trackAgentSubTask.agentRequestId,\n creditsToRedeem: trackAgentSubTask.creditsToRedeem || 0,\n tag: trackAgentSubTask.tag,\n description: trackAgentSubTask.description,\n status: trackAgentSubTask.status,\n }\n\n const options = this.getBackendHTTPOptions('POST', body)\n const url = new URL(API_URL_TRACK_AGENT_SUB_TASK, this.environment.backend)\n const response = await fetch(url, options)\n\n if (!response.ok) {\n throw PaymentsError.fromBackend('Unable to track agent sub task', await response.json())\n }\n\n return response.json()\n }\n}\n"]}
1
+ {"version":3,"file":"requests-api.js","sourceRoot":"","sources":["../../src/api/requests-api.ts"],"names":[],"mappings":"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","sourcesContent":["import { BasePaymentsAPI } from './base-payments.js'\nimport {\n PaymentOptions,\n TrackAgentSubTaskDto,\n StartAgentRequest,\n NvmAPIResult,\n SimulationRequestOptions,\n} from '../common/types.js'\nimport {\n API_URL_TRACK_AGENT_SUB_TASK,\n API_URL_SIMULATE_AGENT_REQUEST,\n API_URL_SIMULATE_REDEEM_AGENT_REQUEST,\n} from './nvm-api.js'\nimport { PaymentsError } from '../common/payments.error.js'\nimport { safeParseJson } from '../common/helper.js'\n\n/**\n * The AgentRequestsAPI class provides methods to manage the requests received by AI Agents integrated with Nevermined.\n *\n */\nexport class AgentRequestsAPI extends BasePaymentsAPI {\n /**\n * This method is used to create a singleton instance of the AgentRequestsAPI class.\n *\n * @param options - The options to initialize the payments class.\n * @returns The instance of the AgentRequestsAPI class.\n */\n static getInstance(options: PaymentOptions): AgentRequestsAPI {\n return new AgentRequestsAPI(options)\n }\n\n /**\n * This method simulates an agent request.\n *\n * @remarks\n * This method is used to simulate an agent request.\n *\n * @param opts - The options for the simulation request.\n * @returns @see {@link StartAgentRequest} The information about the simulation of the request.\n * @throws PaymentsError if unable to simulate the agent request.\n *\n * @example\n * ```\n * const result = await payments.requests.startSimulationRequest()\n *\n * // {\n * // agentRequestId: '3921032910321',\n * // urlMatching: 'https://api.example.com/agent-endpoint/1234',\n * // verbMatching: 'POST'\n * // }\n * ```\n */\n public async startSimulationRequest(\n opts: SimulationRequestOptions = {},\n ): Promise<StartAgentRequest> {\n const url = new URL(API_URL_SIMULATE_AGENT_REQUEST, this.environment.backend).toString()\n const options = this.getBackendHTTPOptions('POST', opts)\n const response = await fetch(url, options)\n if (!response.ok) {\n throw PaymentsError.fromBackend(\n 'Unable to start simulation request',\n await safeParseJson(response),\n )\n }\n return response.json()\n }\n\n /**\n * This method simulates the redemption of credits for an agent request.\n *\n * @remarks\n * This method is used to simulate the redemption of credits for an agent request.\n *\n * @param agentRequestId - The unique identifier of the agent request.\n * @param marginPercent - The margin percentage to apply. Defaults to 20%.\n * @param batch - Whether the request is a batch request. Defaults to false.\n * @returns @see {@link NvmAPIResult} The result of the simulation.\n * @throws PaymentsError if unable to finish the simulation request.\n *\n * @example\n * ```\n * const result = await payments.requests.finishSimulationRequest('arId-3921032910321', 0.2, true)\n *\n * // {\n * // creditsToRedeem: '10',\n * // success: true\n * // }\n * ```\n */\n public async finishSimulationRequest(\n agentRequestId: string,\n marginPercent = 0.2,\n batch = false,\n ): Promise<NvmAPIResult> {\n const url = new URL(API_URL_SIMULATE_REDEEM_AGENT_REQUEST, this.environment.backend).toString()\n const options = this.getBackendHTTPOptions('POST', {\n agentRequestId,\n marginPercent,\n batch,\n })\n\n // Since this method is usually called immediately after the llm call\n // the request might not be immediately available on helicone, so we need to retry.\n const maxRetries = 3\n let lastError: Error | null = null\n\n for (let attempt = 0; attempt < maxRetries; attempt++) {\n try {\n const response = await fetch(url, options)\n if (!response.ok) {\n lastError = PaymentsError.fromBackend(\n 'Unable to finish simulation request',\n await safeParseJson(response),\n )\n if (attempt < maxRetries - 1) {\n await new Promise((resolve) => setTimeout(resolve, 1000))\n continue\n }\n throw lastError\n }\n return response.json()\n } catch (error) {\n if (error instanceof PaymentsError) {\n lastError = error\n } else {\n lastError = PaymentsError.fromBackend('Unable to finish simulation request', {\n error: String(error),\n })\n }\n if (attempt < maxRetries - 1) {\n await new Promise((resolve) => setTimeout(resolve, 1000))\n continue\n }\n throw lastError\n }\n }\n\n // This should never be reached, but TypeScript requires it\n throw lastError || new PaymentsError('Unable to finish simulation request')\n }\n\n /**\n * Tracks an agent sub task.\n *\n * @remarks\n * This method is used by agent owners to track agent sub tasks for agent tasks.\n * It records information about credit redemption, categorization tags, and processing descriptions.\n *\n * @param trackAgentSubTask - @see {@link TrackAgentSubTaskDto} The agent sub task data to track\n * @returns @see {@link NvmAPIResult} A promise that resolves to the result of the operation.\n * @throws PaymentsError if unable to track the agent sub task\n *\n * @example\n * ```\n * const result = await payments.requests.trackAgentSubTask({\n * agentRequestId: 'atx-12345',\n * creditsToRedeem: 5,\n * tag: 'high-priority',\n * description: 'Processing high-priority data request',\n * status: AgentTaskStatus.SUCCESS\n * })\n *\n * // {\n * // txHash: '0x8d29d5769e832a35e53f80cd4e8890d941c50a09c33dbd975533debc894f2535',\n * // success: true\n * // }\n * ```\n */\n public async trackAgentSubTask(trackAgentSubTask: TrackAgentSubTaskDto): Promise<NvmAPIResult> {\n const body = {\n agentRequestId: trackAgentSubTask.agentRequestId,\n creditsToRedeem: trackAgentSubTask.creditsToRedeem || 0,\n tag: trackAgentSubTask.tag,\n description: trackAgentSubTask.description,\n status: trackAgentSubTask.status,\n }\n\n const options = this.getBackendHTTPOptions('POST', body)\n const url = new URL(API_URL_TRACK_AGENT_SUB_TASK, this.environment.backend)\n const response = await fetch(url, options)\n\n if (!response.ok) {\n throw PaymentsError.fromBackend(\n 'Unable to track agent sub task',\n await safeParseJson(response),\n )\n }\n\n return response.json()\n }\n}\n"]}
@@ -1,5 +1,16 @@
1
1
  import { Endpoint } from './types.js';
2
2
  export declare const sleep: (ms: number) => Promise<unknown>;
3
+ /**
4
+ * Safe JSON parse for fetch responses. Reads the body once and tolerates
5
+ * non-JSON payloads (e.g. NGINX HTML 5xx gateway pages) by returning a
6
+ * `{ message }` shell that downstream error code paths can still consume.
7
+ *
8
+ * Prevents the failure mode tracked in #1727: callers doing
9
+ * `throw PaymentsError.fromBackend('...', await response.json())` would
10
+ * otherwise let a SyntaxError from `.json()` escape and surface as an
11
+ * `unhandledRejection` that can take the host Node process down.
12
+ */
13
+ export declare function safeParseJson(response: Response): Promise<unknown>;
3
14
  export declare const jsonReplacer: (_key: any, value: {
4
15
  toString: () => any;
5
16
  }) => string | {
@@ -1 +1 @@
1
- {"version":3,"file":"helper.d.ts","sourceRoot":"","sources":["../../src/common/helper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAErC,eAAO,MAAM,KAAK,GAAI,IAAI,MAAM,qBAAsD,CAAA;AAEtF,eAAO,MAAM,YAAY,GAAI,MAAM,GAAG,EAAE,OAAO;IAAE,QAAQ,EAAE,MAAM,GAAG,CAAA;CAAE;cAAX,MAAM,GAAG;CAEnE,CAAA;AAED,eAAO,MAAM,2BAA2B,GAAI,WAAW,QAAQ,EAAE,KAAG,MAOnE,CAAA"}
1
+ {"version":3,"file":"helper.d.ts","sourceRoot":"","sources":["../../src/common/helper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAErC,eAAO,MAAM,KAAK,GAAI,IAAI,MAAM,qBAAsD,CAAA;AAEtF;;;;;;;;;GASG;AACH,wBAAsB,aAAa,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,CAmBxE;AAED,eAAO,MAAM,YAAY,GAAI,MAAM,GAAG,EAAE,OAAO;IAAE,QAAQ,EAAE,MAAM,GAAG,CAAA;CAAE;cAAX,MAAM,GAAG;CAEnE,CAAA;AAED,eAAO,MAAM,2BAA2B,GAAI,WAAW,QAAQ,EAAE,KAAG,MAOnE,CAAA"}
@@ -1,4 +1,36 @@
1
1
  export const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
2
+ /**
3
+ * Safe JSON parse for fetch responses. Reads the body once and tolerates
4
+ * non-JSON payloads (e.g. NGINX HTML 5xx gateway pages) by returning a
5
+ * `{ message }` shell that downstream error code paths can still consume.
6
+ *
7
+ * Prevents the failure mode tracked in #1727: callers doing
8
+ * `throw PaymentsError.fromBackend('...', await response.json())` would
9
+ * otherwise let a SyntaxError from `.json()` escape and surface as an
10
+ * `unhandledRejection` that can take the host Node process down.
11
+ */
12
+ export async function safeParseJson(response) {
13
+ const contentType = response.headers.get('content-type') ?? '';
14
+ // Always consume the body so the underlying socket can be released, even
15
+ // when we decide we can't parse it as JSON.
16
+ const text = await response.text().catch(() => '');
17
+ if (!text)
18
+ return {};
19
+ if (!contentType.toLowerCase().includes('json')) {
20
+ // Truncate to keep the payload bounded — a full HTML gateway page is
21
+ // noise in an error log.
22
+ const snippet = text.length > 200 ? `${text.slice(0, 200)}…` : text;
23
+ return { message: `Non-JSON response (${contentType || 'no content-type'}): ${snippet}` };
24
+ }
25
+ try {
26
+ return JSON.parse(text);
27
+ }
28
+ catch (cause) {
29
+ return {
30
+ message: `Malformed JSON response: ${cause instanceof Error ? cause.message : String(cause)}`,
31
+ };
32
+ }
33
+ }
2
34
  export const jsonReplacer = (_key, value) => {
3
35
  return typeof value === 'bigint' ? value.toString() : value;
4
36
  };
@@ -1 +1 @@
1
- {"version":3,"file":"helper.js","sourceRoot":"","sources":["../../src/common/helper.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,EAAU,EAAE,EAAE,CAAC,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAA;AAEtF,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,IAAS,EAAE,KAA8B,EAAE,EAAE;IACxE,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,KAAK,CAAA;AAC7D,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,SAAqB,EAAU,EAAE;IAC3E,IAAI,WAAW,GAAG,EAAE,CAAA;IACpB,SAAS,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE;QAC1B,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAA;QAC5C,WAAW,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,CAAC,MAAM,CAAA;IACzC,CAAC,CAAC,CAAA;IACF,OAAO,WAAW,CAAA;AACpB,CAAC,CAAA","sourcesContent":["import { Endpoint } from './types.js'\n\nexport const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms))\n\nexport const jsonReplacer = (_key: any, value: { toString: () => any }) => {\n return typeof value === 'bigint' ? value.toString() : value\n}\n\nexport const getServiceHostFromEndpoints = (endpoints: Endpoint[]): string => {\n let serviceHost = ''\n endpoints.some((endpoint) => {\n const _endpoint = Object.values(endpoint)[0]\n serviceHost = new URL(_endpoint).origin\n })\n return serviceHost\n}\n"]}
1
+ {"version":3,"file":"helper.js","sourceRoot":"","sources":["../../src/common/helper.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,EAAU,EAAE,EAAE,CAAC,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAA;AAEtF;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,QAAkB;IACpD,MAAM,WAAW,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,CAAA;IAC9D,yEAAyE;IACzE,4CAA4C;IAC5C,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAA;IAClD,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,CAAA;IACpB,IAAI,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAChD,qEAAqE;QACrE,yBAAyB;QACzB,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAA;QACnE,OAAO,EAAE,OAAO,EAAE,sBAAsB,WAAW,IAAI,iBAAiB,MAAM,OAAO,EAAE,EAAE,CAAA;IAC3F,CAAC;IACD,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IACzB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,OAAO,EAAE,4BAA4B,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;SAC9F,CAAA;IACH,CAAC;AACH,CAAC;AAED,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,IAAS,EAAE,KAA8B,EAAE,EAAE;IACxE,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,KAAK,CAAA;AAC7D,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,SAAqB,EAAU,EAAE;IAC3E,IAAI,WAAW,GAAG,EAAE,CAAA;IACpB,SAAS,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE;QAC1B,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAA;QAC5C,WAAW,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,CAAC,MAAM,CAAA;IACzC,CAAC,CAAC,CAAA;IACF,OAAO,WAAW,CAAA;AACpB,CAAC,CAAA","sourcesContent":["import { Endpoint } from './types.js'\n\nexport const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms))\n\n/**\n * Safe JSON parse for fetch responses. Reads the body once and tolerates\n * non-JSON payloads (e.g. NGINX HTML 5xx gateway pages) by returning a\n * `{ message }` shell that downstream error code paths can still consume.\n *\n * Prevents the failure mode tracked in #1727: callers doing\n * `throw PaymentsError.fromBackend('...', await response.json())` would\n * otherwise let a SyntaxError from `.json()` escape and surface as an\n * `unhandledRejection` that can take the host Node process down.\n */\nexport async function safeParseJson(response: Response): Promise<unknown> {\n const contentType = response.headers.get('content-type') ?? ''\n // Always consume the body so the underlying socket can be released, even\n // when we decide we can't parse it as JSON.\n const text = await response.text().catch(() => '')\n if (!text) return {}\n if (!contentType.toLowerCase().includes('json')) {\n // Truncate to keep the payload bounded — a full HTML gateway page is\n // noise in an error log.\n const snippet = text.length > 200 ? `${text.slice(0, 200)}…` : text\n return { message: `Non-JSON response (${contentType || 'no content-type'}): ${snippet}` }\n }\n try {\n return JSON.parse(text)\n } catch (cause) {\n return {\n message: `Malformed JSON response: ${cause instanceof Error ? cause.message : String(cause)}`,\n }\n }\n}\n\nexport const jsonReplacer = (_key: any, value: { toString: () => any }) => {\n return typeof value === 'bigint' ? value.toString() : value\n}\n\nexport const getServiceHostFromEndpoints = (endpoints: Endpoint[]): string => {\n let serviceHost = ''\n endpoints.some((endpoint) => {\n const _endpoint = Object.values(endpoint)[0]\n serviceHost = new URL(_endpoint).origin\n })\n return serviceHost\n}\n"]}
@@ -1,5 +1,13 @@
1
1
  export interface EnvironmentInfo {
2
2
  frontend: string;
3
+ /**
4
+ * Base URL of the standalone, Privy-free embed app (the `embed.<tier>`
5
+ * origin that serves the chromeless `/cards/*` and `/checkout/*` pages).
6
+ * Formed by prepending `embed.` to the webapp host. The CLI redirect-mode
7
+ * card flows open `${embed}/cards/setup` here — the old webapp
8
+ * `/embed/cards/*` routes were removed in the #1787 cutover.
9
+ */
10
+ embed: string;
3
11
  backend: string;
4
12
  proxy: string;
5
13
  heliconeUrl: string;
@@ -1 +1 @@
1
- {"version":3,"file":"environments.d.ts","sourceRoot":"","sources":["../src/environments.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,eAAO,MAAM,WAAW,+CAA+C,CAAA;AAEvE,MAAM,MAAM,eAAe,GAAG,iBAAiB,GAAG,cAAc,GAAG,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAA;AAEhG;;GAEG;AACH,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,eAAe,EAAE,eAAe,CA2CjE,CAAA"}
1
+ {"version":3,"file":"environments.d.ts","sourceRoot":"","sources":["../src/environments.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAA;IAChB;;;;;;OAMG;IACH,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,eAAO,MAAM,WAAW,+CAA+C,CAAA;AAEvE,MAAM,MAAM,eAAe,GAAG,iBAAiB,GAAG,cAAc,GAAG,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAA;AAEhG;;GAEG;AACH,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,eAAe,EAAE,eAAe,CAqDjE,CAAA"}
@@ -8,12 +8,14 @@ export const Environments = {
8
8
  */
9
9
  staging_sandbox: {
10
10
  frontend: 'https://nevermined.dev',
11
+ embed: 'https://embed.nevermined.dev',
11
12
  backend: 'https://api.sandbox.nevermined.dev/',
12
13
  proxy: 'https://proxy.sandbox.nevermined.dev',
13
14
  heliconeUrl: 'https://helicone.nevermined.dev',
14
15
  },
15
16
  staging_live: {
16
17
  frontend: 'https://nevermined.dev',
18
+ embed: 'https://embed.nevermined.dev',
17
19
  backend: 'https://api.live.nevermined.dev/',
18
20
  proxy: 'https://proxy.live.nevermined.dev',
19
21
  heliconeUrl: 'https://helicone.nevermined.dev',
@@ -23,6 +25,7 @@ export const Environments = {
23
25
  */
24
26
  sandbox: {
25
27
  frontend: 'https://nevermined.app',
28
+ embed: 'https://embed.nevermined.app',
26
29
  backend: 'https://api.sandbox.nevermined.app/',
27
30
  proxy: 'https://proxy.sandbox.nevermined.app',
28
31
  heliconeUrl: 'https://helicone.nevermined.dev',
@@ -32,6 +35,7 @@ export const Environments = {
32
35
  */
33
36
  live: {
34
37
  frontend: 'https://nevermined.app',
38
+ embed: 'https://embed.nevermined.app',
35
39
  backend: 'https://api.live.nevermined.app/',
36
40
  proxy: 'https://proxy.live.nevermined.app',
37
41
  heliconeUrl: 'https://helicone.nevermined.dev',
@@ -41,6 +45,12 @@ export const Environments = {
41
45
  */
42
46
  custom: {
43
47
  frontend: process.env.NVM_FRONTEND_URL || 'http://localhost:4200',
48
+ // No fallback to NVM_FRONTEND_URL: the webapp host no longer serves
49
+ // the card pages post-#1787 cutover, so silently reusing it would
50
+ // reintroduce a dead-route footgun. The embed app runs on its own
51
+ // port (4250, matching nvm-monorepo#1824); set NVM_EMBED_URL to
52
+ // override.
53
+ embed: process.env.NVM_EMBED_URL || 'http://localhost:4250',
44
54
  backend: process.env.NVM_BACKEND_URL || 'http://localhost:3001',
45
55
  proxy: process.env.NVM_PROXY_URL || 'https://localhost:443',
46
56
  heliconeUrl: process.env.HELICONE_URL || 'http://localhost:8585',
@@ -1 +1 @@
1
- {"version":3,"file":"environments.js","sourceRoot":"","sources":["../src/environments.ts"],"names":[],"mappings":"AAOA,MAAM,CAAC,MAAM,WAAW,GAAG,4CAA4C,CAAA;AAIvE;;GAEG;AACH,MAAM,CAAC,MAAM,YAAY,GAA6C;IACpE;;OAEG;IACH,eAAe,EAAE;QACf,QAAQ,EAAE,wBAAwB;QAClC,OAAO,EAAE,qCAAqC;QAC9C,KAAK,EAAE,sCAAsC;QAC7C,WAAW,EAAE,iCAAiC;KAC/C;IACD,YAAY,EAAE;QACZ,QAAQ,EAAE,wBAAwB;QAClC,OAAO,EAAE,kCAAkC;QAC3C,KAAK,EAAE,mCAAmC;QAC1C,WAAW,EAAE,iCAAiC;KAC/C;IACD;;OAEG;IACH,OAAO,EAAE;QACP,QAAQ,EAAE,wBAAwB;QAClC,OAAO,EAAE,qCAAqC;QAC9C,KAAK,EAAE,sCAAsC;QAC7C,WAAW,EAAE,iCAAiC;KAC/C;IACD;;OAEG;IACH,IAAI,EAAE;QACJ,QAAQ,EAAE,wBAAwB;QAClC,OAAO,EAAE,kCAAkC;QAC3C,KAAK,EAAE,mCAAmC;QAC1C,WAAW,EAAE,iCAAiC;KAC/C;IACD;;OAEG;IACH,MAAM,EAAE;QACN,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,uBAAuB;QACjE,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,uBAAuB;QAC/D,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,uBAAuB;QAC3D,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,uBAAuB;KACjE;CACF,CAAA","sourcesContent":["export interface EnvironmentInfo {\n frontend: string\n backend: string\n proxy: string\n heliconeUrl: string\n}\n\nexport const ZeroAddress = '0x0000000000000000000000000000000000000000'\n\nexport type EnvironmentName = 'staging_sandbox' | 'staging_live' | 'sandbox' | 'live' | 'custom'\n\n/**\n * Represents the different environments and their corresponding URLs.\n */\nexport const Environments: Record<EnvironmentName, EnvironmentInfo> = {\n /**\n * The staging environment URLs.\n */\n staging_sandbox: {\n frontend: 'https://nevermined.dev',\n backend: 'https://api.sandbox.nevermined.dev/',\n proxy: 'https://proxy.sandbox.nevermined.dev',\n heliconeUrl: 'https://helicone.nevermined.dev',\n },\n staging_live: {\n frontend: 'https://nevermined.dev',\n backend: 'https://api.live.nevermined.dev/',\n proxy: 'https://proxy.live.nevermined.dev',\n heliconeUrl: 'https://helicone.nevermined.dev',\n },\n /**\n * The Sandbox environment URLs.\n */\n sandbox: {\n frontend: 'https://nevermined.app',\n backend: 'https://api.sandbox.nevermined.app/',\n proxy: 'https://proxy.sandbox.nevermined.app',\n heliconeUrl: 'https://helicone.nevermined.dev',\n },\n /**\n * The Live environment URLs.\n */\n live: {\n frontend: 'https://nevermined.app',\n backend: 'https://api.live.nevermined.app/',\n proxy: 'https://proxy.live.nevermined.app',\n heliconeUrl: 'https://helicone.nevermined.dev',\n },\n /**\n * A custom environment URLs.\n */\n custom: {\n frontend: process.env.NVM_FRONTEND_URL || 'http://localhost:4200',\n backend: process.env.NVM_BACKEND_URL || 'http://localhost:3001',\n proxy: process.env.NVM_PROXY_URL || 'https://localhost:443',\n heliconeUrl: process.env.HELICONE_URL || 'http://localhost:8585',\n },\n}\n"]}
1
+ {"version":3,"file":"environments.js","sourceRoot":"","sources":["../src/environments.ts"],"names":[],"mappings":"AAeA,MAAM,CAAC,MAAM,WAAW,GAAG,4CAA4C,CAAA;AAIvE;;GAEG;AACH,MAAM,CAAC,MAAM,YAAY,GAA6C;IACpE;;OAEG;IACH,eAAe,EAAE;QACf,QAAQ,EAAE,wBAAwB;QAClC,KAAK,EAAE,8BAA8B;QACrC,OAAO,EAAE,qCAAqC;QAC9C,KAAK,EAAE,sCAAsC;QAC7C,WAAW,EAAE,iCAAiC;KAC/C;IACD,YAAY,EAAE;QACZ,QAAQ,EAAE,wBAAwB;QAClC,KAAK,EAAE,8BAA8B;QACrC,OAAO,EAAE,kCAAkC;QAC3C,KAAK,EAAE,mCAAmC;QAC1C,WAAW,EAAE,iCAAiC;KAC/C;IACD;;OAEG;IACH,OAAO,EAAE;QACP,QAAQ,EAAE,wBAAwB;QAClC,KAAK,EAAE,8BAA8B;QACrC,OAAO,EAAE,qCAAqC;QAC9C,KAAK,EAAE,sCAAsC;QAC7C,WAAW,EAAE,iCAAiC;KAC/C;IACD;;OAEG;IACH,IAAI,EAAE;QACJ,QAAQ,EAAE,wBAAwB;QAClC,KAAK,EAAE,8BAA8B;QACrC,OAAO,EAAE,kCAAkC;QAC3C,KAAK,EAAE,mCAAmC;QAC1C,WAAW,EAAE,iCAAiC;KAC/C;IACD;;OAEG;IACH,MAAM,EAAE;QACN,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,uBAAuB;QACjE,oEAAoE;QACpE,kEAAkE;QAClE,kEAAkE;QAClE,gEAAgE;QAChE,YAAY;QACZ,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,uBAAuB;QAC3D,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,uBAAuB;QAC/D,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,uBAAuB;QAC3D,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,uBAAuB;KACjE;CACF,CAAA","sourcesContent":["export interface EnvironmentInfo {\n frontend: string\n /**\n * Base URL of the standalone, Privy-free embed app (the `embed.<tier>`\n * origin that serves the chromeless `/cards/*` and `/checkout/*` pages).\n * Formed by prepending `embed.` to the webapp host. The CLI redirect-mode\n * card flows open `${embed}/cards/setup` here — the old webapp\n * `/embed/cards/*` routes were removed in the #1787 cutover.\n */\n embed: string\n backend: string\n proxy: string\n heliconeUrl: string\n}\n\nexport const ZeroAddress = '0x0000000000000000000000000000000000000000'\n\nexport type EnvironmentName = 'staging_sandbox' | 'staging_live' | 'sandbox' | 'live' | 'custom'\n\n/**\n * Represents the different environments and their corresponding URLs.\n */\nexport const Environments: Record<EnvironmentName, EnvironmentInfo> = {\n /**\n * The staging environment URLs.\n */\n staging_sandbox: {\n frontend: 'https://nevermined.dev',\n embed: 'https://embed.nevermined.dev',\n backend: 'https://api.sandbox.nevermined.dev/',\n proxy: 'https://proxy.sandbox.nevermined.dev',\n heliconeUrl: 'https://helicone.nevermined.dev',\n },\n staging_live: {\n frontend: 'https://nevermined.dev',\n embed: 'https://embed.nevermined.dev',\n backend: 'https://api.live.nevermined.dev/',\n proxy: 'https://proxy.live.nevermined.dev',\n heliconeUrl: 'https://helicone.nevermined.dev',\n },\n /**\n * The Sandbox environment URLs.\n */\n sandbox: {\n frontend: 'https://nevermined.app',\n embed: 'https://embed.nevermined.app',\n backend: 'https://api.sandbox.nevermined.app/',\n proxy: 'https://proxy.sandbox.nevermined.app',\n heliconeUrl: 'https://helicone.nevermined.dev',\n },\n /**\n * The Live environment URLs.\n */\n live: {\n frontend: 'https://nevermined.app',\n embed: 'https://embed.nevermined.app',\n backend: 'https://api.live.nevermined.app/',\n proxy: 'https://proxy.live.nevermined.app',\n heliconeUrl: 'https://helicone.nevermined.dev',\n },\n /**\n * A custom environment URLs.\n */\n custom: {\n frontend: process.env.NVM_FRONTEND_URL || 'http://localhost:4200',\n // No fallback to NVM_FRONTEND_URL: the webapp host no longer serves\n // the card pages post-#1787 cutover, so silently reusing it would\n // reintroduce a dead-route footgun. The embed app runs on its own\n // port (4250, matching nvm-monorepo#1824); set NVM_EMBED_URL to\n // override.\n embed: process.env.NVM_EMBED_URL || 'http://localhost:4250',\n backend: process.env.NVM_BACKEND_URL || 'http://localhost:3001',\n proxy: process.env.NVM_PROXY_URL || 'https://localhost:443',\n heliconeUrl: process.env.HELICONE_URL || 'http://localhost:8585',\n },\n}\n"]}
package/dist/plans.d.ts CHANGED
@@ -3,6 +3,30 @@ export declare const ONE_DAY_DURATION = 86400n;
3
3
  export declare const ONE_WEEK_DURATION = 604800n;
4
4
  export declare const ONE_MONTH_DURATION = 2629746n;
5
5
  export declare const ONE_YEAR_DURATION = 31557600n;
6
+ /**
7
+ * Builds a price configuration for fiat-denominated plans (Stripe / Braintree).
8
+ *
9
+ * `amount` is in **6-decimal units** (the USDC convention used across the
10
+ * Nevermined protocol — NOT cents). To charge $2.00, pass `2_000_000n`;
11
+ * `200n` would be read as $0.0002 and rejected by the backend.
12
+ *
13
+ * Minimum charge enforced server-side is **$1.00** (`1_000_000n`) — fiat
14
+ * processor fixed fees make smaller amounts uneconomic. Passing below the
15
+ * minimum surfaces as `BCK.PROTOCOL.0047`.
16
+ *
17
+ * @param amount - Amount in 6-decimal units (e.g. `2_000_000n` for $2.00)
18
+ * @param receiver - Wallet address that will receive the settled funds
19
+ * @param currency - ISO currency code (defaults to `USD`)
20
+ *
21
+ * @example
22
+ * ```ts
23
+ * // Charge $9.99 in USD
24
+ * getFiatPriceConfig(9_990_000n, sellerWallet)
25
+ *
26
+ * // Charge €29.00 in EUR
27
+ * getFiatPriceConfig(29_000_000n, sellerWallet, Currency.EUR)
28
+ * ```
29
+ */
6
30
  export declare const getFiatPriceConfig: (amount: bigint, receiver: Address, currency?: Currency | string) => PlanPriceConfig;
7
31
  export declare const getCryptoPriceConfig: (amount: bigint, receiver: Address, tokenAddress?: Address) => PlanPriceConfig;
8
32
  export declare const getERC20PriceConfig: (amount: bigint, tokenAddress: Address, receiver: Address) => PlanPriceConfig;
@@ -1 +1 @@
1
- {"version":3,"file":"plans.d.ts","sourceRoot":"","sources":["../src/plans.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,EACP,QAAQ,EAER,iBAAiB,EACjB,eAAe,EACf,kBAAkB,EACnB,MAAM,mBAAmB,CAAA;AAI1B,eAAO,MAAM,gBAAgB,SAAU,CAAA;AACvC,eAAO,MAAM,iBAAiB,UAAW,CAAA;AACzC,eAAO,MAAM,kBAAkB,WAAa,CAAA;AAC5C,eAAO,MAAM,iBAAiB,YAAc,CAAA;AAE5C,eAAO,MAAM,kBAAkB,GAC7B,QAAQ,MAAM,EACd,UAAU,OAAO,EACjB,WAAU,QAAQ,GAAG,MAAqB,KACzC,eAcF,CAAA;AAED,eAAO,MAAM,oBAAoB,GAC/B,QAAQ,MAAM,EACd,UAAU,OAAO,EACjB,eAAc,OAAqB,KAClC,eAaF,CAAA;AAED,eAAO,MAAM,mBAAmB,GAC9B,QAAQ,MAAM,EACd,cAAc,OAAO,EACrB,UAAU,OAAO,KAChB,eAEF,CAAA;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,kBAAkB,GAC7B,QAAQ,MAAM,EACd,UAAU,OAAO,EACjB,cAAa,OAA4B,KACxC,eAKF,CAAA;AAED,eAAO,MAAM,kBAAkB,QAAO,eAWrC,CAAA;AAED,eAAO,MAAM,yBAAyB,GAAI,QAAQ,MAAM,EAAE,UAAU,OAAO,KAAG,eAE7E,CAAA;AAED,eAAO,MAAM,0BAA0B,GAAI,gBAAgB,MAAM,KAAG,iBAUnE,CAAA;AAED,eAAO,MAAM,6BAA6B,QAAO,iBAEhD,CAAA;AAED,eAAO,MAAM,qBAAqB,GAChC,gBAAgB,MAAM,EACtB,0BAAsB,KACrB,iBAUF,CAAA;AAED,eAAO,MAAM,uBAAuB,GAClC,gBAAgB,MAAM,EACtB,6BAAyB,EACzB,6BAAyB,KACxB,iBAUF,CAAA;AAED,eAAO,MAAM,iBAAiB,GAC5B,eAAe,iBAAiB,EAChC,gBAAgB,kBAAkB,KACjC,iBAKF,CAAA;AAED,eAAO,MAAM,gBAAgB,GAC3B,eAAe,iBAAiB,EAChC,uBAAoB,KACnB,iBAKF,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,GACnC,QAAQ,MAAM,EACd,UAAU,OAAO,EACjB,eAAc,OAAqB,EACnC,kBAAkB,OAAO,KACxB,eAoBF,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,0BAA0B,QAAO,iBAU7C,CAAA"}
1
+ {"version":3,"file":"plans.d.ts","sourceRoot":"","sources":["../src/plans.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,EACP,QAAQ,EAER,iBAAiB,EACjB,eAAe,EACf,kBAAkB,EACnB,MAAM,mBAAmB,CAAA;AAI1B,eAAO,MAAM,gBAAgB,SAAU,CAAA;AACvC,eAAO,MAAM,iBAAiB,UAAW,CAAA;AACzC,eAAO,MAAM,kBAAkB,WAAa,CAAA;AAC5C,eAAO,MAAM,iBAAiB,YAAc,CAAA;AAE5C;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,kBAAkB,GAC7B,QAAQ,MAAM,EACd,UAAU,OAAO,EACjB,WAAU,QAAQ,GAAG,MAAqB,KACzC,eAcF,CAAA;AAED,eAAO,MAAM,oBAAoB,GAC/B,QAAQ,MAAM,EACd,UAAU,OAAO,EACjB,eAAc,OAAqB,KAClC,eAaF,CAAA;AAED,eAAO,MAAM,mBAAmB,GAC9B,QAAQ,MAAM,EACd,cAAc,OAAO,EACrB,UAAU,OAAO,KAChB,eAEF,CAAA;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,kBAAkB,GAC7B,QAAQ,MAAM,EACd,UAAU,OAAO,EACjB,cAAa,OAA4B,KACxC,eAKF,CAAA;AAED,eAAO,MAAM,kBAAkB,QAAO,eAWrC,CAAA;AAED,eAAO,MAAM,yBAAyB,GAAI,QAAQ,MAAM,EAAE,UAAU,OAAO,KAAG,eAE7E,CAAA;AAED,eAAO,MAAM,0BAA0B,GAAI,gBAAgB,MAAM,KAAG,iBAUnE,CAAA;AAED,eAAO,MAAM,6BAA6B,QAAO,iBAEhD,CAAA;AAED,eAAO,MAAM,qBAAqB,GAChC,gBAAgB,MAAM,EACtB,0BAAsB,KACrB,iBAUF,CAAA;AAED,eAAO,MAAM,uBAAuB,GAClC,gBAAgB,MAAM,EACtB,6BAAyB,EACzB,6BAAyB,KACxB,iBAUF,CAAA;AAED,eAAO,MAAM,iBAAiB,GAC5B,eAAe,iBAAiB,EAChC,gBAAgB,kBAAkB,KACjC,iBAKF,CAAA;AAED,eAAO,MAAM,gBAAgB,GAC3B,eAAe,iBAAiB,EAChC,uBAAoB,KACnB,iBAKF,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,GACnC,QAAQ,MAAM,EACd,UAAU,OAAO,EACjB,eAAc,OAAqB,EACnC,kBAAkB,OAAO,KACxB,eAoBF,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,0BAA0B,QAAO,iBAU7C,CAAA"}
package/dist/plans.js CHANGED
@@ -5,6 +5,30 @@ export const ONE_DAY_DURATION = 86400n; // 24 * 60 * 60 seconds
5
5
  export const ONE_WEEK_DURATION = 604800n; // 7 * 24 * 60 * 60 seconds
6
6
  export const ONE_MONTH_DURATION = 2629746n; // (365.25 days/year ÷ 12 months/year) × 24 × 60 × 60 ≈ 2,629,746 seconds
7
7
  export const ONE_YEAR_DURATION = 31557600n; // 365.25 * 24 * 60 * 60 seconds
8
+ /**
9
+ * Builds a price configuration for fiat-denominated plans (Stripe / Braintree).
10
+ *
11
+ * `amount` is in **6-decimal units** (the USDC convention used across the
12
+ * Nevermined protocol — NOT cents). To charge $2.00, pass `2_000_000n`;
13
+ * `200n` would be read as $0.0002 and rejected by the backend.
14
+ *
15
+ * Minimum charge enforced server-side is **$1.00** (`1_000_000n`) — fiat
16
+ * processor fixed fees make smaller amounts uneconomic. Passing below the
17
+ * minimum surfaces as `BCK.PROTOCOL.0047`.
18
+ *
19
+ * @param amount - Amount in 6-decimal units (e.g. `2_000_000n` for $2.00)
20
+ * @param receiver - Wallet address that will receive the settled funds
21
+ * @param currency - ISO currency code (defaults to `USD`)
22
+ *
23
+ * @example
24
+ * ```ts
25
+ * // Charge $9.99 in USD
26
+ * getFiatPriceConfig(9_990_000n, sellerWallet)
27
+ *
28
+ * // Charge €29.00 in EUR
29
+ * getFiatPriceConfig(29_000_000n, sellerWallet, Currency.EUR)
30
+ * ```
31
+ */
8
32
  export const getFiatPriceConfig = (amount, receiver, currency = Currency.USD) => {
9
33
  if (!isEthereumAddress(receiver))
10
34
  throw new Error(`Receiver address ${receiver} is not a valid Ethereum address`);