moltspay 0.8.1 → 0.8.2

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 join3(separator = "") {
2894
+ function join4(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: join3,
3101
+ join: join4,
3102
3102
  padding
3103
3103
  };
3104
- genBase58 = /* @__NO_SIDE_EFFECTS__ */ (abc) => /* @__PURE__ */ chain(/* @__PURE__ */ radix(58), /* @__PURE__ */ alphabet(abc), /* @__PURE__ */ join3(""));
3104
+ genBase58 = /* @__NO_SIDE_EFFECTS__ */ (abc) => /* @__PURE__ */ chain(/* @__PURE__ */ radix(58), /* @__PURE__ */ alphabet(abc), /* @__PURE__ */ join4(""));
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(path3) {
3253
- if (!/^[mM]'?/.test(path3)) {
3252
+ derive(path4) {
3253
+ if (!/^[mM]'?/.test(path4)) {
3254
3254
  throw new Error('Path must start with "m" or "M"');
3255
3255
  }
3256
- if (/^[mM]'?$/.test(path3)) {
3256
+ if (/^[mM]'?$/.test(path4)) {
3257
3257
  return this;
3258
3258
  }
3259
- const parts = path3.replace(/^[mM]'?\//, "").split("/");
3259
+ const parts = path4.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: path3, ...options } = {}) {
9621
- const hdKey = hdKey_.derive(path3 || `m/44'/60'/${accountIndex}'/${changeIndex}/${addressIndex}`);
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}`);
9622
9622
  const account = privateKeyToAccount(toHex(hdKey.privateKey), options);
9623
9623
  return {
9624
9624
  ...account,
@@ -30330,86 +30330,9 @@ init_esm_shims();
30330
30330
 
30331
30331
  // src/server/index.ts
30332
30332
  init_esm_shims();
30333
- import { readFileSync } from "fs";
30333
+ import { readFileSync, existsSync } from "fs";
30334
30334
  import { createServer } from "http";
30335
-
30336
- // src/chains/index.ts
30337
- init_esm_shims();
30338
- var CHAINS = {
30339
- // ============ Mainnet ============
30340
- base: {
30341
- name: "Base",
30342
- chainId: 8453,
30343
- rpc: "https://mainnet.base.org",
30344
- usdc: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
30345
- explorer: "https://basescan.org/address/",
30346
- explorerTx: "https://basescan.org/tx/",
30347
- avgBlockTime: 2
30348
- },
30349
- polygon: {
30350
- name: "Polygon",
30351
- chainId: 137,
30352
- rpc: "https://polygon-rpc.com",
30353
- usdc: "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",
30354
- explorer: "https://polygonscan.com/address/",
30355
- explorerTx: "https://polygonscan.com/tx/",
30356
- avgBlockTime: 2
30357
- },
30358
- ethereum: {
30359
- name: "Ethereum",
30360
- chainId: 1,
30361
- rpc: "https://eth.llamarpc.com",
30362
- usdc: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
30363
- explorer: "https://etherscan.io/address/",
30364
- explorerTx: "https://etherscan.io/tx/",
30365
- avgBlockTime: 12
30366
- },
30367
- // ============ Testnet ============
30368
- base_sepolia: {
30369
- name: "Base Sepolia",
30370
- chainId: 84532,
30371
- rpc: "https://sepolia.base.org",
30372
- usdc: "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
30373
- explorer: "https://sepolia.basescan.org/address/",
30374
- explorerTx: "https://sepolia.basescan.org/tx/",
30375
- avgBlockTime: 2
30376
- },
30377
- sepolia: {
30378
- name: "Sepolia",
30379
- chainId: 11155111,
30380
- rpc: "https://rpc.sepolia.org",
30381
- usdc: "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238",
30382
- explorer: "https://sepolia.etherscan.io/address/",
30383
- explorerTx: "https://sepolia.etherscan.io/tx/",
30384
- avgBlockTime: 12
30385
- }
30386
- };
30387
- function getChain(name) {
30388
- const config = CHAINS[name];
30389
- if (!config) {
30390
- throw new Error(`Unsupported chain: ${name}. Supported: ${Object.keys(CHAINS).join(", ")}`);
30391
- }
30392
- return config;
30393
- }
30394
- function listChains() {
30395
- return Object.keys(CHAINS);
30396
- }
30397
- function getChainById(chainId) {
30398
- return Object.values(CHAINS).find((c) => c.chainId === chainId);
30399
- }
30400
- var ERC20_ABI = [
30401
- "function balanceOf(address owner) view returns (uint256)",
30402
- "function transfer(address to, uint256 amount) returns (bool)",
30403
- "function approve(address spender, uint256 amount) returns (bool)",
30404
- "function allowance(address owner, address spender) view returns (uint256)",
30405
- "function decimals() view returns (uint8)",
30406
- "function symbol() view returns (string)",
30407
- "function name() view returns (string)",
30408
- "function nonces(address owner) view returns (uint256)",
30409
- "function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s)",
30410
- "event Transfer(address indexed from, address indexed to, uint256 value)",
30411
- "event Approval(address indexed owner, address indexed spender, uint256 value)"
30412
- ];
30335
+ import * as path2 from "path";
30413
30336
 
30414
30337
  // src/server/types.ts
30415
30338
  init_esm_shims();
@@ -30419,24 +30342,90 @@ var X402_VERSION = 2;
30419
30342
  var PAYMENT_REQUIRED_HEADER = "x-payment-required";
30420
30343
  var PAYMENT_HEADER = "x-payment";
30421
30344
  var PAYMENT_RESPONSE_HEADER = "x-payment-response";
30422
- var DEFAULT_FACILITATOR_URL = "https://x402.org/facilitator";
30345
+ var FACILITATOR_TESTNET = "https://www.x402.org/facilitator";
30346
+ var FACILITATOR_MAINNET = "https://api.cdp.coinbase.com/platform/v2/x402";
30347
+ function loadEnvFiles() {
30348
+ try {
30349
+ const dotenv = __require("dotenv");
30350
+ const envPaths = [
30351
+ path2.join(process.cwd(), ".env"),
30352
+ path2.join(process.env.HOME || "", ".moltspay", ".env")
30353
+ ];
30354
+ for (const envPath of envPaths) {
30355
+ if (existsSync(envPath)) {
30356
+ dotenv.config({ path: envPath });
30357
+ console.log(`[MoltsPay] Loaded config from ${envPath}`);
30358
+ break;
30359
+ }
30360
+ }
30361
+ } catch {
30362
+ }
30363
+ }
30364
+ function getCDPConfig() {
30365
+ loadEnvFiles();
30366
+ return {
30367
+ useMainnet: process.env.USE_MAINNET?.toLowerCase() === "true",
30368
+ apiKeyId: process.env.CDP_API_KEY_ID,
30369
+ apiKeySecret: process.env.CDP_API_KEY_SECRET
30370
+ };
30371
+ }
30372
+ async function getCDPAuthHeaders(method, urlPath, body) {
30373
+ const config = getCDPConfig();
30374
+ if (!config.apiKeyId || !config.apiKeySecret) {
30375
+ throw new Error("CDP_API_KEY_ID and CDP_API_KEY_SECRET required for mainnet");
30376
+ }
30377
+ try {
30378
+ const { getAuthHeaders } = await import("@coinbase/cdp-sdk/auth");
30379
+ const headers = await getAuthHeaders({
30380
+ apiKeyId: config.apiKeyId,
30381
+ apiKeySecret: config.apiKeySecret,
30382
+ requestMethod: method,
30383
+ requestHost: "api.cdp.coinbase.com",
30384
+ requestPath: urlPath,
30385
+ requestBody: body
30386
+ });
30387
+ return headers;
30388
+ } catch (err) {
30389
+ console.error("[MoltsPay] Failed to generate CDP auth headers:", err.message);
30390
+ throw err;
30391
+ }
30392
+ }
30423
30393
  var MoltsPayServer = class {
30424
30394
  manifest;
30425
30395
  skills = /* @__PURE__ */ new Map();
30426
30396
  options;
30397
+ cdpConfig;
30427
30398
  facilitatorUrl;
30399
+ networkId;
30428
30400
  constructor(servicesPath, options = {}) {
30401
+ this.cdpConfig = getCDPConfig();
30429
30402
  const content = readFileSync(servicesPath, "utf-8");
30430
30403
  this.manifest = JSON.parse(content);
30431
30404
  this.options = {
30432
30405
  port: options.port || 3e3,
30433
30406
  host: options.host || "0.0.0.0"
30434
30407
  };
30435
- this.facilitatorUrl = options.facilitatorUrl || DEFAULT_FACILITATOR_URL;
30408
+ if (this.cdpConfig.useMainnet) {
30409
+ if (!this.cdpConfig.apiKeyId || !this.cdpConfig.apiKeySecret) {
30410
+ console.warn("[MoltsPay] WARNING: USE_MAINNET=true but CDP keys not set!");
30411
+ console.warn("[MoltsPay] Set CDP_API_KEY_ID and CDP_API_KEY_SECRET in ~/.moltspay/.env");
30412
+ }
30413
+ this.facilitatorUrl = FACILITATOR_MAINNET;
30414
+ this.networkId = "eip155:8453";
30415
+ } else {
30416
+ this.facilitatorUrl = options.facilitatorUrl || FACILITATOR_TESTNET;
30417
+ this.networkId = "eip155:84532";
30418
+ }
30419
+ const networkName = this.cdpConfig.useMainnet ? "Base mainnet" : "Base Sepolia (testnet)";
30420
+ const facilitatorName = this.cdpConfig.useMainnet ? "CDP" : "x402.org";
30436
30421
  console.log(`[MoltsPay] Loaded ${this.manifest.services.length} services from ${servicesPath}`);
30437
30422
  console.log(`[MoltsPay] Provider: ${this.manifest.provider.name}`);
30438
30423
  console.log(`[MoltsPay] Receive wallet: ${this.manifest.provider.wallet}`);
30439
- console.log(`[MoltsPay] Facilitator: ${this.facilitatorUrl}`);
30424
+ console.log(`[MoltsPay] Network: ${this.networkId} (${networkName})`);
30425
+ console.log(`[MoltsPay] Facilitator: ${facilitatorName} (${this.facilitatorUrl})`);
30426
+ if (this.cdpConfig.useMainnet && this.cdpConfig.apiKeyId) {
30427
+ console.log(`[MoltsPay] CDP API Key: ${this.cdpConfig.apiKeyId.slice(0, 8)}...`);
30428
+ }
30440
30429
  console.log(`[MoltsPay] Protocol: x402 (gasless for both client AND server)`);
30441
30430
  }
30442
30431
  /**
@@ -30497,7 +30486,6 @@ var MoltsPayServer = class {
30497
30486
  * GET /services - List available services
30498
30487
  */
30499
30488
  handleGetServices(res) {
30500
- const chain2 = getChain(this.manifest.provider.chain);
30501
30489
  const services = this.manifest.services.map((s) => ({
30502
30490
  id: s.id,
30503
30491
  name: s.name,
@@ -30513,16 +30501,15 @@ var MoltsPayServer = class {
30513
30501
  services,
30514
30502
  x402: {
30515
30503
  version: X402_VERSION,
30516
- network: `eip155:${chain2.chainId}`,
30504
+ network: this.networkId,
30517
30505
  schemes: ["exact"],
30518
- facilitator: this.facilitatorUrl
30506
+ facilitator: this.cdpConfig.useMainnet ? "cdp" : "x402.org",
30507
+ mainnet: this.cdpConfig.useMainnet
30519
30508
  }
30520
30509
  });
30521
30510
  }
30522
30511
  /**
30523
30512
  * POST /execute - Execute service with x402 payment
30524
- * Body: { service: string, params: object }
30525
- * Header: X-Payment (optional - if missing, returns 402)
30526
30513
  */
30527
30514
  async handleExecute(body, paymentHeader, res) {
30528
30515
  const { service, params } = body;
@@ -30597,16 +30584,17 @@ var MoltsPayServer = class {
30597
30584
  * Return 402 with x402 payment requirements
30598
30585
  */
30599
30586
  sendPaymentRequired(config, res) {
30600
- const chain2 = getChain(this.manifest.provider.chain);
30601
30587
  const amountInUnits = Math.floor(config.price * 1e6).toString();
30602
30588
  const requirements = [{
30603
30589
  scheme: "exact",
30604
- network: `eip155:${chain2.chainId}`,
30590
+ network: this.networkId,
30605
30591
  maxAmountRequired: amountInUnits,
30606
30592
  resource: this.manifest.provider.wallet,
30607
30593
  description: `${config.name} - $${config.price} ${config.currency}`,
30608
- // Include facilitator info for client
30609
- extra: JSON.stringify({ facilitator: this.facilitatorUrl })
30594
+ extra: JSON.stringify({
30595
+ facilitator: this.cdpConfig.useMainnet ? "cdp" : "x402.org",
30596
+ mainnet: this.cdpConfig.useMainnet
30597
+ })
30610
30598
  }];
30611
30599
  const encoded = Buffer.from(JSON.stringify(requirements)).toString("base64");
30612
30600
  res.writeHead(402, {
@@ -30620,7 +30608,7 @@ var MoltsPayServer = class {
30620
30608
  }, null, 2));
30621
30609
  }
30622
30610
  /**
30623
- * Basic payment validation (before calling facilitator)
30611
+ * Basic payment validation
30624
30612
  */
30625
30613
  validatePayment(payment, config) {
30626
30614
  if (payment.x402Version !== X402_VERSION) {
@@ -30629,37 +30617,45 @@ var MoltsPayServer = class {
30629
30617
  if (payment.scheme !== "exact") {
30630
30618
  return { valid: false, error: `Unsupported scheme: ${payment.scheme}` };
30631
30619
  }
30632
- const chain2 = getChain(this.manifest.provider.chain);
30633
- const expectedNetwork = `eip155:${chain2.chainId}`;
30634
- if (payment.network !== expectedNetwork) {
30635
- return { valid: false, error: `Network mismatch: expected ${expectedNetwork}` };
30620
+ if (payment.network !== this.networkId) {
30621
+ return { valid: false, error: `Network mismatch: expected ${this.networkId}, got ${payment.network}` };
30636
30622
  }
30637
30623
  return { valid: true };
30638
30624
  }
30639
30625
  /**
30640
- * Verify payment with facilitator
30626
+ * Verify payment with facilitator (testnet or CDP)
30641
30627
  */
30642
30628
  async verifyWithFacilitator(payment, config) {
30643
30629
  try {
30644
- const chain2 = getChain(this.manifest.provider.chain);
30645
30630
  const amountInUnits = Math.floor(config.price * 1e6).toString();
30646
30631
  const requirements = {
30647
30632
  scheme: "exact",
30648
- network: `eip155:${chain2.chainId}`,
30633
+ network: this.networkId,
30649
30634
  maxAmountRequired: amountInUnits,
30650
- resource: this.manifest.provider.wallet
30635
+ resource: this.manifest.provider.wallet,
30636
+ payTo: this.manifest.provider.wallet
30637
+ };
30638
+ const requestBody = {
30639
+ paymentPayload: payment,
30640
+ paymentRequirements: requirements
30651
30641
  };
30642
+ let headers = { "Content-Type": "application/json" };
30643
+ if (this.cdpConfig.useMainnet) {
30644
+ const authHeaders = await getCDPAuthHeaders(
30645
+ "POST",
30646
+ "/platform/v2/x402/verify",
30647
+ requestBody
30648
+ );
30649
+ headers = { ...headers, ...authHeaders };
30650
+ }
30652
30651
  const response = await fetch(`${this.facilitatorUrl}/verify`, {
30653
30652
  method: "POST",
30654
- headers: { "Content-Type": "application/json" },
30655
- body: JSON.stringify({
30656
- paymentPayload: payment,
30657
- paymentRequirements: requirements
30658
- })
30653
+ headers,
30654
+ body: JSON.stringify(requestBody)
30659
30655
  });
30660
30656
  const result = await response.json();
30661
30657
  if (!response.ok || !result.isValid) {
30662
- return { valid: false, error: result.invalidReason || "Verification failed" };
30658
+ return { valid: false, error: result.invalidReason || result.error || "Verification failed" };
30663
30659
  }
30664
30660
  return { valid: true };
30665
30661
  } catch (err) {
@@ -30670,25 +30666,35 @@ var MoltsPayServer = class {
30670
30666
  * Settle payment with facilitator (execute on-chain transfer)
30671
30667
  */
30672
30668
  async settleWithFacilitator(payment, config) {
30673
- const chain2 = getChain(this.manifest.provider.chain);
30674
30669
  const amountInUnits = Math.floor(config.price * 1e6).toString();
30675
30670
  const requirements = {
30676
30671
  scheme: "exact",
30677
- network: `eip155:${chain2.chainId}`,
30672
+ network: this.networkId,
30678
30673
  maxAmountRequired: amountInUnits,
30679
- resource: this.manifest.provider.wallet
30674
+ resource: this.manifest.provider.wallet,
30675
+ payTo: this.manifest.provider.wallet
30680
30676
  };
30677
+ const requestBody = {
30678
+ paymentPayload: payment,
30679
+ paymentRequirements: requirements
30680
+ };
30681
+ let headers = { "Content-Type": "application/json" };
30682
+ if (this.cdpConfig.useMainnet) {
30683
+ const authHeaders = await getCDPAuthHeaders(
30684
+ "POST",
30685
+ "/platform/v2/x402/settle",
30686
+ requestBody
30687
+ );
30688
+ headers = { ...headers, ...authHeaders };
30689
+ }
30681
30690
  const response = await fetch(`${this.facilitatorUrl}/settle`, {
30682
30691
  method: "POST",
30683
- headers: { "Content-Type": "application/json" },
30684
- body: JSON.stringify({
30685
- paymentPayload: payment,
30686
- paymentRequirements: requirements
30687
- })
30692
+ headers,
30693
+ body: JSON.stringify(requestBody)
30688
30694
  });
30689
30695
  const result = await response.json();
30690
- if (!response.ok) {
30691
- throw new Error(result.error || "Settlement failed");
30696
+ if (!response.ok || !result.success) {
30697
+ throw new Error(result.error || result.errorReason || "Settlement failed");
30692
30698
  }
30693
30699
  return {
30694
30700
  transaction: result.transaction,
@@ -30721,11 +30727,89 @@ var MoltsPayServer = class {
30721
30727
 
30722
30728
  // src/client/index.ts
30723
30729
  init_esm_shims();
30724
- import { existsSync, readFileSync as readFileSync2, writeFileSync, mkdirSync } from "fs";
30730
+ import { existsSync as existsSync2, readFileSync as readFileSync2, writeFileSync, mkdirSync } from "fs";
30725
30731
  import { homedir } from "os";
30726
- import { join } from "path";
30732
+ import { join as join2 } from "path";
30727
30733
  import { Wallet, ethers } from "ethers";
30728
30734
 
30735
+ // src/chains/index.ts
30736
+ init_esm_shims();
30737
+ var CHAINS = {
30738
+ // ============ Mainnet ============
30739
+ base: {
30740
+ name: "Base",
30741
+ chainId: 8453,
30742
+ rpc: "https://mainnet.base.org",
30743
+ usdc: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
30744
+ explorer: "https://basescan.org/address/",
30745
+ explorerTx: "https://basescan.org/tx/",
30746
+ avgBlockTime: 2
30747
+ },
30748
+ polygon: {
30749
+ name: "Polygon",
30750
+ chainId: 137,
30751
+ rpc: "https://polygon-rpc.com",
30752
+ usdc: "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",
30753
+ explorer: "https://polygonscan.com/address/",
30754
+ explorerTx: "https://polygonscan.com/tx/",
30755
+ avgBlockTime: 2
30756
+ },
30757
+ ethereum: {
30758
+ name: "Ethereum",
30759
+ chainId: 1,
30760
+ rpc: "https://eth.llamarpc.com",
30761
+ usdc: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
30762
+ explorer: "https://etherscan.io/address/",
30763
+ explorerTx: "https://etherscan.io/tx/",
30764
+ avgBlockTime: 12
30765
+ },
30766
+ // ============ Testnet ============
30767
+ base_sepolia: {
30768
+ name: "Base Sepolia",
30769
+ chainId: 84532,
30770
+ rpc: "https://sepolia.base.org",
30771
+ usdc: "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
30772
+ explorer: "https://sepolia.basescan.org/address/",
30773
+ explorerTx: "https://sepolia.basescan.org/tx/",
30774
+ avgBlockTime: 2
30775
+ },
30776
+ sepolia: {
30777
+ name: "Sepolia",
30778
+ chainId: 11155111,
30779
+ rpc: "https://rpc.sepolia.org",
30780
+ usdc: "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238",
30781
+ explorer: "https://sepolia.etherscan.io/address/",
30782
+ explorerTx: "https://sepolia.etherscan.io/tx/",
30783
+ avgBlockTime: 12
30784
+ }
30785
+ };
30786
+ function getChain(name) {
30787
+ const config = CHAINS[name];
30788
+ if (!config) {
30789
+ throw new Error(`Unsupported chain: ${name}. Supported: ${Object.keys(CHAINS).join(", ")}`);
30790
+ }
30791
+ return config;
30792
+ }
30793
+ function listChains() {
30794
+ return Object.keys(CHAINS);
30795
+ }
30796
+ function getChainById(chainId) {
30797
+ return Object.values(CHAINS).find((c) => c.chainId === chainId);
30798
+ }
30799
+ var ERC20_ABI = [
30800
+ "function balanceOf(address owner) view returns (uint256)",
30801
+ "function transfer(address to, uint256 amount) returns (bool)",
30802
+ "function approve(address spender, uint256 amount) returns (bool)",
30803
+ "function allowance(address owner, address spender) view returns (uint256)",
30804
+ "function decimals() view returns (uint8)",
30805
+ "function symbol() view returns (string)",
30806
+ "function name() view returns (string)",
30807
+ "function nonces(address owner) view returns (uint256)",
30808
+ "function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s)",
30809
+ "event Transfer(address indexed from, address indexed to, uint256 value)",
30810
+ "event Approval(address indexed owner, address indexed spender, uint256 value)"
30811
+ ];
30812
+
30729
30813
  // src/client/types.ts
30730
30814
  init_esm_shims();
30731
30815
 
@@ -30748,7 +30832,7 @@ var MoltsPayClient = class {
30748
30832
  todaySpending = 0;
30749
30833
  lastSpendingReset = 0;
30750
30834
  constructor(options = {}) {
30751
- this.configDir = options.configDir || join(homedir(), ".moltspay");
30835
+ this.configDir = options.configDir || join2(homedir(), ".moltspay");
30752
30836
  this.config = this.loadConfig();
30753
30837
  this.walletData = this.loadWallet();
30754
30838
  if (this.walletData) {
@@ -30930,8 +31014,8 @@ var MoltsPayClient = class {
30930
31014
  }
30931
31015
  // --- Config & Wallet Management ---
30932
31016
  loadConfig() {
30933
- const configPath = join(this.configDir, "config.json");
30934
- if (existsSync(configPath)) {
31017
+ const configPath = join2(this.configDir, "config.json");
31018
+ if (existsSync2(configPath)) {
30935
31019
  const content = readFileSync2(configPath, "utf-8");
30936
31020
  return { ...DEFAULT_CONFIG, ...JSON.parse(content) };
30937
31021
  }
@@ -30939,12 +31023,12 @@ var MoltsPayClient = class {
30939
31023
  }
30940
31024
  saveConfig() {
30941
31025
  mkdirSync(this.configDir, { recursive: true });
30942
- const configPath = join(this.configDir, "config.json");
31026
+ const configPath = join2(this.configDir, "config.json");
30943
31027
  writeFileSync(configPath, JSON.stringify(this.config, null, 2));
30944
31028
  }
30945
31029
  loadWallet() {
30946
- const walletPath = join(this.configDir, "wallet.json");
30947
- if (existsSync(walletPath)) {
31030
+ const walletPath = join2(this.configDir, "wallet.json");
31031
+ if (existsSync2(walletPath)) {
30948
31032
  const content = readFileSync2(walletPath, "utf-8");
30949
31033
  return JSON.parse(content);
30950
31034
  }
@@ -30961,7 +31045,7 @@ var MoltsPayClient = class {
30961
31045
  privateKey: wallet.privateKey,
30962
31046
  createdAt: Date.now()
30963
31047
  };
30964
- const walletPath = join(configDir, "wallet.json");
31048
+ const walletPath = join2(configDir, "wallet.json");
30965
31049
  writeFileSync(walletPath, JSON.stringify(walletData, null, 2));
30966
31050
  const config = {
30967
31051
  chain: options.chain,
@@ -30970,7 +31054,7 @@ var MoltsPayClient = class {
30970
31054
  maxPerDay: options.maxPerDay
30971
31055
  }
30972
31056
  };
30973
- const configPath = join(configDir, "config.json");
31057
+ const configPath = join2(configDir, "config.json");
30974
31058
  writeFileSync(configPath, JSON.stringify(config, null, 2));
30975
31059
  return { address: wallet.address, configDir };
30976
31060
  }
@@ -31009,10 +31093,10 @@ import { ethers as ethers2 } from "ethers";
31009
31093
  // src/wallet/createWallet.ts
31010
31094
  init_esm_shims();
31011
31095
  import { ethers as ethers3 } from "ethers";
31012
- import { writeFileSync as writeFileSync2, readFileSync as readFileSync3, existsSync as existsSync2, mkdirSync as mkdirSync2 } from "fs";
31013
- import { join as join2, dirname } from "path";
31096
+ import { writeFileSync as writeFileSync2, readFileSync as readFileSync3, existsSync as existsSync3, mkdirSync as mkdirSync2 } from "fs";
31097
+ import { join as join3, dirname } from "path";
31014
31098
  import { createCipheriv, createDecipheriv, randomBytes, scryptSync } from "crypto";
31015
- var DEFAULT_STORAGE_DIR = join2(process.env.HOME || "~", ".moltspay");
31099
+ var DEFAULT_STORAGE_DIR = join3(process.env.HOME || "~", ".moltspay");
31016
31100
  var DEFAULT_STORAGE_FILE = "wallet.json";
31017
31101
  function encryptPrivateKey(privateKey, password) {
31018
31102
  const salt = randomBytes(16);
@@ -31035,8 +31119,8 @@ function decryptPrivateKey(encrypted, password, iv, salt) {
31035
31119
  return decrypted;
31036
31120
  }
31037
31121
  function createWallet(options = {}) {
31038
- const storagePath = options.storagePath || join2(DEFAULT_STORAGE_DIR, DEFAULT_STORAGE_FILE);
31039
- if (existsSync2(storagePath) && !options.overwrite) {
31122
+ const storagePath = options.storagePath || join3(DEFAULT_STORAGE_DIR, DEFAULT_STORAGE_FILE);
31123
+ if (existsSync3(storagePath) && !options.overwrite) {
31040
31124
  try {
31041
31125
  const existing = JSON.parse(readFileSync3(storagePath, "utf8"));
31042
31126
  return {
@@ -31070,7 +31154,7 @@ function createWallet(options = {}) {
31070
31154
  walletData.privateKey = wallet.privateKey;
31071
31155
  }
31072
31156
  const dir = dirname(storagePath);
31073
- if (!existsSync2(dir)) {
31157
+ if (!existsSync3(dir)) {
31074
31158
  mkdirSync2(dir, { recursive: true });
31075
31159
  }
31076
31160
  writeFileSync2(storagePath, JSON.stringify(walletData, null, 2), { mode: 384 });
@@ -31088,8 +31172,8 @@ function createWallet(options = {}) {
31088
31172
  }
31089
31173
  }
31090
31174
  function loadWallet(options = {}) {
31091
- const storagePath = options.storagePath || join2(DEFAULT_STORAGE_DIR, DEFAULT_STORAGE_FILE);
31092
- if (!existsSync2(storagePath)) {
31175
+ const storagePath = options.storagePath || join3(DEFAULT_STORAGE_DIR, DEFAULT_STORAGE_FILE);
31176
+ if (!existsSync3(storagePath)) {
31093
31177
  return { success: false, error: "Wallet not found. Run createWallet() first." };
31094
31178
  }
31095
31179
  try {
@@ -31108,20 +31192,20 @@ function loadWallet(options = {}) {
31108
31192
  }
31109
31193
  }
31110
31194
  function getWalletAddress(storagePath) {
31111
- const path3 = storagePath || join2(DEFAULT_STORAGE_DIR, DEFAULT_STORAGE_FILE);
31112
- if (!existsSync2(path3)) {
31195
+ const path4 = storagePath || join3(DEFAULT_STORAGE_DIR, DEFAULT_STORAGE_FILE);
31196
+ if (!existsSync3(path4)) {
31113
31197
  return null;
31114
31198
  }
31115
31199
  try {
31116
- const data = JSON.parse(readFileSync3(path3, "utf8"));
31200
+ const data = JSON.parse(readFileSync3(path4, "utf8"));
31117
31201
  return data.address;
31118
31202
  } catch {
31119
31203
  return null;
31120
31204
  }
31121
31205
  }
31122
31206
  function walletExists(storagePath) {
31123
- const path3 = storagePath || join2(DEFAULT_STORAGE_DIR, DEFAULT_STORAGE_FILE);
31124
- return existsSync2(path3);
31207
+ const path4 = storagePath || join3(DEFAULT_STORAGE_DIR, DEFAULT_STORAGE_FILE);
31208
+ return existsSync3(path4);
31125
31209
  }
31126
31210
 
31127
31211
  // src/verify/index.ts
@@ -31264,8 +31348,8 @@ async function waitForTransaction(txHash, chain2 = "base", confirmations = 1, ti
31264
31348
  // src/cdp/index.ts
31265
31349
  init_esm_shims();
31266
31350
  import * as fs from "fs";
31267
- import * as path2 from "path";
31268
- var DEFAULT_STORAGE_DIR2 = path2.join(process.env.HOME || ".", ".moltspay");
31351
+ import * as path3 from "path";
31352
+ var DEFAULT_STORAGE_DIR2 = path3.join(process.env.HOME || ".", ".moltspay");
31269
31353
  var CDP_CONFIG_FILE = "cdp-wallet.json";
31270
31354
  function isCDPAvailable() {
31271
31355
  try {
@@ -31287,7 +31371,7 @@ function getCDPCredentials(config) {
31287
31371
  async function initCDPWallet(config = {}) {
31288
31372
  const storageDir = config.storageDir || DEFAULT_STORAGE_DIR2;
31289
31373
  const chain2 = config.chain || "base";
31290
- const storagePath = path2.join(storageDir, CDP_CONFIG_FILE);
31374
+ const storagePath = path3.join(storageDir, CDP_CONFIG_FILE);
31291
31375
  if (fs.existsSync(storagePath)) {
31292
31376
  try {
31293
31377
  const data = JSON.parse(fs.readFileSync(storagePath, "utf-8"));
@@ -31349,7 +31433,7 @@ async function initCDPWallet(config = {}) {
31349
31433
  }
31350
31434
  function loadCDPWallet(config = {}) {
31351
31435
  const storageDir = config.storageDir || DEFAULT_STORAGE_DIR2;
31352
- const storagePath = path2.join(storageDir, CDP_CONFIG_FILE);
31436
+ const storagePath = path3.join(storageDir, CDP_CONFIG_FILE);
31353
31437
  if (!fs.existsSync(storagePath)) {
31354
31438
  return null;
31355
31439
  }