{"version":3,"sources":["../../../../src/exact/server/scheme.ts"],"sourcesContent":["import { convertToTokenAmount, numberToDecimalString, parseMoneyString } from \"@x402/core/utils\";\nimport { DEFAULT_TOKEN_DECIMALS } from \"../../constants\";\nimport { getUsdcAddress } from \"../../utils\";\nimport type {\n  AssetAmount,\n  Network,\n  PaymentRequirements,\n  Price,\n  SchemeNetworkServer,\n  MoneyParser,\n} from \"@x402/core/types\";\n\n/**\n * Stellar server implementation for the Exact payment scheme.\n */\nexport class ExactStellarScheme implements SchemeNetworkServer {\n  readonly scheme = \"exact\";\n  private moneyParsers: MoneyParser[] = [];\n\n  /**\n   * Register a custom money parser in the parser chain.\n   * Multiple parsers can be registered - they will be tried in registration order.\n   * Each parser receives a decimal amount (e.g., 1.50 for $1.50).\n   * If a parser returns null, the next parser in the chain will be tried.\n   * The default parser is always the final fallback.\n   *\n   * @param parser - Custom function to convert amount to AssetAmount (or null to skip)\n   * @returns The service instance for chaining\n   */\n  registerMoneyParser(parser: MoneyParser): ExactStellarScheme {\n    this.moneyParsers.push(parser);\n    return this;\n  }\n\n  /**\n   * Parses a price into `AssetAmount`.\n   * If price is already an `AssetAmount`, returns it directly.\n   * If price is `Money` (string | number), parses to decimal and tries custom parsers.\n   * If no custom parsers return a valid `AssetAmount`, falls back to default conversion, assuming USDC token contract.\n   *\n   * @param price - The `Price` to parse\n   * @param network - The `Network` to use\n   * @returns Promise that resolves to the parsed `AssetAmount`\n   */\n  async parsePrice(price: Price, network: Network): Promise<AssetAmount> {\n    // Attempt 1: if already an AssetAmount, return it directly\n    if (typeof price === \"object\" && price !== null && \"amount\" in price) {\n      if (!price.asset) {\n        throw new Error(`Asset address must be specified for AssetAmount on network ${network}`);\n      }\n      return {\n        amount: price.amount,\n        asset: price.asset,\n        extra: price.extra || {},\n      };\n    }\n\n    // Parse Money to decimal number\n    const amount = this.parseMoneyToDecimal(price);\n\n    // Attempt 2: try each custom money parser in order\n    for (const parser of this.moneyParsers) {\n      const result = await parser(amount, network);\n      if (result !== null) {\n        return result;\n      }\n    }\n\n    // Attempt 3: fallback to default conversion, assuming USDC token contract.\n    return this.defaultMoneyConversion(amount, network);\n  }\n\n  /**\n   * Build payment requirements for this scheme/network combination\n   *\n   * @param paymentRequirements - The base payment requirements\n   * @param supportedKind - The supported kind configuration\n   * @param supportedKind.x402Version - The x402 protocol version\n   * @param supportedKind.scheme - The payment scheme\n   * @param supportedKind.network - The network identifier\n   * @param supportedKind.extra - Extra metadata including `areFeesSponsored` from facilitator\n   * @param extensionKeys - Extension keys supported by the facilitator\n   * @returns Enhanced payment requirements with `areFeesSponsored` in extra\n   */\n  enhancePaymentRequirements(\n    paymentRequirements: PaymentRequirements,\n    supportedKind: {\n      x402Version: number;\n      scheme: string;\n      network: Network;\n      extra?: Record<string, unknown>;\n    },\n    extensionKeys: string[],\n  ): Promise<PaymentRequirements> {\n    // Mark unused parameters to satisfy linter\n    void extensionKeys;\n\n    // Add `areFeesSponsored` from supportedKind.extra to payment requirements\n    // The facilitator provides `areFeesSponsored` which clients use to determine if fees are sponsored\n    const areFeesSponsored = supportedKind.extra?.areFeesSponsored;\n    return Promise.resolve({\n      ...paymentRequirements,\n      extra: {\n        ...paymentRequirements.extra,\n        ...(typeof areFeesSponsored === \"boolean\" && { areFeesSponsored }),\n      },\n    });\n  }\n\n  /**\n   * Parse Money (string | number) to a decimal number.\n   * Handles formats like \"$1.50\", \"1.50\", 1.50, etc.\n   *\n   * @param money - The money value to parse\n   * @returns Decimal number\n   */\n  private parseMoneyToDecimal(money: string | number): number {\n    if (typeof money === \"number\") {\n      return money;\n    }\n\n    return parseMoneyString(money);\n  }\n\n  /**\n   * Default money conversion implementation.\n   * Converts decimal amount to USDC on the specified network.\n   *\n   * @param amount - The decimal amount (e.g., 1.50)\n   * @param network - The network to use\n   * @returns The parsed asset amount in USDC\n   */\n  private defaultMoneyConversion(amount: number, network: Network): AssetAmount {\n    // Convert decimal amount to token amount (USDC on Stellar has 7 decimals)\n    const tokenAmount = convertToTokenAmount(numberToDecimalString(amount), DEFAULT_TOKEN_DECIMALS);\n\n    return {\n      amount: tokenAmount,\n      asset: getUsdcAddress(network),\n      extra: {},\n    };\n  }\n}\n"],"mappings":";;;;;;AAAA,SAAS,sBAAsB,uBAAuB,wBAAwB;AAevE,IAAM,qBAAN,MAAwD;AAAA,EAAxD;AACL,SAAS,SAAS;AAClB,SAAQ,eAA8B,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYvC,oBAAoB,QAAyC;AAC3D,SAAK,aAAa,KAAK,MAAM;AAC7B,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,WAAW,OAAc,SAAwC;AAErE,QAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,YAAY,OAAO;AACpE,UAAI,CAAC,MAAM,OAAO;AAChB,cAAM,IAAI,MAAM,8DAA8D,OAAO,EAAE;AAAA,MACzF;AACA,aAAO;AAAA,QACL,QAAQ,MAAM;AAAA,QACd,OAAO,MAAM;AAAA,QACb,OAAO,MAAM,SAAS,CAAC;AAAA,MACzB;AAAA,IACF;AAGA,UAAM,SAAS,KAAK,oBAAoB,KAAK;AAG7C,eAAW,UAAU,KAAK,cAAc;AACtC,YAAM,SAAS,MAAM,OAAO,QAAQ,OAAO;AAC3C,UAAI,WAAW,MAAM;AACnB,eAAO;AAAA,MACT;AAAA,IACF;AAGA,WAAO,KAAK,uBAAuB,QAAQ,OAAO;AAAA,EACpD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,2BACE,qBACA,eAMA,eAC8B;AAE9B,SAAK;AAIL,UAAM,mBAAmB,cAAc,OAAO;AAC9C,WAAO,QAAQ,QAAQ;AAAA,MACrB,GAAG;AAAA,MACH,OAAO;AAAA,QACL,GAAG,oBAAoB;AAAA,QACvB,GAAI,OAAO,qBAAqB,aAAa,EAAE,iBAAiB;AAAA,MAClE;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,oBAAoB,OAAgC;AAC1D,QAAI,OAAO,UAAU,UAAU;AAC7B,aAAO;AAAA,IACT;AAEA,WAAO,iBAAiB,KAAK;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUQ,uBAAuB,QAAgB,SAA+B;AAE5E,UAAM,cAAc,qBAAqB,sBAAsB,MAAM,GAAG,sBAAsB;AAE9F,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,OAAO,eAAe,OAAO;AAAA,MAC7B,OAAO,CAAC;AAAA,IACV;AAAA,EACF;AACF;","names":[]}