{"version":3,"sources":["../../src/constants.ts","../../src/utils.ts"],"sourcesContent":["/**\n * CAIP-2 network identifiers for Stellar (V2)\n */\nexport const STELLAR_PUBNET_CAIP2 = \"stellar:pubnet\";\nexport const STELLAR_TESTNET_CAIP2 = \"stellar:testnet\";\nexport const STELLAR_WILDCARD_CAIP2 = \"stellar:*\";\n\n/**\n * Default testnet RPC URL\n */\nexport const DEFAULT_TESTNET_RPC_URL = \"https://soroban-testnet.stellar.org\";\n\n/**\n * Default Horizon API URLs\n */\nexport const DEFAULT_TESTNET_HORIZON_URL = \"https://horizon-testnet.stellar.org\";\nexport const DEFAULT_PUBNET_HORIZON_URL = \"https://horizon.stellar.org\";\n\n/**\n * Stellar validation regex for destination and asset addresses\n */\nexport const STELLAR_DESTINATION_ADDRESS_REGEX = /^(?:[GC][ABCD][A-Z2-7]{54}|M[ABCD][A-Z2-7]{67})$/; // Stellar address: G-account (56 chars), C-account (56 chars), or M-account (69 chars, muxed)\nexport const STELLAR_ASSET_ADDRESS_REGEX = /^(?:[C][ABCD][A-Z2-7]{54})$/; // Stellar token contract address: C-account (56 chars)\n\n/**\n * USDC contract addresses (default stablecoin)\n */\nexport const USDC_PUBNET_ADDRESS = \"CCW67TSZV3SSS2HXMBQ5JFGCKJNXKZM7UQUWUZPUTHXSTZLEO7SJMI75\";\nexport const USDC_TESTNET_ADDRESS = \"CBIELTK6YBZJU5UP2WWQEUCYKLPU6AUNZ2BQ4WWFEIE3USCIHMXQDAMA\";\n\nexport const STELLAR_NETWORK_TO_PASSPHRASE: ReadonlyMap<string, string> = new Map([\n  [STELLAR_PUBNET_CAIP2, \"Public Global Stellar Network ; September 2015\"],\n  [STELLAR_TESTNET_CAIP2, \"Test SDF Network ; September 2015\"],\n]);\n\n/**\n * Default token decimals\n */\nexport const DEFAULT_TOKEN_DECIMALS = 7;\n","import { Horizon, rpc } from \"@stellar/stellar-sdk\";\nimport {\n  convertToTokenAmount as coreConvertToTokenAmount,\n  numberToDecimalString,\n} from \"@x402/core/utils\";\nimport {\n  DEFAULT_PUBNET_HORIZON_URL,\n  DEFAULT_TESTNET_HORIZON_URL,\n  DEFAULT_TESTNET_RPC_URL,\n  DEFAULT_TOKEN_DECIMALS,\n  STELLAR_ASSET_ADDRESS_REGEX,\n  STELLAR_DESTINATION_ADDRESS_REGEX,\n  STELLAR_NETWORK_TO_PASSPHRASE,\n  STELLAR_PUBNET_CAIP2,\n  STELLAR_TESTNET_CAIP2,\n  USDC_PUBNET_ADDRESS,\n  USDC_TESTNET_ADDRESS,\n} from \"./constants\";\nimport type { Network } from \"@x402/core/types\";\n\nexport const DEFAULT_ESTIMATED_LEDGER_SECONDS = 5;\nconst HORIZON_LEDGERS_SAMPLE_SIZE = 20;\n\n/**\n * Configuration for RPC client connections\n */\nexport interface RpcConfig {\n  /** Custom RPC URL to use instead of defaults */\n  url?: string;\n}\n\n/**\n * Checks if a network is a Stellar network\n *\n * @param network - The CAIP-2 network identifier\n * @returns `true` if the network is a Stellar network, `false` otherwise\n */\nexport function isStellarNetwork(network: Network): boolean {\n  return STELLAR_NETWORK_TO_PASSPHRASE.has(network);\n}\n\n/**\n * Validates a Stellar destination address (G-account, C-account, or M-account)\n *\n * @param address - Stellar destination address to validate\n * @returns `true` if the address is valid, `false` otherwise\n */\nexport function validateStellarDestinationAddress(address: string): boolean {\n  return STELLAR_DESTINATION_ADDRESS_REGEX.test(address);\n}\n\n/**\n * Validates a Stellar asset/contract address (C-account only)\n *\n * @param address - Stellar asset address to validate\n * @returns `true` if the address is valid, `false` otherwise\n */\nexport function validateStellarAssetAddress(address: string): boolean {\n  return STELLAR_ASSET_ADDRESS_REGEX.test(address);\n}\n\n/**\n * Gets the network passphrase for a given Stellar network\n *\n * @param network - The CAIP-2 network identifier\n * @returns The network passphrase string\n * @throws {Error} If the network is not a known Stellar network\n */\nexport function getNetworkPassphrase(network: Network): string {\n  const networkPassphrase = STELLAR_NETWORK_TO_PASSPHRASE.get(network);\n  if (!networkPassphrase) {\n    throw new Error(`Unknown Stellar network: ${network}`);\n  }\n  return networkPassphrase;\n}\n\n/**\n * Gets the RPC URL for a given Stellar network\n *\n * @param network - The CAIP-2 network identifier\n * @param rpcConfig - Optional RPC configuration with custom URL\n * @returns The RPC URL string\n * @throws {Error} If the network is unknown or mainnet RPC URL is not provided\n */\nexport function getRpcUrl(network: Network, rpcConfig?: RpcConfig): string {\n  const customRpcUrl = rpcConfig?.url;\n  switch (network) {\n    case STELLAR_TESTNET_CAIP2:\n      return customRpcUrl || DEFAULT_TESTNET_RPC_URL;\n    case STELLAR_PUBNET_CAIP2:\n      if (!customRpcUrl) {\n        throw new Error(\n          \"Stellar mainnet requires a non-empty rpcUrl. For a list of RPC providers, see https://developers.stellar.org/docs/data/apis/rpc/providers#publicly-accessible-apis\",\n        );\n      }\n      return customRpcUrl;\n    default:\n      throw new Error(`Unknown Stellar network: ${network}`);\n  }\n}\n\n/**\n * Creates a Soroban RPC client for the given network\n *\n * @param network - The CAIP-2 network identifier\n * @param rpcConfig - Optional RPC configuration with custom URL\n * @returns A configured Soroban RPC Server instance\n * @throws {Error} If the network is not a valid Stellar network\n */\nexport function getRpcClient(network: Network, rpcConfig?: RpcConfig): rpc.Server {\n  const rpcUrl = getRpcUrl(network, rpcConfig);\n  return new rpc.Server(rpcUrl, {\n    allowHttp: network === STELLAR_TESTNET_CAIP2, // Allow HTTP for testnet\n  });\n}\n\n/**\n * Creates a Horizon SDK client for the given network.\n *\n * @param network - The CAIP-2 network identifier\n * @returns A configured Horizon.Server instance\n * @throws {Error} If the network is unknown\n */\nexport function getHorizonClient(network: Network): Horizon.Server {\n  switch (network) {\n    case STELLAR_TESTNET_CAIP2:\n      return new Horizon.Server(DEFAULT_TESTNET_HORIZON_URL);\n    case STELLAR_PUBNET_CAIP2:\n      return new Horizon.Server(DEFAULT_PUBNET_HORIZON_URL);\n    default:\n      throw new Error(`Unknown Stellar network: ${network}`);\n  }\n}\n\n/**\n * Estimates ledger close time by fetching the most recent ledgers from Horizon.\n *\n * Uses the Horizon SDK's ledger query builder which is significantly faster\n * than the Soroban RPC `getLedgers` method for this purpose.\n *\n * @param network - The CAIP-2 network identifier\n * @returns Estimated seconds per ledger, or DEFAULT_ESTIMATED_LEDGER_SECONDS (5) on error\n */\nexport async function getEstimatedLedgerCloseTimeSeconds(network: Network): Promise<number> {\n  try {\n    const horizon = getHorizonClient(network);\n    const page = await horizon.ledgers().limit(HORIZON_LEDGERS_SAMPLE_SIZE).order(\"desc\").call();\n    const records = page.records;\n    if (!records || records.length < 2) return DEFAULT_ESTIMATED_LEDGER_SECONDS;\n\n    const newestTs = new Date(records[0].closed_at).getTime() / 1000;\n    const oldestTs = new Date(records[records.length - 1].closed_at).getTime() / 1000;\n    const intervals = records.length - 1;\n    return Math.ceil((newestTs - oldestTs) / intervals);\n  } catch {\n    return DEFAULT_ESTIMATED_LEDGER_SECONDS;\n  }\n}\n\n/**\n * Gets the default USDC contract address for a network\n *\n * @param network - The CAIP-2 network identifier\n * @returns The USDC contract address for the network\n * @throws {Error} If the network doesn't have a configured USDC address\n */\nexport function getUsdcAddress(network: Network): string {\n  switch (network) {\n    case STELLAR_PUBNET_CAIP2:\n      return USDC_PUBNET_ADDRESS;\n    case STELLAR_TESTNET_CAIP2:\n      return USDC_TESTNET_ADDRESS;\n    default:\n      throw new Error(`No USDC address configured for network: ${network}`);\n  }\n}\n\nexport { numberToDecimalString };\n\n/**\n * Converts a decimal amount to token smallest units.\n * Wraps the core utility with Stellar's default of 7 decimal places.\n *\n * @param decimalAmount - The decimal amount as a string\n * @param decimals - Number of decimal places for the token (default: 7 for Stellar USDC)\n * @returns The amount in smallest units as a string\n */\nexport function convertToTokenAmount(\n  decimalAmount: string,\n  decimals: number = DEFAULT_TOKEN_DECIMALS,\n): string {\n  return coreConvertToTokenAmount(decimalAmount, decimals);\n}\n"],"mappings":";AAGO,IAAM,uBAAuB;AAC7B,IAAM,wBAAwB;AAC9B,IAAM,yBAAyB;AAK/B,IAAM,0BAA0B;AAKhC,IAAM,8BAA8B;AACpC,IAAM,6BAA6B;AAKnC,IAAM,oCAAoC;AAC1C,IAAM,8BAA8B;AAKpC,IAAM,sBAAsB;AAC5B,IAAM,uBAAuB;AAE7B,IAAM,gCAA6D,oBAAI,IAAI;AAAA,EAChF,CAAC,sBAAsB,gDAAgD;AAAA,EACvE,CAAC,uBAAuB,mCAAmC;AAC7D,CAAC;AAKM,IAAM,yBAAyB;;;ACtCtC,SAAS,SAAS,WAAW;AAC7B;AAAA,EACE,wBAAwB;AAAA,EACxB;AAAA,OACK;AAgBA,IAAM,mCAAmC;AAChD,IAAM,8BAA8B;AAgB7B,SAAS,iBAAiB,SAA2B;AAC1D,SAAO,8BAA8B,IAAI,OAAO;AAClD;AAQO,SAAS,kCAAkC,SAA0B;AAC1E,SAAO,kCAAkC,KAAK,OAAO;AACvD;AAQO,SAAS,4BAA4B,SAA0B;AACpE,SAAO,4BAA4B,KAAK,OAAO;AACjD;AASO,SAAS,qBAAqB,SAA0B;AAC7D,QAAM,oBAAoB,8BAA8B,IAAI,OAAO;AACnE,MAAI,CAAC,mBAAmB;AACtB,UAAM,IAAI,MAAM,4BAA4B,OAAO,EAAE;AAAA,EACvD;AACA,SAAO;AACT;AAUO,SAAS,UAAU,SAAkB,WAA+B;AACzE,QAAM,eAAe,WAAW;AAChC,UAAQ,SAAS;AAAA,IACf,KAAK;AACH,aAAO,gBAAgB;AAAA,IACzB,KAAK;AACH,UAAI,CAAC,cAAc;AACjB,cAAM,IAAI;AAAA,UACR;AAAA,QACF;AAAA,MACF;AACA,aAAO;AAAA,IACT;AACE,YAAM,IAAI,MAAM,4BAA4B,OAAO,EAAE;AAAA,EACzD;AACF;AAUO,SAAS,aAAa,SAAkB,WAAmC;AAChF,QAAM,SAAS,UAAU,SAAS,SAAS;AAC3C,SAAO,IAAI,IAAI,OAAO,QAAQ;AAAA,IAC5B,WAAW,YAAY;AAAA;AAAA,EACzB,CAAC;AACH;AASO,SAAS,iBAAiB,SAAkC;AACjE,UAAQ,SAAS;AAAA,IACf,KAAK;AACH,aAAO,IAAI,QAAQ,OAAO,2BAA2B;AAAA,IACvD,KAAK;AACH,aAAO,IAAI,QAAQ,OAAO,0BAA0B;AAAA,IACtD;AACE,YAAM,IAAI,MAAM,4BAA4B,OAAO,EAAE;AAAA,EACzD;AACF;AAWA,eAAsB,mCAAmC,SAAmC;AAC1F,MAAI;AACF,UAAM,UAAU,iBAAiB,OAAO;AACxC,UAAM,OAAO,MAAM,QAAQ,QAAQ,EAAE,MAAM,2BAA2B,EAAE,MAAM,MAAM,EAAE,KAAK;AAC3F,UAAM,UAAU,KAAK;AACrB,QAAI,CAAC,WAAW,QAAQ,SAAS,EAAG,QAAO;AAE3C,UAAM,WAAW,IAAI,KAAK,QAAQ,CAAC,EAAE,SAAS,EAAE,QAAQ,IAAI;AAC5D,UAAM,WAAW,IAAI,KAAK,QAAQ,QAAQ,SAAS,CAAC,EAAE,SAAS,EAAE,QAAQ,IAAI;AAC7E,UAAM,YAAY,QAAQ,SAAS;AACnC,WAAO,KAAK,MAAM,WAAW,YAAY,SAAS;AAAA,EACpD,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AASO,SAAS,eAAe,SAA0B;AACvD,UAAQ,SAAS;AAAA,IACf,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT;AACE,YAAM,IAAI,MAAM,2CAA2C,OAAO,EAAE;AAAA,EACxE;AACF;AAYO,SAAS,qBACd,eACA,WAAmB,wBACX;AACR,SAAO,yBAAyB,eAAe,QAAQ;AACzD;","names":[]}