moltspay 0.2.1 → 0.2.3

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 (43) hide show
  1. package/dist/chains/index.d.mts +6 -6
  2. package/dist/chains/index.d.ts +6 -6
  3. package/dist/chains/index.js +2 -2
  4. package/dist/chains/index.js.map +1 -1
  5. package/dist/chains/index.mjs +2 -2
  6. package/dist/chains/index.mjs.map +1 -1
  7. package/dist/cli.js +42 -39
  8. package/dist/cli.js.map +1 -1
  9. package/dist/cli.mjs +42 -39
  10. package/dist/cli.mjs.map +1 -1
  11. package/dist/{index-CZzgdtin.d.mts → index-CyFg9s2m.d.mts} +1 -1
  12. package/dist/{index-CZzgdtin.d.ts → index-CyFg9s2m.d.ts} +1 -1
  13. package/dist/index.d.mts +91 -27
  14. package/dist/index.d.ts +91 -27
  15. package/dist/index.js +255 -78
  16. package/dist/index.js.map +1 -1
  17. package/dist/index.mjs +253 -78
  18. package/dist/index.mjs.map +1 -1
  19. package/dist/orders/index.d.mts +13 -13
  20. package/dist/orders/index.d.ts +13 -13
  21. package/dist/orders/index.js +10 -10
  22. package/dist/orders/index.js.map +1 -1
  23. package/dist/orders/index.mjs +10 -10
  24. package/dist/orders/index.mjs.map +1 -1
  25. package/dist/permit/index.d.mts +11 -11
  26. package/dist/permit/index.d.ts +11 -11
  27. package/dist/permit/index.js +14 -14
  28. package/dist/permit/index.js.map +1 -1
  29. package/dist/permit/index.mjs +14 -14
  30. package/dist/permit/index.mjs.map +1 -1
  31. package/dist/verify/index.d.mts +4 -4
  32. package/dist/verify/index.d.ts +4 -4
  33. package/dist/verify/index.js +13 -13
  34. package/dist/verify/index.js.map +1 -1
  35. package/dist/verify/index.mjs +13 -13
  36. package/dist/verify/index.mjs.map +1 -1
  37. package/dist/wallet/index.d.mts +93 -23
  38. package/dist/wallet/index.d.ts +93 -23
  39. package/dist/wallet/index.js +102 -30
  40. package/dist/wallet/index.js.map +1 -1
  41. package/dist/wallet/index.mjs +100 -30
  42. package/dist/wallet/index.mjs.map +1 -1
  43. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -38,6 +38,7 @@ __export(src_exports, {
38
38
  OrderManager: () => OrderManager,
39
39
  PaymentAgent: () => PaymentAgent,
40
40
  PermitPayment: () => PermitPayment,
41
+ PermitSigner: () => PermitSigner,
41
42
  PermitWallet: () => PermitWallet,
42
43
  SecureWallet: () => SecureWallet,
43
44
  SellerTemplates: () => SellerTemplates,
@@ -62,6 +63,7 @@ __export(src_exports, {
62
63
  listChains: () => listChains,
63
64
  loadWallet: () => loadWallet,
64
65
  parseStatusMarker: () => parseStatusMarker,
66
+ signPermit: () => signPermit,
65
67
  verifyPayment: () => verifyPayment,
66
68
  waitForTransaction: () => waitForTransaction,
67
69
  walletExists: () => walletExists
@@ -73,7 +75,7 @@ var import_ethers = require("ethers");
73
75
 
74
76
  // src/chains/index.ts
75
77
  var CHAINS = {
76
- // ============ 主网 ============
78
+ // ============ Mainnet ============
77
79
  base: {
78
80
  name: "Base",
79
81
  chainId: 8453,
@@ -101,7 +103,7 @@ var CHAINS = {
101
103
  explorerTx: "https://etherscan.io/tx/",
102
104
  avgBlockTime: 12
103
105
  },
104
- // ============ 测试网 ============
106
+ // ============ Testnet ============
105
107
  base_sepolia: {
106
108
  name: "Base Sepolia",
107
109
  chainId: 84532,
@@ -172,7 +174,7 @@ var PaymentAgent = class _PaymentAgent {
172
174
  );
173
175
  }
174
176
  /**
175
- * 生成支付请求(Invoice)
177
+ * Generate payment request(Invoice)
176
178
  */
177
179
  createInvoice(params) {
178
180
  const expiresMinutes = params.expiresMinutes || 30;
@@ -199,14 +201,14 @@ var PaymentAgent = class _PaymentAgent {
199
201
  return invoice;
200
202
  }
201
203
  /**
202
- * 生成钱包深度链接(支持 MetaMask 等)
204
+ * Generate wallet deep link(supports MetaMask etc)
203
205
  */
204
206
  generateDeepLink(amount, memo) {
205
207
  const amountWei = Math.floor(amount * 1e6);
206
208
  return `https://metamask.app.link/send/${this.chainConfig.usdc}@${this.chainConfig.chainId}/transfer?address=${this.walletAddress}&uint256=${amountWei}`;
207
209
  }
208
210
  /**
209
- * 验证链上支付
211
+ * Verify on-chain payment
210
212
  */
211
213
  async verifyPayment(txHash, options = {}) {
212
214
  try {
@@ -261,7 +263,7 @@ var PaymentAgent = class _PaymentAgent {
261
263
  }
262
264
  }
263
265
  /**
264
- * 扫描最近转账(按金额匹配)
266
+ * Scan recent transfers (match by amount)
265
267
  */
266
268
  async scanRecentTransfers(expectedAmount, timeoutMinutes = 30) {
267
269
  try {
@@ -299,7 +301,7 @@ var PaymentAgent = class _PaymentAgent {
299
301
  }
300
302
  }
301
303
  /**
302
- * 获取钱包余额
304
+ * Get wallet balance
303
305
  */
304
306
  async getBalance(address) {
305
307
  const addr = address || this.walletAddress;
@@ -315,7 +317,7 @@ var PaymentAgent = class _PaymentAgent {
315
317
  };
316
318
  }
317
319
  /**
318
- * 格式化 Invoice 为人类可读消息
320
+ * Format Invoice as human-readable message
319
321
  */
320
322
  formatInvoiceMessage(invoice, includeJson = true) {
321
323
  let msg = `\u{1F3AC} **Payment Request**
@@ -377,7 +379,7 @@ var Wallet = class {
377
379
  );
378
380
  }
379
381
  /**
380
- * 获取钱包余额
382
+ * Get wallet balance
381
383
  */
382
384
  async getBalance() {
383
385
  const [ethBalance, usdcBalance] = await Promise.all([
@@ -392,7 +394,7 @@ var Wallet = class {
392
394
  };
393
395
  }
394
396
  /**
395
- * 发送 USDC 转账
397
+ * Send USDC transfer
396
398
  */
397
399
  async transfer(to, amount) {
398
400
  try {
@@ -433,14 +435,14 @@ var Wallet = class {
433
435
  }
434
436
  }
435
437
  /**
436
- * 获取 ETH 余额
438
+ * Get ETH balance
437
439
  */
438
440
  async getEthBalance() {
439
441
  const balance = await this.provider.getBalance(this.address);
440
442
  return import_ethers2.ethers.formatEther(balance);
441
443
  }
442
444
  /**
443
- * 获取 USDC 余额
445
+ * Get USDC balance
444
446
  */
445
447
  async getUsdcBalance() {
446
448
  const balance = await this.usdcContract.balanceOf(this.address);
@@ -461,7 +463,7 @@ var AuditLog = class {
461
463
  this.loadLastHash();
462
464
  }
463
465
  /**
464
- * 记录审计日志
466
+ * Record audit log
465
467
  */
466
468
  async log(params) {
467
469
  const now = /* @__PURE__ */ new Date();
@@ -478,7 +480,7 @@ var AuditLog = class {
478
480
  requester: params.requester,
479
481
  prev_hash: this.lastHash,
480
482
  hash: "",
481
- // 计算后填充
483
+ // Filled after calculation
482
484
  metadata: params.metadata
483
485
  };
484
486
  entry.hash = this.calculateHash(entry);
@@ -489,7 +491,7 @@ var AuditLog = class {
489
491
  return entry;
490
492
  }
491
493
  /**
492
- * 读取指定日期的日志
494
+ * Read logs for specified date
493
495
  */
494
496
  read(date) {
495
497
  const filePath = this.getFilePath(date || /* @__PURE__ */ new Date());
@@ -501,7 +503,7 @@ var AuditLog = class {
501
503
  return lines.map((line) => JSON.parse(line));
502
504
  }
503
505
  /**
504
- * 验证日志完整性
506
+ * Verify log integrity
505
507
  */
506
508
  verify(date) {
507
509
  const entries = this.read(date);
@@ -519,7 +521,7 @@ var AuditLog = class {
519
521
  return { valid: errors.length === 0, errors };
520
522
  }
521
523
  /**
522
- * 搜索日志
524
+ * Search logs
523
525
  */
524
526
  search(filter) {
525
527
  const results = [];
@@ -543,14 +545,14 @@ var AuditLog = class {
543
545
  return results;
544
546
  }
545
547
  /**
546
- * 获取日志文件路径
548
+ * Get log file path
547
549
  */
548
550
  getFilePath(date) {
549
551
  const dateStr = date.toISOString().slice(0, 10);
550
552
  return path.join(this.basePath, `audit_${dateStr}.jsonl`);
551
553
  }
552
554
  /**
553
- * 计算条目哈希
555
+ * Calculate entry hash
554
556
  */
555
557
  calculateHash(entry) {
556
558
  const data = {
@@ -567,7 +569,7 @@ var AuditLog = class {
567
569
  return crypto.createHash("sha256").update(str).digest("hex").slice(0, 16);
568
570
  }
569
571
  /**
570
- * 加载最后一条日志的哈希
572
+ * Load last log entry hash
571
573
  */
572
574
  loadLastHash() {
573
575
  const today = /* @__PURE__ */ new Date();
@@ -582,7 +584,7 @@ var AuditLog = class {
582
584
  }
583
585
  }
584
586
  /**
585
- * 确保目录存在
587
+ * Ensure directory exists
586
588
  */
587
589
  ensureDir() {
588
590
  if (!fs.existsSync(this.basePath)) {
@@ -594,9 +596,9 @@ var AuditLog = class {
594
596
  // src/wallet/SecureWallet.ts
595
597
  var DEFAULT_LIMITS = {
596
598
  singleMax: 100,
597
- // 单笔最大 $100
599
+ // Single max $100
598
600
  dailyMax: 1e3,
599
- // 日最大 $1000
601
+ // Daily max $1000
600
602
  requireWhitelist: true
601
603
  };
602
604
  var SecureWallet = class {
@@ -617,21 +619,21 @@ var SecureWallet = class {
617
619
  this.auditLog = new AuditLog(config.auditPath);
618
620
  }
619
621
  /**
620
- * 获取钱包地址
622
+ * Get wallet address
621
623
  */
622
624
  get address() {
623
625
  return this.wallet.address;
624
626
  }
625
627
  /**
626
- * 获取余额
628
+ * Get balance
627
629
  */
628
630
  async getBalance() {
629
631
  return this.wallet.getBalance();
630
632
  }
631
633
  /**
632
- * 安全转账(带限额和白名单检查)
634
+ * Secure transfer (with limit and whitelist checks)
633
635
  *
634
- * 支持两种调用方式:
636
+ * Supports two calling methods:
635
637
  * - transfer({ to, amount, reason?, requester? })
636
638
  * - transfer(to, amount)
637
639
  */
@@ -731,7 +733,7 @@ var SecureWallet = class {
731
733
  return result;
732
734
  }
733
735
  /**
734
- * 审批待处理转账
736
+ * Approve pending transfer
735
737
  */
736
738
  async approve(requestId, approver) {
737
739
  const pending = this.pendingTransfers.get(requestId);
@@ -772,7 +774,7 @@ var SecureWallet = class {
772
774
  return result;
773
775
  }
774
776
  /**
775
- * 拒绝待处理转账
777
+ * Reject pending transfer
776
778
  */
777
779
  async reject(requestId, rejecter, reason) {
778
780
  const pending = this.pendingTransfers.get(requestId);
@@ -787,7 +789,7 @@ var SecureWallet = class {
787
789
  });
788
790
  }
789
791
  /**
790
- * 添加白名单地址
792
+ * Add to whitelist
791
793
  */
792
794
  async addToWhitelist(address, addedBy) {
793
795
  const addr = address.toLowerCase();
@@ -800,7 +802,7 @@ var SecureWallet = class {
800
802
  });
801
803
  }
802
804
  /**
803
- * 移除白名单地址
805
+ * Remove from whitelist
804
806
  */
805
807
  async removeFromWhitelist(address, removedBy) {
806
808
  const addr = address.toLowerCase();
@@ -813,32 +815,32 @@ var SecureWallet = class {
813
815
  });
814
816
  }
815
817
  /**
816
- * 检查地址是否在白名单
818
+ * Check if address is whitelisted
817
819
  */
818
820
  isWhitelisted(address) {
819
821
  return this.whitelist.has(address.toLowerCase());
820
822
  }
821
823
  /**
822
- * 获取待处理转账列表
824
+ * Get pending transfers list
823
825
  */
824
826
  getPendingTransfers() {
825
827
  return Array.from(this.pendingTransfers.values()).filter((p) => p.status === "pending");
826
828
  }
827
829
  /**
828
- * 获取当前限额配置
830
+ * Get current limit config
829
831
  */
830
832
  getLimits() {
831
833
  return { ...this.limits };
832
834
  }
833
835
  /**
834
- * 获取今日已用额度
836
+ * Get daily used amount
835
837
  */
836
838
  getDailyUsed() {
837
839
  this.updateDailyTotal();
838
840
  return this.dailyTotal;
839
841
  }
840
842
  /**
841
- * 更新日限额计数器
843
+ * Update daily limit counter
842
844
  */
843
845
  updateDailyTotal() {
844
846
  const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
@@ -1213,8 +1215,76 @@ After signing, send { v, r, s, deadline } to the Agent.
1213
1215
  \u26A0\uFE0F Note: This authorization only allows the Agent to spend up to ${amount} USDC from your wallet. Your private key is never exposed.`;
1214
1216
  }
1215
1217
 
1216
- // src/permit/Permit.ts
1218
+ // src/wallet/signPermit.ts
1217
1219
  var import_ethers5 = require("ethers");
1220
+ async function signPermit(config, params) {
1221
+ const chain = config.chain || "base";
1222
+ const chainConfig = getChain(chain);
1223
+ const privateKey = config.privateKey || process.env.PAYMENT_AGENT_PRIVATE_KEY;
1224
+ if (!privateKey) {
1225
+ throw new Error("privateKey is required");
1226
+ }
1227
+ const rpcUrl = config.rpcUrl || chainConfig.rpc;
1228
+ const provider = new import_ethers5.ethers.JsonRpcProvider(rpcUrl);
1229
+ const wallet = new import_ethers5.ethers.Wallet(privateKey, provider);
1230
+ const usdcContract = new import_ethers5.ethers.Contract(chainConfig.usdc, ERC20_ABI, provider);
1231
+ const nonce = Number(await usdcContract.nonces(wallet.address));
1232
+ let deadline;
1233
+ if (!params.deadline) {
1234
+ deadline = Math.floor(Date.now() / 1e3) + 30 * 60;
1235
+ } else if (params.deadline < 1e6) {
1236
+ deadline = Math.floor(Date.now() / 1e3) + params.deadline * 60;
1237
+ } else {
1238
+ deadline = params.deadline;
1239
+ }
1240
+ const value = BigInt(Math.floor(params.amount * 1e6)).toString();
1241
+ const domain = {
1242
+ name: "USD Coin",
1243
+ version: "2",
1244
+ chainId: chainConfig.chainId,
1245
+ verifyingContract: chainConfig.usdc
1246
+ };
1247
+ const types = {
1248
+ Permit: [
1249
+ { name: "owner", type: "address" },
1250
+ { name: "spender", type: "address" },
1251
+ { name: "value", type: "uint256" },
1252
+ { name: "nonce", type: "uint256" },
1253
+ { name: "deadline", type: "uint256" }
1254
+ ]
1255
+ };
1256
+ const message = {
1257
+ owner: wallet.address,
1258
+ spender: params.spender,
1259
+ value,
1260
+ nonce,
1261
+ deadline
1262
+ };
1263
+ const signature = await wallet.signTypedData(domain, types, message);
1264
+ const sig = import_ethers5.ethers.Signature.from(signature);
1265
+ return {
1266
+ owner: wallet.address,
1267
+ spender: params.spender,
1268
+ value,
1269
+ deadline,
1270
+ nonce,
1271
+ v: sig.v,
1272
+ r: sig.r,
1273
+ s: sig.s
1274
+ };
1275
+ }
1276
+ var PermitSigner = class {
1277
+ config;
1278
+ constructor(config) {
1279
+ this.config = config;
1280
+ }
1281
+ async sign(params) {
1282
+ return signPermit(this.config, params);
1283
+ }
1284
+ };
1285
+
1286
+ // src/permit/Permit.ts
1287
+ var import_ethers6 = require("ethers");
1218
1288
  var PermitPayment = class {
1219
1289
  chain;
1220
1290
  chainConfig;
@@ -1227,26 +1297,26 @@ var PermitPayment = class {
1227
1297
  this.chainConfig = getChain(this.chain);
1228
1298
  this.spenderAddress = config.spenderAddress || process.env.PAYMENT_AGENT_WALLET || "";
1229
1299
  const rpcUrl = config.rpcUrl || this.chainConfig.rpc;
1230
- this.provider = new import_ethers5.ethers.JsonRpcProvider(rpcUrl);
1300
+ this.provider = new import_ethers6.ethers.JsonRpcProvider(rpcUrl);
1231
1301
  const privateKey = config.privateKey || process.env.PAYMENT_AGENT_PRIVATE_KEY;
1232
1302
  if (privateKey) {
1233
- this.wallet = new import_ethers5.ethers.Wallet(privateKey, this.provider);
1303
+ this.wallet = new import_ethers6.ethers.Wallet(privateKey, this.provider);
1234
1304
  this.spenderAddress = this.wallet.address;
1235
1305
  }
1236
- this.usdcContract = new import_ethers5.ethers.Contract(
1306
+ this.usdcContract = new import_ethers6.ethers.Contract(
1237
1307
  this.chainConfig.usdc,
1238
1308
  ERC20_ABI,
1239
1309
  this.wallet || this.provider
1240
1310
  );
1241
1311
  }
1242
1312
  /**
1243
- * 获取用户当前 nonce
1313
+ * Get user current nonce
1244
1314
  */
1245
1315
  async getNonce(owner) {
1246
1316
  return Number(await this.usdcContract.nonces(owner));
1247
1317
  }
1248
1318
  /**
1249
- * 生成 EIP-712 签名请求(发给前端/用户钱包)
1319
+ * Generate EIP-712 signing request (for frontend/user wallet)
1250
1320
  */
1251
1321
  async createPermitRequest(owner, amount, orderId, deadlineMinutes = 30) {
1252
1322
  const nonce = await this.getNonce(owner);
@@ -1294,11 +1364,11 @@ var PermitPayment = class {
1294
1364
  };
1295
1365
  }
1296
1366
  /**
1297
- * 执行 permit + transferFrom
1367
+ * Execute permit + transferFrom
1298
1368
  *
1299
- * @param owner 用户地址
1300
- * @param amount 金额
1301
- * @param signature 用户签名 {v, r, s, deadline}
1369
+ * @param owner User address
1370
+ * @param amount Amount
1371
+ * @param signature User signature {v, r, s, deadline}
1302
1372
  */
1303
1373
  async executePermitAndTransfer(owner, amount, signature) {
1304
1374
  if (!this.wallet) {
@@ -1330,7 +1400,7 @@ var PermitPayment = class {
1330
1400
  }
1331
1401
  }
1332
1402
  /**
1333
- * 仅执行 permit(不 transfer
1403
+ * Execute permit only (no transfer)
1334
1404
  */
1335
1405
  async executePermit(owner, amount, signature) {
1336
1406
  if (!this.wallet) {
@@ -1360,22 +1430,22 @@ var PermitPayment = class {
1360
1430
  }
1361
1431
  }
1362
1432
  /**
1363
- * 格式化 Permit 请求为用户消息
1433
+ * Format Permit request as user message
1364
1434
  */
1365
1435
  formatPermitMessage(request) {
1366
1436
  const { typed_data } = request;
1367
1437
  const { message } = typed_data;
1368
- return `\u{1F510} **\u7B7E\u540D\u6388\u6743\u8BF7\u6C42**
1438
+ return `\u{1F510} **Signature Authorization Request**
1369
1439
 
1370
- \u6388\u6743 \`${(Number(message.value) / 1e6).toFixed(2)} USDC\` \u7ED9\u670D\u52A1\u65B9
1440
+ Authorize \`${(Number(message.value) / 1e6).toFixed(2)} USDC\` to service provider
1371
1441
 
1372
- **\u7B7E\u540D\u4FE1\u606F\uFF1A**
1442
+ **Signature Details:**
1373
1443
  - Owner: \`${message.owner}\`
1374
1444
  - Spender: \`${message.spender}\`
1375
1445
  - Amount: ${(Number(message.value) / 1e6).toFixed(2)} USDC
1376
1446
  - Deadline: ${new Date(message.deadline * 1e3).toISOString()}
1377
1447
 
1378
- \u8BF7\u5728\u94B1\u5305\u4E2D\u7B7E\u540D\u6B64\u8BF7\u6C42\uFF08\u4E0D\u6D88\u8017 Gas\uFF09\u3002
1448
+ Please sign this request in your wallet (no gas required).
1379
1449
 
1380
1450
  \`\`\`json
1381
1451
  ${JSON.stringify(typed_data, null, 2)}
@@ -1420,13 +1490,13 @@ var OrderManager = class {
1420
1490
  this.defaultChain = options.defaultChain || "base";
1421
1491
  }
1422
1492
  /**
1423
- * 生成订单ID
1493
+ * Generate order ID
1424
1494
  */
1425
1495
  generateOrderId() {
1426
1496
  return "vo_" + (0, import_crypto2.randomBytes)(4).toString("hex");
1427
1497
  }
1428
1498
  /**
1429
- * 创建订单
1499
+ * Create order
1430
1500
  */
1431
1501
  async createOrder(params) {
1432
1502
  const order = {
@@ -1443,13 +1513,13 @@ var OrderManager = class {
1443
1513
  return order;
1444
1514
  }
1445
1515
  /**
1446
- * 获取订单
1516
+ * Get order
1447
1517
  */
1448
1518
  async getOrder(orderId) {
1449
1519
  return this.store.get(orderId);
1450
1520
  }
1451
1521
  /**
1452
- * 更新订单
1522
+ * Update order
1453
1523
  */
1454
1524
  async updateOrder(orderId, updates) {
1455
1525
  const order = await this.store.get(orderId);
@@ -1459,7 +1529,7 @@ var OrderManager = class {
1459
1529
  return updated;
1460
1530
  }
1461
1531
  /**
1462
- * 查找用户的待支付订单
1532
+ * Find user pending orders
1463
1533
  */
1464
1534
  async findPendingOrder(userId) {
1465
1535
  const orders = await this.store.findByUser(userId, "pending");
@@ -1473,7 +1543,7 @@ var OrderManager = class {
1473
1543
  return null;
1474
1544
  }
1475
1545
  /**
1476
- * 标记订单为已支付
1546
+ * Mark order as paid
1477
1547
  */
1478
1548
  async markAsPaid(orderId, txHash, payerAddress) {
1479
1549
  return this.updateOrder(orderId, {
@@ -1484,13 +1554,13 @@ var OrderManager = class {
1484
1554
  });
1485
1555
  }
1486
1556
  /**
1487
- * 标记订单为生成中
1557
+ * Mark order as generating
1488
1558
  */
1489
1559
  async markAsGenerating(orderId) {
1490
1560
  return this.updateOrder(orderId, { status: "generating" });
1491
1561
  }
1492
1562
  /**
1493
- * 标记订单为完成
1563
+ * Mark order as completed
1494
1564
  */
1495
1565
  async markAsCompleted(orderId, videoPath) {
1496
1566
  return this.updateOrder(orderId, {
@@ -1499,7 +1569,7 @@ var OrderManager = class {
1499
1569
  });
1500
1570
  }
1501
1571
  /**
1502
- * 标记订单为失败
1572
+ * Mark order as failed
1503
1573
  */
1504
1574
  async markAsFailed(orderId, error) {
1505
1575
  return this.updateOrder(orderId, {
@@ -1508,7 +1578,7 @@ var OrderManager = class {
1508
1578
  });
1509
1579
  }
1510
1580
  /**
1511
- * 取消订单
1581
+ * Cancel order
1512
1582
  */
1513
1583
  async cancelOrder(orderId) {
1514
1584
  return this.updateOrder(orderId, { status: "cancelled" });
@@ -1516,8 +1586,8 @@ var OrderManager = class {
1516
1586
  };
1517
1587
 
1518
1588
  // src/verify/index.ts
1519
- var import_ethers6 = require("ethers");
1520
- var TRANSFER_EVENT_TOPIC = import_ethers6.ethers.id("Transfer(address,address,uint256)");
1589
+ var import_ethers7 = require("ethers");
1590
+ var TRANSFER_EVENT_TOPIC = import_ethers7.ethers.id("Transfer(address,address,uint256)");
1521
1591
  async function verifyPayment(params) {
1522
1592
  const { txHash, expectedAmount, expectedTo } = params;
1523
1593
  let chain;
@@ -1528,23 +1598,23 @@ async function verifyPayment(params) {
1528
1598
  chain = getChain(params.chain || "base");
1529
1599
  }
1530
1600
  if (!chain) {
1531
- return { verified: false, error: `\u4E0D\u652F\u6301\u7684\u94FE: ${params.chain}` };
1601
+ return { verified: false, error: `Unsupported chain: ${params.chain}` };
1532
1602
  }
1533
1603
  } catch (e) {
1534
- return { verified: false, error: `\u4E0D\u652F\u6301\u7684\u94FE: ${params.chain}` };
1604
+ return { verified: false, error: `Unsupported chain: ${params.chain}` };
1535
1605
  }
1536
1606
  try {
1537
- const provider = new import_ethers6.ethers.JsonRpcProvider(chain.rpc);
1607
+ const provider = new import_ethers7.ethers.JsonRpcProvider(chain.rpc);
1538
1608
  const receipt = await provider.getTransactionReceipt(txHash);
1539
1609
  if (!receipt) {
1540
- return { verified: false, error: "\u4EA4\u6613\u672A\u627E\u5230\u6216\u672A\u786E\u8BA4" };
1610
+ return { verified: false, error: "Transaction not found or not confirmed" };
1541
1611
  }
1542
1612
  if (receipt.status !== 1) {
1543
- return { verified: false, error: "\u4EA4\u6613\u5931\u8D25" };
1613
+ return { verified: false, error: "Transaction failed" };
1544
1614
  }
1545
1615
  const usdcAddress = chain.usdc?.toLowerCase();
1546
1616
  if (!usdcAddress) {
1547
- return { verified: false, error: `\u94FE ${chain.name} \u672A\u914D\u7F6EUSDC\u5730\u5740` };
1617
+ return { verified: false, error: `Chain ${chain.name} USDC address not configured` };
1548
1618
  }
1549
1619
  for (const log of receipt.logs) {
1550
1620
  if (log.address.toLowerCase() !== usdcAddress) {
@@ -1563,7 +1633,7 @@ async function verifyPayment(params) {
1563
1633
  if (amount < expectedAmount) {
1564
1634
  return {
1565
1635
  verified: false,
1566
- error: `\u91D1\u989D\u4E0D\u8DB3: \u6536\u5230 ${amount} USDC, \u9700\u8981 ${expectedAmount} USDC`,
1636
+ error: `Insufficient amount: received ${amount} USDC, expected ${expectedAmount} USDC`,
1567
1637
  amount,
1568
1638
  from,
1569
1639
  to,
@@ -1580,7 +1650,7 @@ async function verifyPayment(params) {
1580
1650
  blockNumber: receipt.blockNumber
1581
1651
  };
1582
1652
  }
1583
- return { verified: false, error: "\u672A\u627E\u5230USDC\u8F6C\u8D26\u8BB0\u5F55" };
1653
+ return { verified: false, error: "No USDC transfer found" };
1584
1654
  } catch (e) {
1585
1655
  return { verified: false, error: e.message || String(e) };
1586
1656
  }
@@ -1594,7 +1664,7 @@ async function getTransactionStatus(txHash, chain = "base") {
1594
1664
  return { status: "not_found" };
1595
1665
  }
1596
1666
  try {
1597
- const provider = new import_ethers6.ethers.JsonRpcProvider(chainConfig.rpc);
1667
+ const provider = new import_ethers7.ethers.JsonRpcProvider(chainConfig.rpc);
1598
1668
  const receipt = await provider.getTransactionReceipt(txHash);
1599
1669
  if (!receipt) {
1600
1670
  const tx = await provider.getTransaction(txHash);
@@ -1626,19 +1696,19 @@ async function waitForTransaction(txHash, chain = "base", confirmations = 1, tim
1626
1696
  try {
1627
1697
  chainConfig = typeof chain === "number" ? getChainById(chain) : getChain(chain);
1628
1698
  if (!chainConfig) {
1629
- return { verified: false, confirmed: false, error: `\u4E0D\u652F\u6301\u7684\u94FE: ${chain}` };
1699
+ return { verified: false, confirmed: false, error: `Unsupported chain: ${chain}` };
1630
1700
  }
1631
1701
  } catch (e) {
1632
- return { verified: false, confirmed: false, error: `\u4E0D\u652F\u6301\u7684\u94FE: ${chain}` };
1702
+ return { verified: false, confirmed: false, error: `Unsupported chain: ${chain}` };
1633
1703
  }
1634
- const provider = new import_ethers6.ethers.JsonRpcProvider(chainConfig.rpc);
1704
+ const provider = new import_ethers7.ethers.JsonRpcProvider(chainConfig.rpc);
1635
1705
  try {
1636
1706
  const receipt = await provider.waitForTransaction(txHash, confirmations, timeoutMs);
1637
1707
  if (!receipt) {
1638
- return { verified: false, confirmed: false, error: "\u7B49\u5F85\u8D85\u65F6" };
1708
+ return { verified: false, confirmed: false, error: "Timeout waiting" };
1639
1709
  }
1640
1710
  if (receipt.status !== 1) {
1641
- return { verified: false, confirmed: true, error: "\u4EA4\u6613\u5931\u8D25" };
1711
+ return { verified: false, confirmed: true, error: "Transaction failed" };
1642
1712
  }
1643
1713
  return {
1644
1714
  verified: true,
@@ -2054,6 +2124,58 @@ ${receipt.delivery?.url ? `- Delivery: ${receipt.delivery.url}` : ""}
2054
2124
  */
2055
2125
  end() {
2056
2126
  return `Thank you for your purchase. This transaction is complete. Feel free to reach out if you need modifications or new services.`;
2127
+ },
2128
+ // ============ Permit Payment (Seller receives Permit from Client) ============
2129
+ /**
2130
+ * Offer Permit payment option
2131
+ */
2132
+ offerPermitPayment(params) {
2133
+ const { service, price, sellerAddress, chain = "base", invoiceId } = params;
2134
+ const chainConfig = getChain(chain);
2135
+ return `Quote:
2136
+ - Service: ${service}
2137
+ - Price: ${price} USDC
2138
+ - Chain: ${chainConfig.name}
2139
+ - Invoice: ${invoiceId}
2140
+
2141
+ You can pay by signing a Permit authorizing my wallet to collect payment:
2142
+ - Spender (me): \`${sellerAddress}\`
2143
+ - Amount: ${price} USDC
2144
+
2145
+ Sign the Permit and send me the data. I'll then execute the collection.
2146
+ [status:awaiting_permit invoice=${invoiceId}]`;
2147
+ },
2148
+ /**
2149
+ * Confirm Permit received, executing payment
2150
+ */
2151
+ executingPermit(invoiceId) {
2152
+ return `Permit received for invoice ${invoiceId}. Executing payment collection now...`;
2153
+ },
2154
+ /**
2155
+ * Permit payment successful
2156
+ */
2157
+ permitPaymentReceived(params) {
2158
+ const { amount, txHash, invoiceId } = params;
2159
+ return `Payment collected successfully!
2160
+ - Invoice: ${invoiceId}
2161
+ - Amount: ${amount} USDC
2162
+ - Tx Hash: \`${txHash}\`
2163
+
2164
+ Starting to process your request now.
2165
+ [status:payment_confirmed tx=${txHash}]`;
2166
+ },
2167
+ /**
2168
+ * Permit payment failed
2169
+ */
2170
+ permitPaymentFailed(error, invoiceId) {
2171
+ return `Failed to collect payment for invoice ${invoiceId}: ${error}
2172
+
2173
+ Please check:
2174
+ - Permit signature is valid
2175
+ - Permit hasn't expired
2176
+ - Your wallet has sufficient USDC balance
2177
+
2178
+ You can re-sign and send a new Permit.`;
2057
2179
  }
2058
2180
  };
2059
2181
  var BuyerTemplates = {
@@ -2146,11 +2268,46 @@ ${requirements}`;
2146
2268
  const { amount, agentAddress, deadlineHours = 24, reason } = params;
2147
2269
  return `Boss, I need a USDC spending allowance (Permit) for ${reason || "purchasing services"}.
2148
2270
  Please authorize ${amount} USDC to my wallet ${agentAddress}, valid for ${deadlineHours} hours.`;
2271
+ },
2272
+ // ============ Permit Payment (Client signs Permit to Seller) ============
2273
+ /**
2274
+ * Confirm willing to pay via Permit
2275
+ */
2276
+ confirmPermitPayment() {
2277
+ return `Confirmed. I'll sign a Permit authorizing you to collect the payment.`;
2278
+ },
2279
+ /**
2280
+ * Send signed Permit to Seller
2281
+ */
2282
+ sendPermit(params) {
2283
+ const { permit, invoiceId, amount } = params;
2284
+ return `Payment authorized via Permit.
2285
+
2286
+ Invoice: ${invoiceId}
2287
+ Amount: ${amount} USDC
2288
+
2289
+ Permit Data:
2290
+ \`\`\`json
2291
+ ${JSON.stringify(permit, null, 2)}
2292
+ \`\`\`
2293
+
2294
+ [status:permit_sent invoice=${invoiceId} amount=${amount}]`;
2295
+ },
2296
+ /**
2297
+ * Simplified Permit message (compact JSON for agent parsing)
2298
+ */
2299
+ sendPermitCompact(params) {
2300
+ const { permit, invoiceId } = params;
2301
+ return `Permit signed for invoice ${invoiceId}:
2302
+ ${JSON.stringify(permit)}
2303
+ [status:permit_sent invoice=${invoiceId}]`;
2149
2304
  }
2150
2305
  };
2151
2306
  var StatusMarkers = {
2152
2307
  walletReady: "[status:wallet_ready]",
2153
2308
  permitReady: (amount) => `[status:permit_ready USDC=${amount}]`,
2309
+ permitSent: (invoiceId, amount) => `[status:permit_sent invoice=${invoiceId} amount=${amount}]`,
2310
+ awaitingPermit: (invoiceId) => `[status:awaiting_permit invoice=${invoiceId}]`,
2154
2311
  paymentSent: (txHash, amount) => `[status:payment_sent tx=${txHash} amount=${amount} USDC]`,
2155
2312
  paymentConfirmed: (txHash) => `[status:payment_confirmed tx=${txHash}]`,
2156
2313
  delivered: (url, hash) => `[status:delivered url=${url}${hash ? ` hash=${hash}` : ""}]`,
@@ -2170,6 +2327,24 @@ function parseStatusMarker(message) {
2170
2327
  data: { amount: amountMatch?.[1] || "0" }
2171
2328
  };
2172
2329
  }
2330
+ if (content.startsWith("permit_sent")) {
2331
+ const invoiceMatch = content.match(/invoice=(\S+)/);
2332
+ const amountMatch = content.match(/amount=(\d+(?:\.\d+)?)/);
2333
+ return {
2334
+ type: "permit_sent",
2335
+ data: {
2336
+ invoiceId: invoiceMatch?.[1] || "",
2337
+ amount: amountMatch?.[1] || "0"
2338
+ }
2339
+ };
2340
+ }
2341
+ if (content.startsWith("awaiting_permit")) {
2342
+ const invoiceMatch = content.match(/invoice=(\S+)/);
2343
+ return {
2344
+ type: "awaiting_permit",
2345
+ data: { invoiceId: invoiceMatch?.[1] || "" }
2346
+ };
2347
+ }
2173
2348
  if (content.startsWith("payment_sent")) {
2174
2349
  const txMatch = content.match(/tx=(\S+)/);
2175
2350
  const amountMatch = content.match(/amount=(\d+(?:\.\d+)?)/);
@@ -2222,6 +2397,7 @@ function parseStatusMarker(message) {
2222
2397
  OrderManager,
2223
2398
  PaymentAgent,
2224
2399
  PermitPayment,
2400
+ PermitSigner,
2225
2401
  PermitWallet,
2226
2402
  SecureWallet,
2227
2403
  SellerTemplates,
@@ -2246,6 +2422,7 @@ function parseStatusMarker(message) {
2246
2422
  listChains,
2247
2423
  loadWallet,
2248
2424
  parseStatusMarker,
2425
+ signPermit,
2249
2426
  verifyPayment,
2250
2427
  waitForTransaction,
2251
2428
  walletExists