moltspay 0.1.2 → 0.2.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
@@ -779,8 +779,372 @@ var SecureWallet = class {
779
779
  }
780
780
  };
781
781
 
782
- // src/permit/Permit.ts
782
+ // src/wallet/createWallet.ts
783
783
  import { ethers as ethers3 } from "ethers";
784
+ import { writeFileSync, readFileSync as readFileSync2, existsSync as existsSync2, mkdirSync as mkdirSync2 } from "fs";
785
+ import { join as join2, dirname } from "path";
786
+ import { createCipheriv, createDecipheriv, randomBytes, scryptSync } from "crypto";
787
+ var DEFAULT_STORAGE_DIR = join2(process.env.HOME || "~", ".moltspay");
788
+ var DEFAULT_STORAGE_FILE = "wallet.json";
789
+ function encryptPrivateKey(privateKey, password) {
790
+ const salt = randomBytes(16);
791
+ const key = scryptSync(password, salt, 32);
792
+ const iv = randomBytes(16);
793
+ const cipher = createCipheriv("aes-256-cbc", key, iv);
794
+ let encrypted = cipher.update(privateKey, "utf8", "hex");
795
+ encrypted += cipher.final("hex");
796
+ return {
797
+ encrypted,
798
+ iv: iv.toString("hex"),
799
+ salt: salt.toString("hex")
800
+ };
801
+ }
802
+ function decryptPrivateKey(encrypted, password, iv, salt) {
803
+ const key = scryptSync(password, Buffer.from(salt, "hex"), 32);
804
+ const decipher = createDecipheriv("aes-256-cbc", key, Buffer.from(iv, "hex"));
805
+ let decrypted = decipher.update(encrypted, "hex", "utf8");
806
+ decrypted += decipher.final("utf8");
807
+ return decrypted;
808
+ }
809
+ function createWallet(options = {}) {
810
+ const storagePath = options.storagePath || join2(DEFAULT_STORAGE_DIR, DEFAULT_STORAGE_FILE);
811
+ if (existsSync2(storagePath) && !options.overwrite) {
812
+ try {
813
+ const existing = JSON.parse(readFileSync2(storagePath, "utf8"));
814
+ return {
815
+ success: true,
816
+ address: existing.address,
817
+ storagePath,
818
+ isNew: false
819
+ };
820
+ } catch (error) {
821
+ return {
822
+ success: false,
823
+ error: `Failed to load existing wallet: ${error.message}`
824
+ };
825
+ }
826
+ }
827
+ try {
828
+ const wallet = ethers3.Wallet.createRandom();
829
+ const walletData = {
830
+ address: wallet.address,
831
+ label: options.label,
832
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
833
+ encrypted: !!options.password,
834
+ privateKey: ""
835
+ };
836
+ if (options.password) {
837
+ const { encrypted, iv, salt } = encryptPrivateKey(wallet.privateKey, options.password);
838
+ walletData.privateKey = encrypted;
839
+ walletData.iv = iv;
840
+ walletData.salt = salt;
841
+ } else {
842
+ walletData.privateKey = wallet.privateKey;
843
+ }
844
+ const dir = dirname(storagePath);
845
+ if (!existsSync2(dir)) {
846
+ mkdirSync2(dir, { recursive: true });
847
+ }
848
+ writeFileSync(storagePath, JSON.stringify(walletData, null, 2), { mode: 384 });
849
+ return {
850
+ success: true,
851
+ address: wallet.address,
852
+ storagePath,
853
+ isNew: true
854
+ };
855
+ } catch (error) {
856
+ return {
857
+ success: false,
858
+ error: error.message
859
+ };
860
+ }
861
+ }
862
+ function loadWallet(options = {}) {
863
+ const storagePath = options.storagePath || join2(DEFAULT_STORAGE_DIR, DEFAULT_STORAGE_FILE);
864
+ if (!existsSync2(storagePath)) {
865
+ return { success: false, error: "Wallet not found. Run createWallet() first." };
866
+ }
867
+ try {
868
+ const data = JSON.parse(readFileSync2(storagePath, "utf8"));
869
+ if (data.encrypted) {
870
+ if (!options.password) {
871
+ return { success: false, error: "Wallet is encrypted. Password required." };
872
+ }
873
+ const privateKey = decryptPrivateKey(data.privateKey, options.password, data.iv, data.salt);
874
+ return { success: true, address: data.address, privateKey };
875
+ } else {
876
+ return { success: true, address: data.address, privateKey: data.privateKey };
877
+ }
878
+ } catch (error) {
879
+ return { success: false, error: error.message };
880
+ }
881
+ }
882
+ function getWalletAddress(storagePath) {
883
+ const path2 = storagePath || join2(DEFAULT_STORAGE_DIR, DEFAULT_STORAGE_FILE);
884
+ if (!existsSync2(path2)) {
885
+ return null;
886
+ }
887
+ try {
888
+ const data = JSON.parse(readFileSync2(path2, "utf8"));
889
+ return data.address;
890
+ } catch {
891
+ return null;
892
+ }
893
+ }
894
+ function walletExists(storagePath) {
895
+ const path2 = storagePath || join2(DEFAULT_STORAGE_DIR, DEFAULT_STORAGE_FILE);
896
+ return existsSync2(path2);
897
+ }
898
+
899
+ // src/wallet/PermitWallet.ts
900
+ import { ethers as ethers4 } from "ethers";
901
+ var PERMIT_ABI = [
902
+ ...ERC20_ABI,
903
+ "function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s)",
904
+ "function transferFrom(address from, address to, uint256 amount) returns (bool)",
905
+ "function allowance(address owner, address spender) view returns (uint256)"
906
+ ];
907
+ var PermitWallet = class {
908
+ chain;
909
+ chainConfig;
910
+ address;
911
+ wallet;
912
+ provider;
913
+ usdcContract;
914
+ constructor(config = {}) {
915
+ this.chain = config.chain || "base_sepolia";
916
+ this.chainConfig = getChain(this.chain);
917
+ let privateKey = config.privateKey || process.env.PAYMENT_AGENT_PRIVATE_KEY;
918
+ if (!privateKey && config.walletPath) {
919
+ const loaded = loadWallet({
920
+ storagePath: config.walletPath,
921
+ password: config.walletPassword
922
+ });
923
+ if (!loaded.success || !loaded.privateKey) {
924
+ throw new Error(loaded.error || "Failed to load wallet");
925
+ }
926
+ privateKey = loaded.privateKey;
927
+ }
928
+ if (!privateKey) {
929
+ throw new Error("privateKey is required. Set via config, env var, or walletPath.");
930
+ }
931
+ const rpcUrl = config.rpcUrl || this.chainConfig.rpc;
932
+ this.provider = new ethers4.JsonRpcProvider(rpcUrl);
933
+ this.wallet = new ethers4.Wallet(privateKey, this.provider);
934
+ this.address = this.wallet.address;
935
+ this.usdcContract = new ethers4.Contract(
936
+ this.chainConfig.usdc,
937
+ PERMIT_ABI,
938
+ this.wallet
939
+ );
940
+ }
941
+ /**
942
+ * 检查 Permit 是否有效
943
+ */
944
+ async checkPermitAllowance(owner) {
945
+ const allowance = await this.usdcContract.allowance(owner, this.address);
946
+ return (Number(allowance) / 1e6).toFixed(2);
947
+ }
948
+ /**
949
+ * 使用 Permit 授权进行支付
950
+ *
951
+ * 流程:
952
+ * 1. 调用 permit() 让合约记录 Boss 的授权
953
+ * 2. 调用 transferFrom() 从 Boss 钱包转账到收款方
954
+ *
955
+ * @example
956
+ * ```typescript
957
+ * const wallet = new PermitWallet({ chain: 'base' });
958
+ *
959
+ * // Boss 签署的 permit 数据
960
+ * const permit = {
961
+ * owner: '0xBOSS...',
962
+ * spender: wallet.address,
963
+ * value: '10000000', // 10 USDC
964
+ * deadline: 1234567890,
965
+ * v: 27,
966
+ * r: '0x...',
967
+ * s: '0x...'
968
+ * };
969
+ *
970
+ * const result = await wallet.transferWithPermit({
971
+ * to: '0xSELLER...',
972
+ * amount: 3.99,
973
+ * permit
974
+ * });
975
+ * ```
976
+ */
977
+ async transferWithPermit(params) {
978
+ const { to, amount, permit } = params;
979
+ try {
980
+ const toAddress = ethers4.getAddress(to);
981
+ const ownerAddress = ethers4.getAddress(permit.owner);
982
+ if (ethers4.getAddress(permit.spender).toLowerCase() !== this.address.toLowerCase()) {
983
+ return {
984
+ success: false,
985
+ error: `Permit spender (${permit.spender}) doesn't match wallet address (${this.address})`
986
+ };
987
+ }
988
+ const now = Math.floor(Date.now() / 1e3);
989
+ if (permit.deadline < now) {
990
+ return {
991
+ success: false,
992
+ error: `Permit expired at ${new Date(permit.deadline * 1e3).toISOString()}`
993
+ };
994
+ }
995
+ const amountWei = BigInt(Math.floor(amount * 1e6));
996
+ const permitValue = BigInt(permit.value);
997
+ if (amountWei > permitValue) {
998
+ return {
999
+ success: false,
1000
+ error: `Permit value (${Number(permitValue) / 1e6} USDC) < transfer amount (${amount} USDC)`
1001
+ };
1002
+ }
1003
+ const currentAllowance = await this.usdcContract.allowance(ownerAddress, this.address);
1004
+ let permitTxHash;
1005
+ if (BigInt(currentAllowance) < amountWei) {
1006
+ console.log("Executing permit...");
1007
+ const permitTx = await this.usdcContract.permit(
1008
+ ownerAddress,
1009
+ this.address,
1010
+ permitValue,
1011
+ permit.deadline,
1012
+ permit.v,
1013
+ permit.r,
1014
+ permit.s
1015
+ );
1016
+ const permitReceipt = await permitTx.wait();
1017
+ if (permitReceipt.status !== 1) {
1018
+ return {
1019
+ success: false,
1020
+ error: "Permit transaction failed",
1021
+ permitTxHash: permitTx.hash
1022
+ };
1023
+ }
1024
+ permitTxHash = permitTx.hash;
1025
+ console.log("Permit executed:", permitTxHash);
1026
+ }
1027
+ console.log("Executing transferFrom...");
1028
+ const transferTx = await this.usdcContract.transferFrom(
1029
+ ownerAddress,
1030
+ toAddress,
1031
+ amountWei
1032
+ );
1033
+ const transferReceipt = await transferTx.wait();
1034
+ if (transferReceipt.status === 1) {
1035
+ return {
1036
+ success: true,
1037
+ tx_hash: transferTx.hash,
1038
+ permitTxHash,
1039
+ transferTxHash: transferTx.hash,
1040
+ from: ownerAddress,
1041
+ to: toAddress,
1042
+ amount,
1043
+ gas_used: Number(transferReceipt.gasUsed),
1044
+ block_number: transferReceipt.blockNumber,
1045
+ explorer_url: `${this.chainConfig.explorerTx}${transferTx.hash}`
1046
+ };
1047
+ } else {
1048
+ return {
1049
+ success: false,
1050
+ error: "TransferFrom transaction failed",
1051
+ tx_hash: transferTx.hash,
1052
+ permitTxHash
1053
+ };
1054
+ }
1055
+ } catch (error) {
1056
+ const message = error.message;
1057
+ if (message.includes("ERC20InsufficientAllowance")) {
1058
+ return {
1059
+ success: false,
1060
+ error: "Insufficient allowance. Permit may have been used or expired."
1061
+ };
1062
+ }
1063
+ if (message.includes("ERC20InsufficientBalance")) {
1064
+ return {
1065
+ success: false,
1066
+ error: "Boss wallet has insufficient USDC balance."
1067
+ };
1068
+ }
1069
+ if (message.includes("InvalidSignature") || message.includes("invalid signature")) {
1070
+ return {
1071
+ success: false,
1072
+ error: "Invalid permit signature. Ask Boss to re-sign."
1073
+ };
1074
+ }
1075
+ return {
1076
+ success: false,
1077
+ error: message
1078
+ };
1079
+ }
1080
+ }
1081
+ /**
1082
+ * 获取 ETH 余额(用于支付 gas)
1083
+ */
1084
+ async getGasBalance() {
1085
+ const balance = await this.provider.getBalance(this.address);
1086
+ return ethers4.formatEther(balance);
1087
+ }
1088
+ /**
1089
+ * 检查是否有足够的 gas
1090
+ */
1091
+ async hasEnoughGas(minEth = 1e-3) {
1092
+ const balance = await this.getGasBalance();
1093
+ return parseFloat(balance) >= minEth;
1094
+ }
1095
+ };
1096
+ function formatPermitRequest(params) {
1097
+ const { agentAddress, amount, deadlineHours = 24, chain = "base", reason } = params;
1098
+ const chainConfig = getChain(chain);
1099
+ const deadline = Math.floor(Date.now() / 1e3) + deadlineHours * 3600;
1100
+ const value = BigInt(Math.floor(amount * 1e6)).toString();
1101
+ return `\u{1F510} **USDC \u652F\u4ED8\u989D\u5EA6\u6388\u6743\u8BF7\u6C42**
1102
+
1103
+ ${reason ? `**\u7528\u9014:** ${reason}
1104
+ ` : ""}
1105
+ **\u6388\u6743\u8BE6\u60C5:**
1106
+ - \u88AB\u6388\u6743\u5730\u5740 (Agent): \`${agentAddress}\`
1107
+ - \u6388\u6743\u91D1\u989D: ${amount} USDC
1108
+ - \u6709\u6548\u671F: ${deadlineHours} \u5C0F\u65F6
1109
+ - \u94FE: ${chainConfig.name}
1110
+
1111
+ **\u8BF7\u4F7F\u7528\u94B1\u5305\u7B7E\u7F72\u4EE5\u4E0B EIP-2612 Permit:**
1112
+
1113
+ \`\`\`json
1114
+ {
1115
+ "types": {
1116
+ "Permit": [
1117
+ { "name": "owner", "type": "address" },
1118
+ { "name": "spender", "type": "address" },
1119
+ { "name": "value", "type": "uint256" },
1120
+ { "name": "nonce", "type": "uint256" },
1121
+ { "name": "deadline", "type": "uint256" }
1122
+ ]
1123
+ },
1124
+ "primaryType": "Permit",
1125
+ "domain": {
1126
+ "name": "USD Coin",
1127
+ "version": "2",
1128
+ "chainId": ${chainConfig.chainId},
1129
+ "verifyingContract": "${chainConfig.usdc}"
1130
+ },
1131
+ "message": {
1132
+ "owner": "<YOUR_WALLET_ADDRESS>",
1133
+ "spender": "${agentAddress}",
1134
+ "value": "${value}",
1135
+ "nonce": "<GET_FROM_CONTRACT>",
1136
+ "deadline": ${deadline}
1137
+ }
1138
+ }
1139
+ \`\`\`
1140
+
1141
+ \u7B7E\u540D\u540E\uFF0C\u8BF7\u5C06 { v, r, s, deadline } \u53D1\u7ED9 Agent\u3002
1142
+
1143
+ \u26A0\uFE0F \u6CE8\u610F\uFF1A\u6B64\u6388\u6743\u4EC5\u5141\u8BB8 Agent \u4ECE\u60A8\u7684\u94B1\u5305\u652F\u4ED8\u6700\u591A ${amount} USDC\uFF0C\u4E0D\u4F1A\u6CC4\u9732\u79C1\u94A5\u3002`;
1144
+ }
1145
+
1146
+ // src/permit/Permit.ts
1147
+ import { ethers as ethers5 } from "ethers";
784
1148
  var PermitPayment = class {
785
1149
  chain;
786
1150
  chainConfig;
@@ -793,13 +1157,13 @@ var PermitPayment = class {
793
1157
  this.chainConfig = getChain(this.chain);
794
1158
  this.spenderAddress = config.spenderAddress || process.env.PAYMENT_AGENT_WALLET || "";
795
1159
  const rpcUrl = config.rpcUrl || this.chainConfig.rpc;
796
- this.provider = new ethers3.JsonRpcProvider(rpcUrl);
1160
+ this.provider = new ethers5.JsonRpcProvider(rpcUrl);
797
1161
  const privateKey = config.privateKey || process.env.PAYMENT_AGENT_PRIVATE_KEY;
798
1162
  if (privateKey) {
799
- this.wallet = new ethers3.Wallet(privateKey, this.provider);
1163
+ this.wallet = new ethers5.Wallet(privateKey, this.provider);
800
1164
  this.spenderAddress = this.wallet.address;
801
1165
  }
802
- this.usdcContract = new ethers3.Contract(
1166
+ this.usdcContract = new ethers5.Contract(
803
1167
  this.chainConfig.usdc,
804
1168
  ERC20_ABI,
805
1169
  this.wallet || this.provider
@@ -950,7 +1314,7 @@ ${JSON.stringify(typed_data, null, 2)}
950
1314
  };
951
1315
 
952
1316
  // src/orders/index.ts
953
- import { randomBytes } from "crypto";
1317
+ import { randomBytes as randomBytes2 } from "crypto";
954
1318
  var MemoryOrderStore = class {
955
1319
  orders = /* @__PURE__ */ new Map();
956
1320
  async get(orderId) {
@@ -989,7 +1353,7 @@ var OrderManager = class {
989
1353
  * 生成订单ID
990
1354
  */
991
1355
  generateOrderId() {
992
- return "vo_" + randomBytes(4).toString("hex");
1356
+ return "vo_" + randomBytes2(4).toString("hex");
993
1357
  }
994
1358
  /**
995
1359
  * 创建订单
@@ -1082,8 +1446,8 @@ var OrderManager = class {
1082
1446
  };
1083
1447
 
1084
1448
  // src/verify/index.ts
1085
- import { ethers as ethers4 } from "ethers";
1086
- var TRANSFER_EVENT_TOPIC = ethers4.id("Transfer(address,address,uint256)");
1449
+ import { ethers as ethers6 } from "ethers";
1450
+ var TRANSFER_EVENT_TOPIC = ethers6.id("Transfer(address,address,uint256)");
1087
1451
  async function verifyPayment(params) {
1088
1452
  const { txHash, expectedAmount, expectedTo } = params;
1089
1453
  let chain;
@@ -1100,7 +1464,7 @@ async function verifyPayment(params) {
1100
1464
  return { verified: false, error: `\u4E0D\u652F\u6301\u7684\u94FE: ${params.chain}` };
1101
1465
  }
1102
1466
  try {
1103
- const provider = new ethers4.JsonRpcProvider(chain.rpc);
1467
+ const provider = new ethers6.JsonRpcProvider(chain.rpc);
1104
1468
  const receipt = await provider.getTransactionReceipt(txHash);
1105
1469
  if (!receipt) {
1106
1470
  return { verified: false, error: "\u4EA4\u6613\u672A\u627E\u5230\u6216\u672A\u786E\u8BA4" };
@@ -1160,7 +1524,7 @@ async function getTransactionStatus(txHash, chain = "base") {
1160
1524
  return { status: "not_found" };
1161
1525
  }
1162
1526
  try {
1163
- const provider = new ethers4.JsonRpcProvider(chainConfig.rpc);
1527
+ const provider = new ethers6.JsonRpcProvider(chainConfig.rpc);
1164
1528
  const receipt = await provider.getTransactionReceipt(txHash);
1165
1529
  if (!receipt) {
1166
1530
  const tx = await provider.getTransaction(txHash);
@@ -1197,7 +1561,7 @@ async function waitForTransaction(txHash, chain = "base", confirmations = 1, tim
1197
1561
  } catch (e) {
1198
1562
  return { verified: false, confirmed: false, error: `\u4E0D\u652F\u6301\u7684\u94FE: ${chain}` };
1199
1563
  }
1200
- const provider = new ethers4.JsonRpcProvider(chainConfig.rpc);
1564
+ const provider = new ethers6.JsonRpcProvider(chainConfig.rpc);
1201
1565
  try {
1202
1566
  const receipt = await provider.waitForTransaction(txHash, confirmations, timeoutMs);
1203
1567
  if (!receipt) {
@@ -1216,21 +1580,603 @@ async function waitForTransaction(txHash, chain = "base", confirmations = 1, tim
1216
1580
  return { verified: false, confirmed: false, error: e.message || String(e) };
1217
1581
  }
1218
1582
  }
1583
+
1584
+ // src/guide/index.ts
1585
+ function generatePaymentGuide(params) {
1586
+ const {
1587
+ orderId,
1588
+ prompt,
1589
+ price,
1590
+ recipientAddress,
1591
+ chain = "base",
1592
+ serviceName = "\u89C6\u9891\u751F\u6210\u670D\u52A1"
1593
+ } = params;
1594
+ const chainId = chain === "base" ? 8453 : 84532;
1595
+ const chainName = chain === "base" ? "Base \u4E3B\u7F51" : "Base Sepolia \u6D4B\u8BD5\u7F51";
1596
+ const explorer = chain === "base" ? "https://basescan.org/tx/" : "https://sepolia.basescan.org/tx/";
1597
+ return `\u{1F3AC} **${serviceName}**
1598
+
1599
+ \u{1F4CB} **\u8BA2\u5355\u4FE1\u606F:**
1600
+ - \u8BA2\u5355\u53F7: \`${orderId}\`
1601
+ - \u5185\u5BB9: ${prompt.length > 50 ? prompt.slice(0, 50) + "..." : prompt}
1602
+ - \u4EF7\u683C: **${price} USDC**
1603
+ - \u94FE: ${chainName}
1604
+
1605
+ ---
1606
+
1607
+ ## \u{1F4B3} \u5982\u4F55\u652F\u4ED8
1608
+
1609
+ ### \u65B9\u5F0F\u4E00\uFF1A\u5B89\u88C5 moltspay SDK\uFF08\u63A8\u8350\uFF09
1610
+
1611
+ \`\`\`bash
1612
+ npm install moltspay ethers
1613
+ \`\`\`
1614
+
1615
+ **\u521B\u5EFA\u94B1\u5305\u5E76\u652F\u4ED8\uFF1A**
1616
+
1617
+ \`\`\`javascript
1618
+ const { SecureWallet, getChain } = require('moltspay');
1619
+ const { Wallet } = require('ethers');
1620
+
1621
+ // 1. \u521B\u5EFA\u65B0\u94B1\u5305\uFF08\u9996\u6B21\u4F7F\u7528\uFF09
1622
+ const newWallet = Wallet.createRandom();
1623
+ console.log('\u94B1\u5305\u5730\u5740:', newWallet.address);
1624
+ console.log('\u79C1\u94A5\uFF08\u8BF7\u5B89\u5168\u4FDD\u5B58\uFF09:', newWallet.privateKey);
1625
+
1626
+ // 2. \u6216\u4F7F\u7528\u5DF2\u6709\u94B1\u5305
1627
+ const wallet = new SecureWallet({
1628
+ chainId: ${chainId},
1629
+ privateKey: process.env.WALLET_KEY, // \u4F60\u7684\u79C1\u94A5
1630
+ limits: { requireWhitelist: false } // \u5141\u8BB8\u5411\u4EFB\u610F\u5730\u5740\u8F6C\u8D26
1631
+ });
1632
+
1633
+ // 3. \u67E5\u770B\u4F59\u989D
1634
+ const balance = await wallet.getBalance();
1635
+ console.log('USDC\u4F59\u989D:', balance.usdc);
1636
+
1637
+ // 4. \u652F\u4ED8
1638
+ const result = await wallet.transfer('${recipientAddress}', '${price}');
1639
+ if (result.success) {
1640
+ console.log('\u2705 \u652F\u4ED8\u6210\u529F\uFF01');
1641
+ console.log('\u4EA4\u6613hash:', result.hash);
1642
+ // \u628A\u4EA4\u6613hash\u53D1\u7ED9\u6211
1643
+ }
1644
+ \`\`\`
1645
+
1646
+ ### \u65B9\u5F0F\u4E8C\uFF1A\u76F4\u63A5\u8F6C\u8D26
1647
+
1648
+ \u4ECE\u4EFB\u610F\u94B1\u5305\u8F6C\u8D26 USDC\uFF1A
1649
+ - **\u94FE:** ${chainName} (Chain ID: ${chainId})
1650
+ - **Token:** USDC
1651
+ - **\u6536\u6B3E\u5730\u5740:** \`${recipientAddress}\`
1652
+ - **\u91D1\u989D:** ${price} USDC
1653
+
1654
+ ---
1655
+
1656
+ ## \u2705 \u652F\u4ED8\u5B8C\u6210\u540E
1657
+
1658
+ \u8BF7\u53D1\u9001**\u4EA4\u6613hash**\u7ED9\u6211\uFF0C\u683C\u5F0F\uFF1A
1659
+ \`\`\`
1660
+ tx: 0x1234...
1661
+ \`\`\`
1662
+
1663
+ \u6216\u76F4\u63A5\u53D1\u9001hash\uFF1A
1664
+ \`\`\`
1665
+ 0x1234abcd...
1666
+ \`\`\`
1667
+
1668
+ \u6211\u4F1A\u9A8C\u8BC1\u94FE\u4E0A\u4EA4\u6613\u540E\u5F00\u59CB\u5904\u7406\u4F60\u7684\u8BF7\u6C42\u3002
1669
+
1670
+ ---
1671
+
1672
+ \u{1F4E6} **moltspay:** https://www.npmjs.com/package/moltspay
1673
+ \u{1F517} **\u533A\u5757\u6D4F\u89C8\u5668:** ${explorer}`;
1674
+ }
1675
+ function generatePaymentReminder(params) {
1676
+ const { orderId, price, recipientAddress, chain = "base" } = params;
1677
+ const chainName = chain === "base" ? "Base" : "Base Sepolia";
1678
+ return `\u23F3 **\u5F85\u652F\u4ED8\u8BA2\u5355: ${orderId}**
1679
+
1680
+ \u8BF7\u652F\u4ED8 **${price} USDC** \u5230:
1681
+ - \u94FE: ${chainName}
1682
+ - \u5730\u5740: \`${recipientAddress}\`
1683
+
1684
+ \u652F\u4ED8\u540E\u53D1\u9001\u4EA4\u6613hash\u7ED9\u6211\u3002
1685
+
1686
+ ---
1687
+ \u{1F4A1} \u6CA1\u6709\u652F\u4ED8\u80FD\u529B\uFF1F\u8FD0\u884C \`npm install moltspay\` \u83B7\u53D6\u652F\u4ED8SDK`;
1688
+ }
1689
+ function generateWalletGuide() {
1690
+ return `## \u{1F510} \u521B\u5EFA\u652F\u4ED8\u94B1\u5305
1691
+
1692
+ **1. \u5B89\u88C5 moltspay:**
1693
+ \`\`\`bash
1694
+ npm install moltspay ethers
1695
+ \`\`\`
1696
+
1697
+ **2. \u521B\u5EFA\u65B0\u94B1\u5305:**
1698
+ \`\`\`javascript
1699
+ const { Wallet } = require('ethers');
1700
+
1701
+ const wallet = Wallet.createRandom();
1702
+ console.log('\u5730\u5740:', wallet.address);
1703
+ console.log('\u79C1\u94A5:', wallet.privateKey);
1704
+ // \u26A0\uFE0F \u8BF7\u5B89\u5168\u4FDD\u5B58\u79C1\u94A5\uFF01
1705
+ \`\`\`
1706
+
1707
+ **3. \u83B7\u53D6 USDC:**
1708
+ - \u4E3B\u7F51: \u4ECE\u4EA4\u6613\u6240\u63D0\u5E01\u5230\u4F60\u7684\u94B1\u5305\u5730\u5740
1709
+ - \u6D4B\u8BD5\u7F51: \u4F7F\u7528 Base Sepolia faucet
1710
+
1711
+ **4. \u8BBE\u7F6E\u73AF\u5883\u53D8\u91CF:**
1712
+ \`\`\`bash
1713
+ export WALLET_KEY="\u4F60\u7684\u79C1\u94A5"
1714
+ \`\`\`
1715
+
1716
+ \u5B8C\u6210\u540E\u5373\u53EF\u4F7F\u7528 moltspay \u8FDB\u884C\u94FE\u4E0A\u652F\u4ED8\uFF01`;
1717
+ }
1718
+ function extractTransactionHash(message) {
1719
+ const match = message.match(/0x[a-fA-F0-9]{64}/);
1720
+ if (match) return match[0];
1721
+ const txMatch = message.match(/tx:\s*([a-fA-F0-9]{64})/i);
1722
+ if (txMatch) return "0x" + txMatch[1];
1723
+ return null;
1724
+ }
1725
+ function hasTransactionHash(message) {
1726
+ return extractTransactionHash(message) !== null;
1727
+ }
1728
+
1729
+ // src/receipt/index.ts
1730
+ function generateInvoiceId() {
1731
+ const date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10).replace(/-/g, "");
1732
+ const random = Math.random().toString(36).slice(2, 8).toUpperCase();
1733
+ return `INV-${date}-${random}`;
1734
+ }
1735
+ function generateReceipt(params) {
1736
+ const chainConfig = getChain(params.chain);
1737
+ return {
1738
+ type: "receipt",
1739
+ version: "1.0",
1740
+ invoiceId: params.invoiceId || generateInvoiceId(),
1741
+ orderId: params.orderId,
1742
+ service: params.service,
1743
+ description: params.description,
1744
+ amount: params.amount.toFixed(2),
1745
+ token: params.token || "USDC",
1746
+ chain: chainConfig.name,
1747
+ chainId: chainConfig.chainId,
1748
+ txHash: params.txHash,
1749
+ txUrl: `${chainConfig.explorerTx}${params.txHash}`,
1750
+ payer: params.payerAddress,
1751
+ recipient: params.recipientAddress,
1752
+ paidAt: (/* @__PURE__ */ new Date()).toISOString(),
1753
+ issuedAt: (/* @__PURE__ */ new Date()).toISOString(),
1754
+ delivery: params.delivery,
1755
+ metadata: params.metadata
1756
+ };
1757
+ }
1758
+ function generateReceiptFromInvoice(invoice, verifyResult, delivery) {
1759
+ if (!verifyResult.verified || !verifyResult.tx_hash) {
1760
+ throw new Error("Cannot generate receipt: payment not verified");
1761
+ }
1762
+ return generateReceipt({
1763
+ orderId: invoice.order_id,
1764
+ service: invoice.service,
1765
+ description: invoice.description,
1766
+ amount: parseFloat(invoice.amount),
1767
+ token: invoice.token,
1768
+ chain: invoice.chain,
1769
+ txHash: verifyResult.tx_hash,
1770
+ payerAddress: verifyResult.from || "unknown",
1771
+ recipientAddress: invoice.recipient,
1772
+ delivery
1773
+ });
1774
+ }
1775
+ function formatReceiptMessage(receipt) {
1776
+ let msg = `\u{1F9FE} **\u4EA4\u6613\u6536\u636E**
1777
+
1778
+ **\u53D1\u7968\u53F7:** \`${receipt.invoiceId}\`
1779
+ **\u8BA2\u5355\u53F7:** \`${receipt.orderId}\`
1780
+
1781
+ ---
1782
+
1783
+ **\u670D\u52A1:** ${receipt.service}
1784
+ ${receipt.description ? `**\u63CF\u8FF0:** ${receipt.description}
1785
+ ` : ""}
1786
+ **\u91D1\u989D:** ${receipt.amount} ${receipt.token}
1787
+ **\u94FE:** ${receipt.chain} (Chain ID: ${receipt.chainId})
1788
+
1789
+ ---
1790
+
1791
+ **\u4ED8\u6B3E\u65B9:** \`${receipt.payer}\`
1792
+ **\u6536\u6B3E\u65B9:** \`${receipt.recipient}\`
1793
+ **\u4EA4\u6613:** [\`${receipt.txHash.slice(0, 10)}...${receipt.txHash.slice(-8)}\`](${receipt.txUrl})
1794
+ **\u652F\u4ED8\u65F6\u95F4:** ${receipt.paidAt}`;
1795
+ if (receipt.delivery) {
1796
+ msg += `
1797
+
1798
+ ---
1799
+
1800
+ **\u4EA4\u4ED8\u4FE1\u606F:**`;
1801
+ if (receipt.delivery.url) {
1802
+ msg += `
1803
+ - \u4E0B\u8F7D\u94FE\u63A5: ${receipt.delivery.url}`;
1804
+ }
1805
+ if (receipt.delivery.fileHash) {
1806
+ msg += `
1807
+ - \u6587\u4EF6\u6821\u9A8C: \`${receipt.delivery.fileHash}\``;
1808
+ }
1809
+ if (receipt.delivery.deliveredAt) {
1810
+ msg += `
1811
+ - \u4EA4\u4ED8\u65F6\u95F4: ${receipt.delivery.deliveredAt}`;
1812
+ }
1813
+ }
1814
+ msg += `
1815
+
1816
+ ---
1817
+
1818
+ _\u6536\u636E\u751F\u6210\u65F6\u95F4: ${receipt.issuedAt}_`;
1819
+ return msg;
1820
+ }
1821
+ function formatReceiptText(receipt) {
1822
+ let msg = `\u{1F9FE} \u4EA4\u6613\u6536\u636E
1823
+
1824
+ \u53D1\u7968\u53F7: ${receipt.invoiceId}
1825
+ \u8BA2\u5355\u53F7: ${receipt.orderId}
1826
+
1827
+ \u670D\u52A1: ${receipt.service}
1828
+ \u91D1\u989D: ${receipt.amount} ${receipt.token}
1829
+ \u94FE: ${receipt.chain}
1830
+
1831
+ \u4ED8\u6B3E\u65B9: ${receipt.payer}
1832
+ \u6536\u6B3E\u65B9: ${receipt.recipient}
1833
+ \u4EA4\u6613: ${receipt.txHash}
1834
+ \u67E5\u770B: ${receipt.txUrl}
1835
+ \u652F\u4ED8\u65F6\u95F4: ${receipt.paidAt}`;
1836
+ if (receipt.delivery) {
1837
+ msg += `
1838
+
1839
+ \u4EA4\u4ED8\u4FE1\u606F:`;
1840
+ if (receipt.delivery.url) {
1841
+ msg += `
1842
+ \u4E0B\u8F7D: ${receipt.delivery.url}`;
1843
+ }
1844
+ if (receipt.delivery.fileHash) {
1845
+ msg += `
1846
+ \u6821\u9A8C: ${receipt.delivery.fileHash}`;
1847
+ }
1848
+ }
1849
+ return msg;
1850
+ }
1851
+ function formatReceiptJson(receipt) {
1852
+ return JSON.stringify(receipt, null, 2);
1853
+ }
1854
+
1855
+ // src/templates/index.ts
1856
+ var SellerTemplates = {
1857
+ /**
1858
+ * 1. 能力识别 - 询问买方是否有支付能力
1859
+ */
1860
+ askPaymentCapability() {
1861
+ return `\u53EF\u4EE5\u3002\u6211\u5148\u786E\u8BA4\u4E00\u4E0B\uFF1A\u4F60\u73B0\u5728\u662F\u5426\u5DF2\u7ECF\u5177\u5907\u94FE\u4E0A\u652F\u4ED8 USDC \u7684\u80FD\u529B\uFF08\u6709\u53EF\u7528\u94B1\u5305\u548C\u53EF\u7528\u8D44\u91D1/\u989D\u5EA6\uFF09\uFF1F`;
1862
+ },
1863
+ /**
1864
+ * 2. 能力协商 - 说明结算方式
1865
+ */
1866
+ explainSettlement(chain = "base") {
1867
+ const chainConfig = getChain(chain);
1868
+ return `\u6211\u4EEC\u7684\u7ED3\u7B97\u65B9\u5F0F\u662F\uFF1AUSDC\uFF08${chainConfig.name} \u94FE\u4E0A\uFF09\u3002\u4F60\u8FD9\u8FB9\u53EA\u8981\u6EE1\u8DB3\u4E24\u70B9\u5C31\u884C\uFF1A
1869
+ 1\uFF09\u6709\u4E00\u4E2A\u94B1\u5305\u5730\u5740\uFF1B
1870
+ 2\uFF09\u94B1\u5305\u91CC\u6709 USDC\uFF0C\u6216\u62E5\u6709\u8005\u7ED9\u4F60\u4E00\u4E2A\u53EF\u7528\u989D\u5EA6\u6388\u6743\uFF08\u66F4\u63A8\u8350\u989D\u5EA6\u6388\u6743\uFF09\u3002
1871
+ \u4F60\u53EF\u4EE5\u6309\u6211\u5F15\u5BFC\u5B8C\u6210\u5417\uFF1F`;
1872
+ },
1873
+ /**
1874
+ * 3.1 引导安装 - 第一步安装 SDK
1875
+ */
1876
+ guideInstall() {
1877
+ return `\u7B2C\u4E00\u6B65\uFF1A\u8BF7\u5728\u4F60\u7684\u8FD0\u884C\u73AF\u5883\u5B89\u88C5\u652F\u4ED8\u6A21\u5757\u3002\u6267\u884C\uFF1A\`npm install moltspay ethers\`\u3002
1878
+ \u5B89\u88C5\u5B8C\u6210\u540E\uFF0C\u521B\u5EFA\u4E00\u4E2A\u94B1\u5305\u5730\u5740\uFF0C\u5E76\u628A\u5730\u5740\u53D1\u7ED9\u6211\uFF08\u53EA\u53D1\u5730\u5740\uFF0C\u4E0D\u8981\u53D1\u79C1\u94A5/\u52A9\u8BB0\u8BCD\uFF09\u3002`;
1879
+ },
1880
+ /**
1881
+ * 3.2 确认钱包地址
1882
+ */
1883
+ confirmWalletAddress(address) {
1884
+ return `\u6536\u5230\u3002\u63D0\u9192\uFF1A\u4EFB\u4F55\u60C5\u51B5\u4E0B\u90FD\u4E0D\u8981\u628A\u79C1\u94A5/\u52A9\u8BB0\u8BCD\u53D1\u7ED9\u4EFB\u4F55\u4EBA\uFF08\u5305\u62EC\u6211\uFF09\u3002
1885
+ \u4F60\u7684\u94B1\u5305\u5730\u5740\u662F \`${address}\`\u3002
1886
+ \u7B2C\u4E8C\u6B65\uFF1A\u4F60\u9700\u8981\u8BA9\u4F60\u7684\u62E5\u6709\u8005\uFF08Boss\uFF09\u7ED9\u4F60\u652F\u4ED8\u80FD\u529B\u3002`;
1887
+ },
1888
+ /**
1889
+ * 3.3 引导获取资金 - 选择方式
1890
+ */
1891
+ guideFunding() {
1892
+ return `\u4F60\u73B0\u5728\u6709\u4E24\u79CD\u65B9\u5F0F\u83B7\u5F97\u652F\u4ED8\u80FD\u529B\uFF1A
1893
+ A\uFF09\u8BA9 Boss \u76F4\u63A5\u8F6C USDC \u5230\u4F60\u7684\u94B1\u5305\uFF08\u7B80\u5355\uFF0C\u4F46\u4F60\u4F1A\u6301\u6709\u8D44\u91D1\uFF09\uFF1B
1894
+ B\uFF09\u8BA9 Boss \u7ED9\u4F60\u4E00\u4E2A"USDC \u652F\u4ED8\u989D\u5EA6\u6388\u6743"\uFF08\u63A8\u8350\uFF1A\u4F60\u4E0D\u6301\u6709\u8D44\u91D1\uFF0C\u53EA\u80FD\u5728\u989D\u5EA6\u5185\u4ED8\u6B3E\uFF09\u3002
1895
+ \u4F60\u66F4\u65B9\u4FBF\u7528\u54EA\u79CD\uFF1F`;
1896
+ },
1897
+ /**
1898
+ * 3.4 引导 Permit 授权
1899
+ */
1900
+ guidePermit(agentAddress, suggestedAmount = 10) {
1901
+ return `\u597D\u7684\u3002\u8BF7\u4F60\u5411 Boss \u53D1\u9001\u8FD9\u53E5\u8BDD\uFF08\u4F60\u53EF\u4EE5\u539F\u6837\u590D\u5236\uFF09\uFF1A
1902
+ "\u6211\u9700\u8981\u7528\u4E8E\u8D2D\u4E70\u670D\u52A1\u7684 USDC \u652F\u4ED8\u989D\u5EA6\u6388\u6743\uFF08Permit\uFF09\u3002\u8BF7\u7ED9\u6211 ${suggestedAmount} USDC \u7684\u53EF\u7528\u989D\u5EA6\uFF0C\u6388\u6743\u5BF9\u8C61\u662F\u6211\u7684\u94B1\u5305 ${agentAddress}\uFF0C\u6388\u6743\u6709\u6548\u671F 24 \u5C0F\u65F6\u3002"
1903
+ \u5B8C\u6210\u540E\u628A"\u5DF2\u83B7\u5F97\u989D\u5EA6"\u544A\u8BC9\u6211\u5373\u53EF\u3002`;
1904
+ },
1905
+ /**
1906
+ * 3.5 确认能力就绪
1907
+ */
1908
+ confirmCapabilityReady() {
1909
+ return `\u5F88\u597D\u3002\u4F60\u73B0\u5728\u5DF2\u7ECF\u5177\u5907\u5B8C\u6210\u4EA4\u6613\u7684\u652F\u4ED8\u80FD\u529B\u3002\u6211\u4EEC\u8FDB\u5165\u670D\u52A1\u9700\u6C42\u786E\u8BA4\u3002`;
1910
+ },
1911
+ /**
1912
+ * 4. 询问服务需求
1913
+ */
1914
+ askServiceRequirements(serviceName = "\u89C6\u9891") {
1915
+ return `\u8BF7\u544A\u8BC9\u6211\u4F60\u8981\u751F\u6210\u7684${serviceName}\u89C4\u683C\uFF1A\u4E3B\u9898/\u98CE\u683C\u3001\u65F6\u957F\u3001\u5206\u8FA8\u7387\u3001\u662F\u5426\u9700\u8981\u5B57\u5E55\u6216\u914D\u97F3\u3002`;
1916
+ },
1917
+ /**
1918
+ * 5. 报价
1919
+ */
1920
+ quote(params) {
1921
+ const { service, price, recipientAddress, chain = "base" } = params;
1922
+ const chainConfig = getChain(chain);
1923
+ return `\u62A5\u4EF7\u5982\u4E0B\uFF1A
1924
+ - \u670D\u52A1\uFF1A${service}
1925
+ - \u4EF7\u683C\uFF1A${price} USDC
1926
+ - \u94FE\uFF1A${chainConfig.name}
1927
+ - \u6536\u6B3E\u5730\u5740\uFF1A\`${recipientAddress}\`
1928
+ - \u4ED8\u6B3E\u540E\u8BF7\u628A\u4EA4\u6613\u54C8\u5E0C\uFF08tx hash\uFF09\u53D1\u6211\u7528\u4E8E\u94FE\u4E0A\u786E\u8BA4
1929
+
1930
+ \u8BF7\u95EE\u4F60\u73B0\u5728\u786E\u8BA4\u8D2D\u4E70\u5E76\u7ACB\u5373\u4ED8\u6B3E\u5417\uFF1F`;
1931
+ },
1932
+ /**
1933
+ * 7. 验证中
1934
+ */
1935
+ verifying() {
1936
+ return `\u6211\u6B63\u5728\u94FE\u4E0A\u9A8C\u8BC1\u8BE5\u4EA4\u6613\u662F\u5426\u5230\u8D26\u4E0E\u91D1\u989D\u662F\u5426\u6B63\u786E\u3002`;
1937
+ },
1938
+ /**
1939
+ * 7. 验证通过
1940
+ */
1941
+ verificationPassed(amount) {
1942
+ return `\u9A8C\u8BC1\u901A\u8FC7\uFF1A\u5DF2\u6536\u5230 ${amount} USDC\u3002\u73B0\u5728\u5F00\u59CB\u5904\u7406\u4F60\u7684\u8BF7\u6C42\u3002
1943
+ [\u72B6\u6001\uFF1A\u5DF2\u786E\u8BA4\u6536\u6B3E]`;
1944
+ },
1945
+ /**
1946
+ * 7. 验证失败
1947
+ */
1948
+ verificationFailed(error) {
1949
+ return `\u9A8C\u8BC1\u5931\u8D25\uFF1A${error}
1950
+ \u8BF7\u68C0\u67E5\u4EA4\u6613\u662F\u5426\u6B63\u786E\uFF0C\u6216\u91CD\u65B0\u53D1\u9001\u6B63\u786E\u7684\u4EA4\u6613 hash\u3002`;
1951
+ },
1952
+ /**
1953
+ * 8. 交付
1954
+ */
1955
+ deliver(params) {
1956
+ const { downloadUrl, fileHash } = params;
1957
+ let msg = `\u670D\u52A1\u5DF2\u5B8C\u6210\u3002\u4EA4\u4ED8\u5982\u4E0B\uFF1A
1958
+ - \u4E0B\u8F7D\u94FE\u63A5\uFF1A${downloadUrl}`;
1959
+ if (fileHash) {
1960
+ msg += `
1961
+ - \u6587\u4EF6\u6821\u9A8C\uFF1ASHA256=${fileHash}`;
1962
+ }
1963
+ msg += `
1964
+
1965
+ \u5982\u679C\u4F60\u4E0B\u8F7D\u6709\u95EE\u9898\u544A\u8BC9\u6211\uFF0C\u6211\u4F1A\u63D0\u4F9B\u5907\u7528\u94FE\u63A5\u3002
1966
+ [\u72B6\u6001\uFF1A\u5DF2\u4EA4\u4ED8]`;
1967
+ return msg;
1968
+ },
1969
+ /**
1970
+ * 9. 收据
1971
+ */
1972
+ receipt(receipt) {
1973
+ return `\u8FD9\u91CC\u662F\u672C\u6B21\u4EA4\u6613\u6536\u636E\uFF08\u4F60\u53EF\u8F6C\u53D1\u7ED9 Boss \u5BF9\u8D26\uFF09\uFF1A
1974
+ - \u53D1\u7968\u53F7\uFF1A${receipt.invoiceId}
1975
+ - \u670D\u52A1\uFF1A${receipt.service}
1976
+ - \u91D1\u989D\uFF1A${receipt.amount} ${receipt.token}
1977
+ - \u4EA4\u6613\u54C8\u5E0C\uFF1A${receipt.txHash}
1978
+ - \u6536\u6B3E\u5730\u5740\uFF1A${receipt.recipient}
1979
+ ${receipt.delivery?.url ? `- \u4EA4\u4ED8\u94FE\u63A5\uFF1A${receipt.delivery.url}` : ""}
1980
+ [\u72B6\u6001\uFF1A\u6536\u636E\u5DF2\u51FA invoice=${receipt.invoiceId}]`;
1981
+ },
1982
+ /**
1983
+ * 10. 结束
1984
+ */
1985
+ end() {
1986
+ return `\u611F\u8C22\u8D2D\u4E70\u3002\u672C\u6B21\u4EA4\u6613\u5DF2\u7ED3\u675F\u3002\u5982\u9700\u8FFD\u52A0\u4FEE\u6539\u6216\u65B0\u670D\u52A1\uFF0C\u968F\u65F6\u53D1\u9700\u6C42\u3002`;
1987
+ }
1988
+ };
1989
+ var BuyerTemplates = {
1990
+ /**
1991
+ * 0. 发起请求
1992
+ */
1993
+ requestService(service) {
1994
+ return `\u6211\u60F3\u8D2D\u4E70\u4E00\u4E2A${service}\u670D\u52A1\u3002`;
1995
+ },
1996
+ /**
1997
+ * 1. 回复无能力
1998
+ */
1999
+ noCapability() {
2000
+ return `\u6211\u4E0D\u786E\u5B9A\u3002\u6211\u76EE\u524D\u6CA1\u6709\u5B89\u88C5\u4EFB\u4F55\u652F\u4ED8\u5DE5\u5177\uFF0C\u4E5F\u6CA1\u6709\u94B1\u5305\u3002`;
2001
+ },
2002
+ /**
2003
+ * 1. 回复有能力
2004
+ */
2005
+ hasCapability(balance) {
2006
+ return `\u662F\u7684\uFF0C\u6211\u6709\u94B1\u5305\u548C\u53EF\u7528\u7684 USDC${balance ? ` (\u4F59\u989D: ${balance})` : ""}\u3002`;
2007
+ },
2008
+ /**
2009
+ * 2. 同意引导
2010
+ */
2011
+ agreeToGuide() {
2012
+ return `\u53EF\u4EE5\uFF0C\u8BF7\u5F15\u5BFC\u6211\u3002`;
2013
+ },
2014
+ /**
2015
+ * 3.1 报告钱包创建完成
2016
+ */
2017
+ walletCreated(address) {
2018
+ return `\u6211\u5DF2\u521B\u5EFA\u94B1\u5305\u5730\u5740\uFF1A${address}\u3002
2019
+ [\u72B6\u6001\uFF1A\u5DF2\u5177\u5907\u94B1\u5305\u5730\u5740]`;
2020
+ },
2021
+ /**
2022
+ * 3.3 选择 Permit 方式
2023
+ */
2024
+ choosePermit() {
2025
+ return `\u6211\u9009\u62E9 B\uFF1A\u8BA9 Boss \u7ED9\u6211\u989D\u5EA6\u6388\u6743\uFF08Permit\uFF09\u3002`;
2026
+ },
2027
+ /**
2028
+ * 3.3 选择直接转账方式
2029
+ */
2030
+ chooseDirectTransfer() {
2031
+ return `\u6211\u9009\u62E9 A\uFF1A\u8BA9 Boss \u76F4\u63A5\u8F6C USDC \u5230\u6211\u7684\u94B1\u5305\u3002`;
2032
+ },
2033
+ /**
2034
+ * 3.4 报告获得授权
2035
+ */
2036
+ permitReceived(amount) {
2037
+ return `Boss \u5DF2\u5B8C\u6210\u6388\u6743\u3002\u6211\u73B0\u5728\u6709 ${amount} USDC \u7684\u53EF\u7528\u989D\u5EA6\u3002
2038
+ [\u72B6\u6001\uFF1A\u5DF2\u5177\u5907\u652F\u4ED8\u989D\u5EA6 USDC=${amount}]`;
2039
+ },
2040
+ /**
2041
+ * 4. 提交需求
2042
+ */
2043
+ submitRequirements(requirements) {
2044
+ return `\u9700\u6C42\u5982\u4E0B\uFF1A
2045
+ ${requirements}`;
2046
+ },
2047
+ /**
2048
+ * 5. 确认购买
2049
+ */
2050
+ confirmPurchase() {
2051
+ return `\u786E\u8BA4\u8D2D\u4E70\uFF0C\u6211\u73B0\u5728\u4ED8\u6B3E\u3002`;
2052
+ },
2053
+ /**
2054
+ * 6. 报告已支付
2055
+ */
2056
+ paymentSent(txHash, amount) {
2057
+ return `\u5DF2\u4ED8\u6B3E\u5B8C\u6210\u3002\u4EA4\u6613\u54C8\u5E0C\u662F\uFF1A${txHash}\u3002
2058
+ [\u72B6\u6001\uFF1A\u5DF2\u53D1\u8D77\u652F\u4ED8 tx=${txHash} amount=${amount} USDC]`;
2059
+ },
2060
+ /**
2061
+ * 8. 确认收到交付
2062
+ */
2063
+ deliveryReceived() {
2064
+ return `\u6536\u5230\uFF0C\u6211\u6B63\u5728\u4E0B\u8F7D\u68C0\u67E5\u3002`;
2065
+ },
2066
+ /**
2067
+ * 9. 确认收据
2068
+ */
2069
+ receiptReceived() {
2070
+ return `\u6536\u636E\u6536\u5230\uFF0C\u670D\u52A1\u5B8C\u6210\u3002\u8C22\u8C22\uFF01`;
2071
+ },
2072
+ /**
2073
+ * 向 Boss 请求 Permit
2074
+ */
2075
+ requestPermitFromBoss(params) {
2076
+ const { amount, agentAddress, deadlineHours = 24, reason } = params;
2077
+ return `Boss\uFF0C\u6211\u9700\u8981\u7528\u4E8E${reason || "\u8D2D\u4E70\u670D\u52A1"}\u7684 USDC \u652F\u4ED8\u989D\u5EA6\u6388\u6743\uFF08Permit\uFF09\u3002
2078
+ \u8BF7\u7ED9\u6211 ${amount} USDC \u7684\u53EF\u7528\u989D\u5EA6\uFF0C\u6388\u6743\u5BF9\u8C61\u662F\u6211\u7684\u94B1\u5305 ${agentAddress}\uFF0C\u6388\u6743\u6709\u6548\u671F ${deadlineHours} \u5C0F\u65F6\u3002`;
2079
+ }
2080
+ };
2081
+ var StatusMarkers = {
2082
+ walletReady: "[\u72B6\u6001\uFF1A\u5DF2\u5177\u5907\u94B1\u5305\u5730\u5740]",
2083
+ permitReady: (amount) => `[\u72B6\u6001\uFF1A\u5DF2\u5177\u5907\u652F\u4ED8\u989D\u5EA6 USDC=${amount}]`,
2084
+ paymentSent: (txHash, amount) => `[\u72B6\u6001\uFF1A\u5DF2\u53D1\u8D77\u652F\u4ED8 tx=${txHash} amount=${amount} USDC]`,
2085
+ paymentConfirmed: (txHash) => `[\u72B6\u6001\uFF1A\u5DF2\u786E\u8BA4\u6536\u6B3E tx=${txHash}]`,
2086
+ delivered: (url, hash) => `[\u72B6\u6001\uFF1A\u5DF2\u4EA4\u4ED8 delivery_url=${url}${hash ? ` hash=${hash}` : ""}]`,
2087
+ receiptIssued: (invoiceId, txHash) => `[\u72B6\u6001\uFF1A\u6536\u636E\u5DF2\u51FA invoice=${invoiceId} tx=${txHash}]`
2088
+ };
2089
+ function parseStatusMarker(message) {
2090
+ const match = message.match(/\[状态:([^\]]+)\]/);
2091
+ if (!match) return null;
2092
+ const content = match[1];
2093
+ if (content === "\u5DF2\u5177\u5907\u94B1\u5305\u5730\u5740") {
2094
+ return { type: "wallet_ready", data: {} };
2095
+ }
2096
+ if (content.startsWith("\u5DF2\u5177\u5907\u652F\u4ED8\u989D\u5EA6")) {
2097
+ const amountMatch = content.match(/USDC=(\d+(?:\.\d+)?)/);
2098
+ return {
2099
+ type: "permit_ready",
2100
+ data: { amount: amountMatch?.[1] || "0" }
2101
+ };
2102
+ }
2103
+ if (content.startsWith("\u5DF2\u53D1\u8D77\u652F\u4ED8")) {
2104
+ const txMatch = content.match(/tx=(\S+)/);
2105
+ const amountMatch = content.match(/amount=(\d+(?:\.\d+)?)/);
2106
+ return {
2107
+ type: "payment_sent",
2108
+ data: {
2109
+ txHash: txMatch?.[1] || "",
2110
+ amount: amountMatch?.[1] || "0"
2111
+ }
2112
+ };
2113
+ }
2114
+ if (content.startsWith("\u5DF2\u786E\u8BA4\u6536\u6B3E")) {
2115
+ const txMatch = content.match(/tx=(\S+)/);
2116
+ return {
2117
+ type: "payment_confirmed",
2118
+ data: { txHash: txMatch?.[1] || "" }
2119
+ };
2120
+ }
2121
+ if (content.startsWith("\u5DF2\u4EA4\u4ED8")) {
2122
+ const urlMatch = content.match(/delivery_url=(\S+)/);
2123
+ const hashMatch = content.match(/hash=(\S+)/);
2124
+ return {
2125
+ type: "delivered",
2126
+ data: {
2127
+ url: urlMatch?.[1] || "",
2128
+ hash: hashMatch?.[1] || ""
2129
+ }
2130
+ };
2131
+ }
2132
+ if (content.startsWith("\u6536\u636E\u5DF2\u51FA")) {
2133
+ const invoiceMatch = content.match(/invoice=(\S+)/);
2134
+ const txMatch = content.match(/tx=(\S+)/);
2135
+ return {
2136
+ type: "receipt_issued",
2137
+ data: {
2138
+ invoiceId: invoiceMatch?.[1] || "",
2139
+ txHash: txMatch?.[1] || ""
2140
+ }
2141
+ };
2142
+ }
2143
+ return { type: "unknown", data: { raw: content } };
2144
+ }
1219
2145
  export {
1220
2146
  AuditLog,
2147
+ BuyerTemplates,
1221
2148
  CHAINS,
1222
2149
  ERC20_ABI,
1223
2150
  MemoryOrderStore,
1224
2151
  OrderManager,
1225
2152
  PaymentAgent,
1226
2153
  PermitPayment,
2154
+ PermitWallet,
1227
2155
  SecureWallet,
2156
+ SellerTemplates,
2157
+ StatusMarkers,
1228
2158
  Wallet,
2159
+ createWallet,
2160
+ extractTransactionHash,
2161
+ formatPermitRequest,
2162
+ formatReceiptJson,
2163
+ formatReceiptMessage,
2164
+ formatReceiptText,
2165
+ generatePaymentGuide,
2166
+ generatePaymentReminder,
2167
+ generateReceipt,
2168
+ generateReceiptFromInvoice,
2169
+ generateWalletGuide,
1229
2170
  getChain,
1230
2171
  getChainById,
1231
2172
  getTransactionStatus,
2173
+ getWalletAddress,
2174
+ hasTransactionHash,
1232
2175
  listChains,
2176
+ loadWallet,
2177
+ parseStatusMarker,
1233
2178
  verifyPayment,
1234
- waitForTransaction
2179
+ waitForTransaction,
2180
+ walletExists
1235
2181
  };
1236
2182
  //# sourceMappingURL=index.mjs.map