moltspay 0.8.14 → 0.9.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.
package/dist/index.mjs CHANGED
@@ -2891,7 +2891,7 @@ function alphabet(letters) {
2891
2891
  };
2892
2892
  }
2893
2893
  // @__NO_SIDE_EFFECTS__
2894
- function join4(separator = "") {
2894
+ function join5(separator = "") {
2895
2895
  astr("join", separator);
2896
2896
  return {
2897
2897
  encode: (from) => {
@@ -3098,10 +3098,10 @@ var init_esm = __esm({
3098
3098
  convertRadix2,
3099
3099
  radix,
3100
3100
  radix2,
3101
- join: join4,
3101
+ join: join5,
3102
3102
  padding
3103
3103
  };
3104
- genBase58 = /* @__NO_SIDE_EFFECTS__ */ (abc) => /* @__PURE__ */ chain(/* @__PURE__ */ radix(58), /* @__PURE__ */ alphabet(abc), /* @__PURE__ */ join4(""));
3104
+ genBase58 = /* @__NO_SIDE_EFFECTS__ */ (abc) => /* @__PURE__ */ chain(/* @__PURE__ */ radix(58), /* @__PURE__ */ alphabet(abc), /* @__PURE__ */ join5(""));
3105
3105
  base58 = /* @__PURE__ */ genBase58("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz");
3106
3106
  createBase58check = (sha2566) => /* @__PURE__ */ chain(checksum(4, (data) => sha2566(sha2566(data))), base58);
3107
3107
  }
@@ -3249,14 +3249,14 @@ var init_esm2 = __esm({
3249
3249
  }
3250
3250
  this.pubHash = hash160(this.pubKey);
3251
3251
  }
3252
- derive(path4) {
3253
- if (!/^[mM]'?/.test(path4)) {
3252
+ derive(path5) {
3253
+ if (!/^[mM]'?/.test(path5)) {
3254
3254
  throw new Error('Path must start with "m" or "M"');
3255
3255
  }
3256
- if (/^[mM]'?$/.test(path4)) {
3256
+ if (/^[mM]'?$/.test(path5)) {
3257
3257
  return this;
3258
3258
  }
3259
- const parts = path4.replace(/^[mM]'?\//, "").split("/");
3259
+ const parts = path5.replace(/^[mM]'?\//, "").split("/");
3260
3260
  let child = this;
3261
3261
  for (const c of parts) {
3262
3262
  const m = /^(\d+)('?)$/.exec(c);
@@ -9617,8 +9617,8 @@ var init_privateKeyToAccount = __esm({
9617
9617
  });
9618
9618
 
9619
9619
  // node_modules/viem/_esm/accounts/hdKeyToAccount.js
9620
- function hdKeyToAccount(hdKey_, { accountIndex = 0, addressIndex = 0, changeIndex = 0, path: path4, ...options } = {}) {
9621
- const hdKey = hdKey_.derive(path4 || `m/44'/60'/${accountIndex}'/${changeIndex}/${addressIndex}`);
9620
+ function hdKeyToAccount(hdKey_, { accountIndex = 0, addressIndex = 0, changeIndex = 0, path: path5, ...options } = {}) {
9621
+ const hdKey = hdKey_.derive(path5 || `m/44'/60'/${accountIndex}'/${changeIndex}/${addressIndex}`);
9622
9622
  const account = privateKeyToAccount(toHex(hdKey.privateKey), options);
9623
9623
  return {
9624
9624
  ...account,
@@ -30330,20 +30330,478 @@ init_esm_shims();
30330
30330
 
30331
30331
  // src/server/index.ts
30332
30332
  init_esm_shims();
30333
- import { readFileSync, existsSync } from "fs";
30333
+ import { readFileSync as readFileSync2, existsSync as existsSync2 } from "fs";
30334
30334
  import { createServer } from "http";
30335
+ import * as path3 from "path";
30336
+
30337
+ // src/facilitators/index.ts
30338
+ init_esm_shims();
30339
+
30340
+ // src/facilitators/interface.ts
30341
+ init_esm_shims();
30342
+ var BaseFacilitator = class {
30343
+ supportsNetwork(network) {
30344
+ return this.supportedNetworks.includes(network);
30345
+ }
30346
+ };
30347
+
30348
+ // src/facilitators/cdp.ts
30349
+ init_esm_shims();
30350
+ import { readFileSync, existsSync } from "fs";
30335
30351
  import * as path2 from "path";
30352
+ var X402_VERSION = 2;
30353
+ var CDP_MAINNET_URL = "https://api.cdp.coinbase.com/platform/v2/x402";
30354
+ var CDP_TESTNET_URL = "https://www.x402.org/facilitator";
30355
+ function loadEnvFile() {
30356
+ const envPaths = [
30357
+ path2.join(process.cwd(), ".env"),
30358
+ path2.join(process.env.HOME || "", ".moltspay", ".env")
30359
+ ];
30360
+ for (const envPath of envPaths) {
30361
+ if (existsSync(envPath)) {
30362
+ try {
30363
+ const content = readFileSync(envPath, "utf-8");
30364
+ for (const line of content.split("\n")) {
30365
+ const trimmed = line.trim();
30366
+ if (!trimmed || trimmed.startsWith("#")) continue;
30367
+ const eqIndex = trimmed.indexOf("=");
30368
+ if (eqIndex === -1) continue;
30369
+ const key = trimmed.slice(0, eqIndex).trim();
30370
+ let value = trimmed.slice(eqIndex + 1).trim();
30371
+ if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
30372
+ value = value.slice(1, -1);
30373
+ }
30374
+ if (!process.env[key]) {
30375
+ process.env[key] = value;
30376
+ }
30377
+ }
30378
+ break;
30379
+ } catch {
30380
+ }
30381
+ }
30382
+ }
30383
+ }
30384
+ var CDPFacilitator = class extends BaseFacilitator {
30385
+ name = "cdp";
30386
+ displayName = "Coinbase CDP";
30387
+ supportedNetworks;
30388
+ endpoint;
30389
+ useMainnet;
30390
+ apiKeyId;
30391
+ apiKeySecret;
30392
+ constructor(config = {}) {
30393
+ super();
30394
+ loadEnvFile();
30395
+ this.useMainnet = config.useMainnet ?? process.env.USE_MAINNET?.toLowerCase() === "true";
30396
+ this.apiKeyId = config.apiKeyId || process.env.CDP_API_KEY_ID;
30397
+ this.apiKeySecret = config.apiKeySecret || process.env.CDP_API_KEY_SECRET;
30398
+ this.endpoint = this.useMainnet ? CDP_MAINNET_URL : CDP_TESTNET_URL;
30399
+ this.supportedNetworks = this.useMainnet ? ["eip155:8453"] : ["eip155:8453", "eip155:84532"];
30400
+ if (this.useMainnet && (!this.apiKeyId || !this.apiKeySecret)) {
30401
+ console.warn("[CDPFacilitator] WARNING: Mainnet mode but missing CDP credentials!");
30402
+ console.warn("[CDPFacilitator] Set CDP_API_KEY_ID and CDP_API_KEY_SECRET");
30403
+ }
30404
+ }
30405
+ /**
30406
+ * Get auth headers for CDP API requests
30407
+ */
30408
+ async getAuthHeaders(method, urlPath, body) {
30409
+ if (!this.useMainnet) {
30410
+ return {};
30411
+ }
30412
+ if (!this.apiKeyId || !this.apiKeySecret) {
30413
+ throw new Error("CDP credentials required for mainnet");
30414
+ }
30415
+ try {
30416
+ const { getAuthHeaders } = await import("@coinbase/cdp-sdk/auth");
30417
+ return await getAuthHeaders({
30418
+ apiKeyId: this.apiKeyId,
30419
+ apiKeySecret: this.apiKeySecret,
30420
+ requestMethod: method,
30421
+ requestHost: "api.cdp.coinbase.com",
30422
+ requestPath: urlPath,
30423
+ requestBody: body
30424
+ });
30425
+ } catch (err) {
30426
+ throw new Error(`Failed to generate CDP auth: ${err.message}`);
30427
+ }
30428
+ }
30429
+ /**
30430
+ * Health check - verify facilitator is reachable
30431
+ */
30432
+ async healthCheck() {
30433
+ const start = Date.now();
30434
+ try {
30435
+ const controller = new AbortController();
30436
+ const timeout = setTimeout(() => controller.abort(), 5e3);
30437
+ const response = await fetch(this.endpoint.replace("/x402", ""), {
30438
+ method: "HEAD",
30439
+ signal: controller.signal
30440
+ }).catch(() => null);
30441
+ clearTimeout(timeout);
30442
+ const latencyMs = Date.now() - start;
30443
+ return {
30444
+ healthy: response !== null,
30445
+ latencyMs
30446
+ };
30447
+ } catch (err) {
30448
+ return {
30449
+ healthy: false,
30450
+ error: err.message,
30451
+ latencyMs: Date.now() - start
30452
+ };
30453
+ }
30454
+ }
30455
+ /**
30456
+ * Verify payment signature with facilitator
30457
+ */
30458
+ async verify(paymentPayload, requirements) {
30459
+ try {
30460
+ const requestBody = {
30461
+ x402Version: X402_VERSION,
30462
+ paymentPayload,
30463
+ paymentRequirements: requirements
30464
+ };
30465
+ const headers = {
30466
+ "Content-Type": "application/json"
30467
+ };
30468
+ if (this.useMainnet) {
30469
+ const authHeaders = await this.getAuthHeaders(
30470
+ "POST",
30471
+ "/platform/v2/x402/verify",
30472
+ requestBody
30473
+ );
30474
+ Object.assign(headers, authHeaders);
30475
+ }
30476
+ const response = await fetch(`${this.endpoint}/verify`, {
30477
+ method: "POST",
30478
+ headers,
30479
+ body: JSON.stringify(requestBody)
30480
+ });
30481
+ const result = await response.json();
30482
+ if (!response.ok || !result.isValid) {
30483
+ return {
30484
+ valid: false,
30485
+ error: result.invalidReason || result.error || "Verification failed",
30486
+ details: result
30487
+ };
30488
+ }
30489
+ return { valid: true, details: result };
30490
+ } catch (err) {
30491
+ return {
30492
+ valid: false,
30493
+ error: `Facilitator error: ${err.message}`
30494
+ };
30495
+ }
30496
+ }
30497
+ /**
30498
+ * Settle payment on-chain via facilitator
30499
+ */
30500
+ async settle(paymentPayload, requirements) {
30501
+ try {
30502
+ const requestBody = {
30503
+ x402Version: X402_VERSION,
30504
+ paymentPayload,
30505
+ paymentRequirements: requirements
30506
+ };
30507
+ const headers = {
30508
+ "Content-Type": "application/json"
30509
+ };
30510
+ if (this.useMainnet) {
30511
+ const authHeaders = await this.getAuthHeaders(
30512
+ "POST",
30513
+ "/platform/v2/x402/settle",
30514
+ requestBody
30515
+ );
30516
+ Object.assign(headers, authHeaders);
30517
+ }
30518
+ const response = await fetch(`${this.endpoint}/settle`, {
30519
+ method: "POST",
30520
+ headers,
30521
+ body: JSON.stringify(requestBody)
30522
+ });
30523
+ const result = await response.json();
30524
+ if (!response.ok || !result.success) {
30525
+ return {
30526
+ success: false,
30527
+ error: result.error || result.errorReason || "Settlement failed"
30528
+ };
30529
+ }
30530
+ return {
30531
+ success: true,
30532
+ transaction: result.transaction,
30533
+ status: result.status || "settled"
30534
+ };
30535
+ } catch (err) {
30536
+ return {
30537
+ success: false,
30538
+ error: `Settlement error: ${err.message}`
30539
+ };
30540
+ }
30541
+ }
30542
+ /**
30543
+ * Get CDP fee information
30544
+ */
30545
+ async getFee() {
30546
+ return {
30547
+ perTx: 1e-3,
30548
+ currency: "USD",
30549
+ freeQuota: 1e3
30550
+ };
30551
+ }
30552
+ /**
30553
+ * Get configuration summary (for logging)
30554
+ */
30555
+ getConfigSummary() {
30556
+ const mode = this.useMainnet ? "mainnet" : "testnet";
30557
+ const hasCredentials = !!(this.apiKeyId && this.apiKeySecret);
30558
+ return `CDP Facilitator (${mode}, credentials: ${hasCredentials ? "yes" : "no"})`;
30559
+ }
30560
+ };
30561
+
30562
+ // src/facilitators/registry.ts
30563
+ init_esm_shims();
30564
+ var FacilitatorRegistry = class {
30565
+ factories = /* @__PURE__ */ new Map();
30566
+ instances = /* @__PURE__ */ new Map();
30567
+ selection;
30568
+ roundRobinIndex = 0;
30569
+ constructor(selection) {
30570
+ this.registerFactory("cdp", (config) => new CDPFacilitator(config));
30571
+ this.selection = selection || { primary: "cdp", strategy: "failover" };
30572
+ }
30573
+ /**
30574
+ * Register a new facilitator factory
30575
+ */
30576
+ registerFactory(name, factory) {
30577
+ this.factories.set(name, factory);
30578
+ }
30579
+ /**
30580
+ * Get or create a facilitator instance
30581
+ */
30582
+ get(name, config) {
30583
+ if (this.instances.has(name)) {
30584
+ return this.instances.get(name);
30585
+ }
30586
+ const factory = this.factories.get(name);
30587
+ if (!factory) {
30588
+ throw new Error(`Unknown facilitator: ${name}. Available: ${Array.from(this.factories.keys()).join(", ")}`);
30589
+ }
30590
+ const mergedConfig = {
30591
+ ...this.selection.config?.[name],
30592
+ ...config
30593
+ };
30594
+ const instance = factory(mergedConfig);
30595
+ this.instances.set(name, instance);
30596
+ return instance;
30597
+ }
30598
+ /**
30599
+ * Get all configured facilitator names
30600
+ */
30601
+ getConfiguredNames() {
30602
+ const names = [this.selection.primary];
30603
+ if (this.selection.fallback) {
30604
+ names.push(...this.selection.fallback);
30605
+ }
30606
+ return names;
30607
+ }
30608
+ /**
30609
+ * Get list of facilitators based on selection strategy
30610
+ */
30611
+ async getOrderedFacilitators(network) {
30612
+ const names = this.getConfiguredNames();
30613
+ const facilitators = [];
30614
+ for (const name of names) {
30615
+ try {
30616
+ const f = this.get(name);
30617
+ if (f.supportsNetwork(network)) {
30618
+ facilitators.push(f);
30619
+ }
30620
+ } catch (err) {
30621
+ console.warn(`[Registry] Failed to get facilitator ${name}:`, err);
30622
+ }
30623
+ }
30624
+ if (facilitators.length === 0) {
30625
+ throw new Error(`No facilitators available for network: ${network}`);
30626
+ }
30627
+ switch (this.selection.strategy) {
30628
+ case "random":
30629
+ return this.shuffle(facilitators);
30630
+ case "roundrobin":
30631
+ this.roundRobinIndex = (this.roundRobinIndex + 1) % facilitators.length;
30632
+ return [
30633
+ ...facilitators.slice(this.roundRobinIndex),
30634
+ ...facilitators.slice(0, this.roundRobinIndex)
30635
+ ];
30636
+ case "cheapest":
30637
+ return this.sortByCheapest(facilitators);
30638
+ case "fastest":
30639
+ return this.sortByFastest(facilitators);
30640
+ case "failover":
30641
+ default:
30642
+ return facilitators;
30643
+ }
30644
+ }
30645
+ shuffle(array) {
30646
+ const result = [...array];
30647
+ for (let i = result.length - 1; i > 0; i--) {
30648
+ const j = Math.floor(Math.random() * (i + 1));
30649
+ [result[i], result[j]] = [result[j], result[i]];
30650
+ }
30651
+ return result;
30652
+ }
30653
+ async sortByCheapest(facilitators) {
30654
+ const withFees = await Promise.all(
30655
+ facilitators.map(async (f) => {
30656
+ try {
30657
+ const fee = await f.getFee?.();
30658
+ return { facilitator: f, perTx: fee?.perTx ?? Infinity };
30659
+ } catch {
30660
+ return { facilitator: f, perTx: Infinity };
30661
+ }
30662
+ })
30663
+ );
30664
+ withFees.sort((a, b) => a.perTx - b.perTx);
30665
+ return withFees.map((w) => w.facilitator);
30666
+ }
30667
+ async sortByFastest(facilitators) {
30668
+ const withLatency = await Promise.all(
30669
+ facilitators.map(async (f) => {
30670
+ try {
30671
+ const health = await f.healthCheck();
30672
+ return { facilitator: f, latency: health.latencyMs ?? Infinity };
30673
+ } catch {
30674
+ return { facilitator: f, latency: Infinity };
30675
+ }
30676
+ })
30677
+ );
30678
+ withLatency.sort((a, b) => a.latency - b.latency);
30679
+ return withLatency.map((w) => w.facilitator);
30680
+ }
30681
+ /**
30682
+ * Verify payment using configured facilitators
30683
+ */
30684
+ async verify(paymentPayload, requirements) {
30685
+ const network = paymentPayload.accepted?.network || paymentPayload.network || requirements.network;
30686
+ const facilitators = await this.getOrderedFacilitators(network);
30687
+ let lastError;
30688
+ for (const f of facilitators) {
30689
+ try {
30690
+ console.log(`[Registry] Trying ${f.name} for verify...`);
30691
+ const result = await f.verify(paymentPayload, requirements);
30692
+ if (result.valid) {
30693
+ console.log(`[Registry] ${f.name} verify succeeded`);
30694
+ return { ...result, facilitator: f.name };
30695
+ }
30696
+ lastError = result.error;
30697
+ console.log(`[Registry] ${f.name} verify failed: ${result.error}`);
30698
+ if (this.selection.strategy === "failover" && !this.isTransientError(result.error)) {
30699
+ break;
30700
+ }
30701
+ } catch (err) {
30702
+ lastError = err.message;
30703
+ console.error(`[Registry] ${f.name} error:`, err.message);
30704
+ }
30705
+ }
30706
+ return {
30707
+ valid: false,
30708
+ error: lastError || "All facilitators failed",
30709
+ facilitator: "none"
30710
+ };
30711
+ }
30712
+ /**
30713
+ * Settle payment using configured facilitators
30714
+ */
30715
+ async settle(paymentPayload, requirements) {
30716
+ const network = paymentPayload.accepted?.network || paymentPayload.network || requirements.network;
30717
+ const facilitators = await this.getOrderedFacilitators(network);
30718
+ let lastError;
30719
+ for (const f of facilitators) {
30720
+ try {
30721
+ console.log(`[Registry] Trying ${f.name} for settle...`);
30722
+ const result = await f.settle(paymentPayload, requirements);
30723
+ if (result.success) {
30724
+ console.log(`[Registry] ${f.name} settle succeeded: ${result.transaction}`);
30725
+ return { ...result, facilitator: f.name };
30726
+ }
30727
+ lastError = result.error;
30728
+ console.log(`[Registry] ${f.name} settle failed: ${result.error}`);
30729
+ } catch (err) {
30730
+ lastError = err.message;
30731
+ console.error(`[Registry] ${f.name} error:`, err.message);
30732
+ }
30733
+ }
30734
+ return {
30735
+ success: false,
30736
+ error: lastError || "All facilitators failed",
30737
+ facilitator: "none"
30738
+ };
30739
+ }
30740
+ /**
30741
+ * Check health of all configured facilitators
30742
+ */
30743
+ async healthCheckAll() {
30744
+ const results = {};
30745
+ for (const name of this.getConfiguredNames()) {
30746
+ try {
30747
+ const f = this.get(name);
30748
+ results[name] = await f.healthCheck();
30749
+ } catch (err) {
30750
+ results[name] = { healthy: false, error: err.message };
30751
+ }
30752
+ }
30753
+ return results;
30754
+ }
30755
+ /**
30756
+ * Check if an error is transient (network/server issue) vs permanent (bad request)
30757
+ */
30758
+ isTransientError(error) {
30759
+ if (!error) return true;
30760
+ const transientPatterns = [
30761
+ /timeout/i,
30762
+ /network/i,
30763
+ /connection/i,
30764
+ /ECONNREFUSED/i,
30765
+ /ETIMEDOUT/i,
30766
+ /503/,
30767
+ /502/,
30768
+ /500/
30769
+ ];
30770
+ return transientPatterns.some((p) => p.test(error));
30771
+ }
30772
+ /**
30773
+ * Update selection configuration
30774
+ */
30775
+ setSelection(selection) {
30776
+ this.selection = selection;
30777
+ this.instances.clear();
30778
+ }
30779
+ /**
30780
+ * Get current selection configuration
30781
+ */
30782
+ getSelection() {
30783
+ return { ...this.selection };
30784
+ }
30785
+ };
30786
+ var defaultRegistry = null;
30787
+ function getDefaultRegistry() {
30788
+ if (!defaultRegistry) {
30789
+ defaultRegistry = new FacilitatorRegistry();
30790
+ }
30791
+ return defaultRegistry;
30792
+ }
30793
+ function createRegistry(selection) {
30794
+ return new FacilitatorRegistry(selection);
30795
+ }
30336
30796
 
30337
30797
  // src/server/types.ts
30338
30798
  init_esm_shims();
30339
30799
 
30340
30800
  // src/server/index.ts
30341
- var X402_VERSION = 2;
30801
+ var X402_VERSION2 = 2;
30342
30802
  var PAYMENT_REQUIRED_HEADER = "x-payment-required";
30343
30803
  var PAYMENT_HEADER = "x-payment";
30344
30804
  var PAYMENT_RESPONSE_HEADER = "x-payment-response";
30345
- var FACILITATOR_TESTNET = "https://www.x402.org/facilitator";
30346
- var FACILITATOR_MAINNET = "https://api.cdp.coinbase.com/platform/v2/x402";
30347
30805
  var USDC_ADDRESSES = {
30348
30806
  "eip155:8453": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
30349
30807
  // Base mainnet
@@ -30354,15 +30812,15 @@ var USDC_DOMAIN = {
30354
30812
  name: "USD Coin",
30355
30813
  version: "2"
30356
30814
  };
30357
- function loadEnvFiles() {
30815
+ function loadEnvFile2() {
30358
30816
  const envPaths = [
30359
- path2.join(process.cwd(), ".env"),
30360
- path2.join(process.env.HOME || "", ".moltspay", ".env")
30817
+ path3.join(process.cwd(), ".env"),
30818
+ path3.join(process.env.HOME || "", ".moltspay", ".env")
30361
30819
  ];
30362
30820
  for (const envPath of envPaths) {
30363
- if (existsSync(envPath)) {
30821
+ if (existsSync2(envPath)) {
30364
30822
  try {
30365
- const content = readFileSync(envPath, "utf-8");
30823
+ const content = readFileSync2(envPath, "utf-8");
30366
30824
  for (const line of content.split("\n")) {
30367
30825
  const trimmed = line.trim();
30368
30826
  if (!trimmed || trimmed.startsWith("#")) continue;
@@ -30379,77 +30837,44 @@ function loadEnvFiles() {
30379
30837
  }
30380
30838
  console.log(`[MoltsPay] Loaded config from ${envPath}`);
30381
30839
  break;
30382
- } catch (err) {
30383
- console.warn(`[MoltsPay] Failed to load ${envPath}:`, err);
30840
+ } catch {
30384
30841
  }
30385
30842
  }
30386
30843
  }
30387
30844
  }
30388
- function getCDPConfig() {
30389
- loadEnvFiles();
30390
- return {
30391
- useMainnet: process.env.USE_MAINNET?.toLowerCase() === "true",
30392
- apiKeyId: process.env.CDP_API_KEY_ID,
30393
- apiKeySecret: process.env.CDP_API_KEY_SECRET
30394
- };
30395
- }
30396
- async function getCDPAuthHeaders(method, urlPath, body) {
30397
- const config = getCDPConfig();
30398
- if (!config.apiKeyId || !config.apiKeySecret) {
30399
- throw new Error("CDP_API_KEY_ID and CDP_API_KEY_SECRET required for mainnet");
30400
- }
30401
- try {
30402
- const { getAuthHeaders } = await import("@coinbase/cdp-sdk/auth");
30403
- const headers = await getAuthHeaders({
30404
- apiKeyId: config.apiKeyId,
30405
- apiKeySecret: config.apiKeySecret,
30406
- requestMethod: method,
30407
- requestHost: "api.cdp.coinbase.com",
30408
- requestPath: urlPath,
30409
- requestBody: body
30410
- });
30411
- return headers;
30412
- } catch (err) {
30413
- console.error("[MoltsPay] Failed to generate CDP auth headers:", err.message);
30414
- throw err;
30415
- }
30416
- }
30417
30845
  var MoltsPayServer = class {
30418
30846
  manifest;
30419
30847
  skills = /* @__PURE__ */ new Map();
30420
30848
  options;
30421
- cdpConfig;
30422
- facilitatorUrl;
30849
+ registry;
30423
30850
  networkId;
30851
+ useMainnet;
30424
30852
  constructor(servicesPath, options = {}) {
30425
- this.cdpConfig = getCDPConfig();
30426
- const content = readFileSync(servicesPath, "utf-8");
30853
+ loadEnvFile2();
30854
+ const content = readFileSync2(servicesPath, "utf-8");
30427
30855
  this.manifest = JSON.parse(content);
30428
30856
  this.options = {
30429
30857
  port: options.port || 3e3,
30430
- host: options.host || "0.0.0.0"
30858
+ host: options.host || "0.0.0.0",
30859
+ ...options
30431
30860
  };
30432
- if (this.cdpConfig.useMainnet) {
30433
- if (!this.cdpConfig.apiKeyId || !this.cdpConfig.apiKeySecret) {
30434
- console.warn("[MoltsPay] WARNING: USE_MAINNET=true but CDP keys not set!");
30435
- console.warn("[MoltsPay] Set CDP_API_KEY_ID and CDP_API_KEY_SECRET in ~/.moltspay/.env");
30861
+ this.useMainnet = process.env.USE_MAINNET?.toLowerCase() === "true";
30862
+ this.networkId = this.useMainnet ? "eip155:8453" : "eip155:84532";
30863
+ const facilitatorConfig = options.facilitators || {
30864
+ primary: "cdp",
30865
+ strategy: "failover",
30866
+ config: {
30867
+ cdp: { useMainnet: this.useMainnet }
30436
30868
  }
30437
- this.facilitatorUrl = FACILITATOR_MAINNET;
30438
- this.networkId = "eip155:8453";
30439
- } else {
30440
- this.facilitatorUrl = options.facilitatorUrl || FACILITATOR_TESTNET;
30441
- this.networkId = "eip155:84532";
30442
- }
30443
- const networkName = this.cdpConfig.useMainnet ? "Base mainnet" : "Base Sepolia (testnet)";
30444
- const facilitatorName = this.cdpConfig.useMainnet ? "CDP" : "x402.org";
30869
+ };
30870
+ this.registry = new FacilitatorRegistry(facilitatorConfig);
30871
+ const primaryFacilitator = this.registry.get(facilitatorConfig.primary);
30872
+ const networkName = this.useMainnet ? "Base mainnet" : "Base Sepolia (testnet)";
30445
30873
  console.log(`[MoltsPay] Loaded ${this.manifest.services.length} services from ${servicesPath}`);
30446
30874
  console.log(`[MoltsPay] Provider: ${this.manifest.provider.name}`);
30447
30875
  console.log(`[MoltsPay] Receive wallet: ${this.manifest.provider.wallet}`);
30448
30876
  console.log(`[MoltsPay] Network: ${this.networkId} (${networkName})`);
30449
- console.log(`[MoltsPay] Facilitator: ${facilitatorName} (${this.facilitatorUrl})`);
30450
- if (this.cdpConfig.useMainnet && this.cdpConfig.apiKeyId) {
30451
- console.log(`[MoltsPay] CDP API Key: ${this.cdpConfig.apiKeyId.slice(0, 8)}...`);
30452
- }
30877
+ console.log(`[MoltsPay] Facilitator: ${primaryFacilitator.displayName} (${facilitatorConfig.strategy || "failover"})`);
30453
30878
  console.log(`[MoltsPay] Protocol: x402 (gasless for both client AND server)`);
30454
30879
  }
30455
30880
  /**
@@ -30475,6 +30900,7 @@ var MoltsPayServer = class {
30475
30900
  console.log(`[MoltsPay] Endpoints:`);
30476
30901
  console.log(` GET /services - List available services`);
30477
30902
  console.log(` POST /execute - Execute service (x402 payment)`);
30903
+ console.log(` GET /health - Health check (incl. facilitators)`);
30478
30904
  });
30479
30905
  }
30480
30906
  /**
@@ -30495,6 +30921,9 @@ var MoltsPayServer = class {
30495
30921
  if (url.pathname === "/services" && req.method === "GET") {
30496
30922
  return this.handleGetServices(res);
30497
30923
  }
30924
+ if (url.pathname === "/health" && req.method === "GET") {
30925
+ return await this.handleHealthCheck(res);
30926
+ }
30498
30927
  if (url.pathname === "/execute" && req.method === "POST") {
30499
30928
  const body = await this.readBody(req);
30500
30929
  const paymentHeader = req.headers[PAYMENT_HEADER];
@@ -30520,18 +30949,37 @@ var MoltsPayServer = class {
30520
30949
  output: s.output,
30521
30950
  available: this.skills.has(s.id)
30522
30951
  }));
30952
+ const selection = this.registry.getSelection();
30523
30953
  this.sendJson(res, 200, {
30524
30954
  provider: this.manifest.provider,
30525
30955
  services,
30526
30956
  x402: {
30527
- version: X402_VERSION,
30957
+ version: X402_VERSION2,
30528
30958
  network: this.networkId,
30529
30959
  schemes: ["exact"],
30530
- facilitator: this.cdpConfig.useMainnet ? "cdp" : "x402.org",
30531
- mainnet: this.cdpConfig.useMainnet
30960
+ facilitators: {
30961
+ primary: selection.primary,
30962
+ fallback: selection.fallback,
30963
+ strategy: selection.strategy
30964
+ },
30965
+ mainnet: this.useMainnet
30532
30966
  }
30533
30967
  });
30534
30968
  }
30969
+ /**
30970
+ * GET /health - Health check endpoint
30971
+ */
30972
+ async handleHealthCheck(res) {
30973
+ const facilitatorHealth = await this.registry.healthCheckAll();
30974
+ const allHealthy = Object.values(facilitatorHealth).every((h) => h.healthy);
30975
+ this.sendJson(res, allHealthy ? 200 : 503, {
30976
+ status: allHealthy ? "healthy" : "degraded",
30977
+ network: this.networkId,
30978
+ facilitators: facilitatorHealth,
30979
+ services: this.manifest.services.length,
30980
+ registered: this.skills.size
30981
+ });
30982
+ }
30535
30983
  /**
30536
30984
  * POST /execute - Execute service with x402 payment
30537
30985
  */
@@ -30563,11 +31011,16 @@ var MoltsPayServer = class {
30563
31011
  if (!validation.valid) {
30564
31012
  return this.sendJson(res, 402, { error: validation.error });
30565
31013
  }
30566
- console.log(`[MoltsPay] Verifying payment with facilitator...`);
30567
- const verifyResult = await this.verifyWithFacilitator(payment, skill.config);
31014
+ const requirements = this.buildPaymentRequirements(skill.config);
31015
+ console.log(`[MoltsPay] Verifying payment...`);
31016
+ const verifyResult = await this.registry.verify(payment, requirements);
30568
31017
  if (!verifyResult.valid) {
30569
- return this.sendJson(res, 402, { error: `Payment verification failed: ${verifyResult.error}` });
31018
+ return this.sendJson(res, 402, {
31019
+ error: `Payment verification failed: ${verifyResult.error}`,
31020
+ facilitator: verifyResult.facilitator
31021
+ });
30570
31022
  }
31023
+ console.log(`[MoltsPay] Verified by ${verifyResult.facilitator}`);
30571
31024
  console.log(`[MoltsPay] Executing skill: ${service}`);
30572
31025
  let result;
30573
31026
  try {
@@ -30582,17 +31035,18 @@ var MoltsPayServer = class {
30582
31035
  console.log(`[MoltsPay] Skill succeeded, settling payment...`);
30583
31036
  let settlement = null;
30584
31037
  try {
30585
- settlement = await this.settleWithFacilitator(payment, skill.config);
30586
- console.log(`[MoltsPay] Payment settled: ${settlement.transaction || "pending"}`);
31038
+ settlement = await this.registry.settle(payment, requirements);
31039
+ console.log(`[MoltsPay] Payment settled by ${settlement.facilitator}: ${settlement.transaction || "pending"}`);
30587
31040
  } catch (err) {
30588
31041
  console.error("[MoltsPay] Settlement failed:", err.message);
30589
31042
  }
30590
31043
  const responseHeaders = {};
30591
- if (settlement) {
31044
+ if (settlement?.success) {
30592
31045
  const responsePayload = {
30593
31046
  success: true,
30594
31047
  transaction: settlement.transaction,
30595
- network: payment.network
31048
+ network: payment.network || payment.accepted?.network,
31049
+ facilitator: settlement.facilitator
30596
31050
  };
30597
31051
  responseHeaders[PAYMENT_RESPONSE_HEADER] = Buffer.from(
30598
31052
  JSON.stringify(responsePayload)
@@ -30601,7 +31055,7 @@ var MoltsPayServer = class {
30601
31055
  this.sendJson(res, 200, {
30602
31056
  success: true,
30603
31057
  result,
30604
- payment: settlement ? { transaction: settlement.transaction, status: "settled" } : { status: "pending" }
31058
+ payment: settlement?.success ? { transaction: settlement.transaction, status: "settled", facilitator: settlement.facilitator } : { status: "pending" }
30605
31059
  }, responseHeaders);
30606
31060
  }
30607
31061
  /**
@@ -30610,7 +31064,7 @@ var MoltsPayServer = class {
30610
31064
  sendPaymentRequired(config, res) {
30611
31065
  const requirements = this.buildPaymentRequirements(config);
30612
31066
  const paymentRequired = {
30613
- x402Version: X402_VERSION,
31067
+ x402Version: X402_VERSION2,
30614
31068
  accepts: [requirements],
30615
31069
  resource: {
30616
31070
  url: `/execute?service=${config.id}`,
@@ -30633,7 +31087,7 @@ var MoltsPayServer = class {
30633
31087
  * Basic payment validation
30634
31088
  */
30635
31089
  validatePayment(payment, config) {
30636
- if (payment.x402Version !== X402_VERSION) {
31090
+ if (payment.x402Version !== X402_VERSION2) {
30637
31091
  return { valid: false, error: `Unsupported x402 version: ${payment.x402Version}` };
30638
31092
  }
30639
31093
  const scheme = payment.accepted?.scheme || payment.scheme;
@@ -30647,7 +31101,7 @@ var MoltsPayServer = class {
30647
31101
  return { valid: true };
30648
31102
  }
30649
31103
  /**
30650
- * Build complete payment requirements for facilitator
31104
+ * Build payment requirements for facilitator
30651
31105
  */
30652
31106
  buildPaymentRequirements(config) {
30653
31107
  const amountInUnits = Math.floor(config.price * 1e6).toString();
@@ -30662,77 +31116,6 @@ var MoltsPayServer = class {
30662
31116
  extra: USDC_DOMAIN
30663
31117
  };
30664
31118
  }
30665
- /**
30666
- * Verify payment with facilitator (testnet or CDP)
30667
- */
30668
- async verifyWithFacilitator(payment, config) {
30669
- try {
30670
- const requirements = this.buildPaymentRequirements(config);
30671
- const requestBody = {
30672
- x402Version: X402_VERSION,
30673
- // Required at top level for CDP
30674
- paymentPayload: payment,
30675
- paymentRequirements: requirements
30676
- };
30677
- console.log("[MoltsPay] Verify request:", JSON.stringify(requestBody, null, 2));
30678
- let headers = { "Content-Type": "application/json" };
30679
- if (this.cdpConfig.useMainnet) {
30680
- const authHeaders = await getCDPAuthHeaders(
30681
- "POST",
30682
- "/platform/v2/x402/verify",
30683
- requestBody
30684
- );
30685
- headers = { ...headers, ...authHeaders };
30686
- }
30687
- const response = await fetch(`${this.facilitatorUrl}/verify`, {
30688
- method: "POST",
30689
- headers,
30690
- body: JSON.stringify(requestBody)
30691
- });
30692
- const result = await response.json();
30693
- console.log("[MoltsPay] Verify response:", JSON.stringify(result, null, 2));
30694
- if (!response.ok || !result.isValid) {
30695
- return { valid: false, error: result.invalidReason || result.error || "Verification failed" };
30696
- }
30697
- return { valid: true };
30698
- } catch (err) {
30699
- return { valid: false, error: `Facilitator error: ${err.message}` };
30700
- }
30701
- }
30702
- /**
30703
- * Settle payment with facilitator (execute on-chain transfer)
30704
- */
30705
- async settleWithFacilitator(payment, config) {
30706
- const requirements = this.buildPaymentRequirements(config);
30707
- const requestBody = {
30708
- x402Version: X402_VERSION,
30709
- // Required at top level for CDP
30710
- paymentPayload: payment,
30711
- paymentRequirements: requirements
30712
- };
30713
- let headers = { "Content-Type": "application/json" };
30714
- if (this.cdpConfig.useMainnet) {
30715
- const authHeaders = await getCDPAuthHeaders(
30716
- "POST",
30717
- "/platform/v2/x402/settle",
30718
- requestBody
30719
- );
30720
- headers = { ...headers, ...authHeaders };
30721
- }
30722
- const response = await fetch(`${this.facilitatorUrl}/settle`, {
30723
- method: "POST",
30724
- headers,
30725
- body: JSON.stringify(requestBody)
30726
- });
30727
- const result = await response.json();
30728
- if (!response.ok || !result.success) {
30729
- throw new Error(result.error || result.errorReason || "Settlement failed");
30730
- }
30731
- return {
30732
- transaction: result.transaction,
30733
- status: result.status || "settled"
30734
- };
30735
- }
30736
31119
  async readBody(req) {
30737
31120
  return new Promise((resolve, reject) => {
30738
31121
  let body = "";
@@ -30759,9 +31142,9 @@ var MoltsPayServer = class {
30759
31142
 
30760
31143
  // src/client/index.ts
30761
31144
  init_esm_shims();
30762
- import { existsSync as existsSync2, readFileSync as readFileSync2, writeFileSync, mkdirSync, statSync, chmodSync } from "fs";
31145
+ import { existsSync as existsSync3, readFileSync as readFileSync3, writeFileSync, mkdirSync, statSync, chmodSync } from "fs";
30763
31146
  import { homedir } from "os";
30764
- import { join as join2 } from "path";
31147
+ import { join as join3 } from "path";
30765
31148
  import { Wallet, ethers } from "ethers";
30766
31149
 
30767
31150
  // src/chains/index.ts
@@ -30846,7 +31229,7 @@ var ERC20_ABI = [
30846
31229
  init_esm_shims();
30847
31230
 
30848
31231
  // src/client/index.ts
30849
- var X402_VERSION2 = 2;
31232
+ var X402_VERSION3 = 2;
30850
31233
  var PAYMENT_REQUIRED_HEADER2 = "x-payment-required";
30851
31234
  var PAYMENT_HEADER2 = "x-payment";
30852
31235
  var DEFAULT_CONFIG = {
@@ -30864,7 +31247,7 @@ var MoltsPayClient = class {
30864
31247
  todaySpending = 0;
30865
31248
  lastSpendingReset = 0;
30866
31249
  constructor(options = {}) {
30867
- this.configDir = options.configDir || join2(homedir(), ".moltspay");
31250
+ this.configDir = options.configDir || join3(homedir(), ".moltspay");
30868
31251
  this.config = this.loadConfig();
30869
31252
  this.walletData = this.loadWallet();
30870
31253
  this.loadSpending();
@@ -30972,7 +31355,7 @@ var MoltsPayClient = class {
30972
31355
  }
30973
31356
  const authorization = await this.signEIP3009(payTo, amount, chain2);
30974
31357
  const payload = {
30975
- x402Version: X402_VERSION2,
31358
+ x402Version: X402_VERSION3,
30976
31359
  payload: authorization,
30977
31360
  // v2 requires 'accepted' field with the requirements being fulfilled
30978
31361
  accepted: {
@@ -31069,26 +31452,26 @@ var MoltsPayClient = class {
31069
31452
  }
31070
31453
  // --- Config & Wallet Management ---
31071
31454
  loadConfig() {
31072
- const configPath = join2(this.configDir, "config.json");
31073
- if (existsSync2(configPath)) {
31074
- const content = readFileSync2(configPath, "utf-8");
31455
+ const configPath = join3(this.configDir, "config.json");
31456
+ if (existsSync3(configPath)) {
31457
+ const content = readFileSync3(configPath, "utf-8");
31075
31458
  return { ...DEFAULT_CONFIG, ...JSON.parse(content) };
31076
31459
  }
31077
31460
  return { ...DEFAULT_CONFIG };
31078
31461
  }
31079
31462
  saveConfig() {
31080
31463
  mkdirSync(this.configDir, { recursive: true });
31081
- const configPath = join2(this.configDir, "config.json");
31464
+ const configPath = join3(this.configDir, "config.json");
31082
31465
  writeFileSync(configPath, JSON.stringify(this.config, null, 2));
31083
31466
  }
31084
31467
  /**
31085
31468
  * Load spending data from disk
31086
31469
  */
31087
31470
  loadSpending() {
31088
- const spendingPath = join2(this.configDir, "spending.json");
31089
- if (existsSync2(spendingPath)) {
31471
+ const spendingPath = join3(this.configDir, "spending.json");
31472
+ if (existsSync3(spendingPath)) {
31090
31473
  try {
31091
- const data = JSON.parse(readFileSync2(spendingPath, "utf-8"));
31474
+ const data = JSON.parse(readFileSync3(spendingPath, "utf-8"));
31092
31475
  const today = (/* @__PURE__ */ new Date()).setHours(0, 0, 0, 0);
31093
31476
  if (data.date && data.date === today) {
31094
31477
  this.todaySpending = data.amount || 0;
@@ -31108,7 +31491,7 @@ var MoltsPayClient = class {
31108
31491
  */
31109
31492
  saveSpending() {
31110
31493
  mkdirSync(this.configDir, { recursive: true });
31111
- const spendingPath = join2(this.configDir, "spending.json");
31494
+ const spendingPath = join3(this.configDir, "spending.json");
31112
31495
  const data = {
31113
31496
  date: this.lastSpendingReset || (/* @__PURE__ */ new Date()).setHours(0, 0, 0, 0),
31114
31497
  amount: this.todaySpending,
@@ -31117,8 +31500,8 @@ var MoltsPayClient = class {
31117
31500
  writeFileSync(spendingPath, JSON.stringify(data, null, 2));
31118
31501
  }
31119
31502
  loadWallet() {
31120
- const walletPath = join2(this.configDir, "wallet.json");
31121
- if (existsSync2(walletPath)) {
31503
+ const walletPath = join3(this.configDir, "wallet.json");
31504
+ if (existsSync3(walletPath)) {
31122
31505
  try {
31123
31506
  const stats = statSync(walletPath);
31124
31507
  const mode = stats.mode & 511;
@@ -31129,7 +31512,7 @@ var MoltsPayClient = class {
31129
31512
  }
31130
31513
  } catch (err) {
31131
31514
  }
31132
- const content = readFileSync2(walletPath, "utf-8");
31515
+ const content = readFileSync3(walletPath, "utf-8");
31133
31516
  return JSON.parse(content);
31134
31517
  }
31135
31518
  return null;
@@ -31145,7 +31528,7 @@ var MoltsPayClient = class {
31145
31528
  privateKey: wallet.privateKey,
31146
31529
  createdAt: Date.now()
31147
31530
  };
31148
- const walletPath = join2(configDir, "wallet.json");
31531
+ const walletPath = join3(configDir, "wallet.json");
31149
31532
  writeFileSync(walletPath, JSON.stringify(walletData, null, 2), { mode: 384 });
31150
31533
  const config = {
31151
31534
  chain: options.chain,
@@ -31154,7 +31537,7 @@ var MoltsPayClient = class {
31154
31537
  maxPerDay: options.maxPerDay
31155
31538
  }
31156
31539
  };
31157
- const configPath = join2(configDir, "config.json");
31540
+ const configPath = join3(configDir, "config.json");
31158
31541
  writeFileSync(configPath, JSON.stringify(config, null, 2));
31159
31542
  return { address: wallet.address, configDir };
31160
31543
  }
@@ -31193,10 +31576,10 @@ import { ethers as ethers2 } from "ethers";
31193
31576
  // src/wallet/createWallet.ts
31194
31577
  init_esm_shims();
31195
31578
  import { ethers as ethers3 } from "ethers";
31196
- import { writeFileSync as writeFileSync2, readFileSync as readFileSync3, existsSync as existsSync3, mkdirSync as mkdirSync2 } from "fs";
31197
- import { join as join3, dirname } from "path";
31579
+ import { writeFileSync as writeFileSync2, readFileSync as readFileSync4, existsSync as existsSync4, mkdirSync as mkdirSync2 } from "fs";
31580
+ import { join as join4, dirname } from "path";
31198
31581
  import { createCipheriv, createDecipheriv, randomBytes, scryptSync } from "crypto";
31199
- var DEFAULT_STORAGE_DIR = join3(process.env.HOME || "~", ".moltspay");
31582
+ var DEFAULT_STORAGE_DIR = join4(process.env.HOME || "~", ".moltspay");
31200
31583
  var DEFAULT_STORAGE_FILE = "wallet.json";
31201
31584
  function encryptPrivateKey(privateKey, password) {
31202
31585
  const salt = randomBytes(16);
@@ -31219,10 +31602,10 @@ function decryptPrivateKey(encrypted, password, iv, salt) {
31219
31602
  return decrypted;
31220
31603
  }
31221
31604
  function createWallet(options = {}) {
31222
- const storagePath = options.storagePath || join3(DEFAULT_STORAGE_DIR, DEFAULT_STORAGE_FILE);
31223
- if (existsSync3(storagePath) && !options.overwrite) {
31605
+ const storagePath = options.storagePath || join4(DEFAULT_STORAGE_DIR, DEFAULT_STORAGE_FILE);
31606
+ if (existsSync4(storagePath) && !options.overwrite) {
31224
31607
  try {
31225
- const existing = JSON.parse(readFileSync3(storagePath, "utf8"));
31608
+ const existing = JSON.parse(readFileSync4(storagePath, "utf8"));
31226
31609
  return {
31227
31610
  success: true,
31228
31611
  address: existing.address,
@@ -31254,7 +31637,7 @@ function createWallet(options = {}) {
31254
31637
  walletData.privateKey = wallet.privateKey;
31255
31638
  }
31256
31639
  const dir = dirname(storagePath);
31257
- if (!existsSync3(dir)) {
31640
+ if (!existsSync4(dir)) {
31258
31641
  mkdirSync2(dir, { recursive: true });
31259
31642
  }
31260
31643
  writeFileSync2(storagePath, JSON.stringify(walletData, null, 2), { mode: 384 });
@@ -31272,12 +31655,12 @@ function createWallet(options = {}) {
31272
31655
  }
31273
31656
  }
31274
31657
  function loadWallet(options = {}) {
31275
- const storagePath = options.storagePath || join3(DEFAULT_STORAGE_DIR, DEFAULT_STORAGE_FILE);
31276
- if (!existsSync3(storagePath)) {
31658
+ const storagePath = options.storagePath || join4(DEFAULT_STORAGE_DIR, DEFAULT_STORAGE_FILE);
31659
+ if (!existsSync4(storagePath)) {
31277
31660
  return { success: false, error: "Wallet not found. Run createWallet() first." };
31278
31661
  }
31279
31662
  try {
31280
- const data = JSON.parse(readFileSync3(storagePath, "utf8"));
31663
+ const data = JSON.parse(readFileSync4(storagePath, "utf8"));
31281
31664
  if (data.encrypted) {
31282
31665
  if (!options.password) {
31283
31666
  return { success: false, error: "Wallet is encrypted. Password required." };
@@ -31292,20 +31675,20 @@ function loadWallet(options = {}) {
31292
31675
  }
31293
31676
  }
31294
31677
  function getWalletAddress(storagePath) {
31295
- const path4 = storagePath || join3(DEFAULT_STORAGE_DIR, DEFAULT_STORAGE_FILE);
31296
- if (!existsSync3(path4)) {
31678
+ const path5 = storagePath || join4(DEFAULT_STORAGE_DIR, DEFAULT_STORAGE_FILE);
31679
+ if (!existsSync4(path5)) {
31297
31680
  return null;
31298
31681
  }
31299
31682
  try {
31300
- const data = JSON.parse(readFileSync3(path4, "utf8"));
31683
+ const data = JSON.parse(readFileSync4(path5, "utf8"));
31301
31684
  return data.address;
31302
31685
  } catch {
31303
31686
  return null;
31304
31687
  }
31305
31688
  }
31306
31689
  function walletExists(storagePath) {
31307
- const path4 = storagePath || join3(DEFAULT_STORAGE_DIR, DEFAULT_STORAGE_FILE);
31308
- return existsSync3(path4);
31690
+ const path5 = storagePath || join4(DEFAULT_STORAGE_DIR, DEFAULT_STORAGE_FILE);
31691
+ return existsSync4(path5);
31309
31692
  }
31310
31693
 
31311
31694
  // src/verify/index.ts
@@ -31448,8 +31831,8 @@ async function waitForTransaction(txHash, chain2 = "base", confirmations = 1, ti
31448
31831
  // src/cdp/index.ts
31449
31832
  init_esm_shims();
31450
31833
  import * as fs from "fs";
31451
- import * as path3 from "path";
31452
- var DEFAULT_STORAGE_DIR2 = path3.join(process.env.HOME || ".", ".moltspay");
31834
+ import * as path4 from "path";
31835
+ var DEFAULT_STORAGE_DIR2 = path4.join(process.env.HOME || ".", ".moltspay");
31453
31836
  var CDP_CONFIG_FILE = "cdp-wallet.json";
31454
31837
  function isCDPAvailable() {
31455
31838
  try {
@@ -31471,7 +31854,7 @@ function getCDPCredentials(config) {
31471
31854
  async function initCDPWallet(config = {}) {
31472
31855
  const storageDir = config.storageDir || DEFAULT_STORAGE_DIR2;
31473
31856
  const chain2 = config.chain || "base";
31474
- const storagePath = path3.join(storageDir, CDP_CONFIG_FILE);
31857
+ const storagePath = path4.join(storageDir, CDP_CONFIG_FILE);
31475
31858
  if (fs.existsSync(storagePath)) {
31476
31859
  try {
31477
31860
  const data = JSON.parse(fs.readFileSync(storagePath, "utf-8"));
@@ -31533,7 +31916,7 @@ async function initCDPWallet(config = {}) {
31533
31916
  }
31534
31917
  function loadCDPWallet(config = {}) {
31535
31918
  const storageDir = config.storageDir || DEFAULT_STORAGE_DIR2;
31536
- const storagePath = path3.join(storageDir, CDP_CONFIG_FILE);
31919
+ const storagePath = path4.join(storageDir, CDP_CONFIG_FILE);
31537
31920
  if (!fs.existsSync(storagePath)) {
31538
31921
  return null;
31539
31922
  }
@@ -31651,15 +32034,20 @@ var CDPWallet = class {
31651
32034
  }
31652
32035
  };
31653
32036
  export {
32037
+ BaseFacilitator,
32038
+ CDPFacilitator,
31654
32039
  CDPWallet,
31655
32040
  CHAINS,
31656
32041
  ERC20_ABI,
32042
+ FacilitatorRegistry,
31657
32043
  MoltsPayClient,
31658
32044
  MoltsPayServer,
32045
+ createRegistry,
31659
32046
  createWallet,
31660
32047
  getCDPWalletAddress,
31661
32048
  getChain,
31662
32049
  getChainById,
32050
+ getDefaultRegistry,
31663
32051
  getTransactionStatus,
31664
32052
  getWalletAddress,
31665
32053
  initCDPWallet,