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/README.md +126 -0
- package/dist/cli.js +17 -3
- package/dist/cli.js.map +1 -1
- package/dist/cli.mjs +17 -3
- package/dist/cli.mjs.map +1 -1
- package/dist/guide/index.d.mts +39 -0
- package/dist/guide/index.d.ts +39 -0
- package/dist/guide/index.js +181 -0
- package/dist/guide/index.js.map +1 -0
- package/dist/guide/index.mjs +152 -0
- package/dist/guide/index.mjs.map +1 -0
- package/dist/index.d.mts +250 -2
- package/dist/index.d.ts +250 -2
- package/dist/index.js +979 -13
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +958 -12
- package/dist/index.mjs.map +1 -1
- package/dist/wallet/index.d.mts +188 -1
- package/dist/wallet/index.d.ts +188 -1
- package/dist/wallet/index.js +378 -2
- package/dist/wallet/index.js.map +1 -1
- package/dist/wallet/index.mjs +371 -1
- package/dist/wallet/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -31,20 +31,40 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
31
31
|
var src_exports = {};
|
|
32
32
|
__export(src_exports, {
|
|
33
33
|
AuditLog: () => AuditLog,
|
|
34
|
+
BuyerTemplates: () => BuyerTemplates,
|
|
34
35
|
CHAINS: () => CHAINS,
|
|
35
36
|
ERC20_ABI: () => ERC20_ABI,
|
|
36
37
|
MemoryOrderStore: () => MemoryOrderStore,
|
|
37
38
|
OrderManager: () => OrderManager,
|
|
38
39
|
PaymentAgent: () => PaymentAgent,
|
|
39
40
|
PermitPayment: () => PermitPayment,
|
|
41
|
+
PermitWallet: () => PermitWallet,
|
|
40
42
|
SecureWallet: () => SecureWallet,
|
|
43
|
+
SellerTemplates: () => SellerTemplates,
|
|
44
|
+
StatusMarkers: () => StatusMarkers,
|
|
41
45
|
Wallet: () => Wallet,
|
|
46
|
+
createWallet: () => createWallet,
|
|
47
|
+
extractTransactionHash: () => extractTransactionHash,
|
|
48
|
+
formatPermitRequest: () => formatPermitRequest,
|
|
49
|
+
formatReceiptJson: () => formatReceiptJson,
|
|
50
|
+
formatReceiptMessage: () => formatReceiptMessage,
|
|
51
|
+
formatReceiptText: () => formatReceiptText,
|
|
52
|
+
generatePaymentGuide: () => generatePaymentGuide,
|
|
53
|
+
generatePaymentReminder: () => generatePaymentReminder,
|
|
54
|
+
generateReceipt: () => generateReceipt,
|
|
55
|
+
generateReceiptFromInvoice: () => generateReceiptFromInvoice,
|
|
56
|
+
generateWalletGuide: () => generateWalletGuide,
|
|
42
57
|
getChain: () => getChain,
|
|
43
58
|
getChainById: () => getChainById,
|
|
44
59
|
getTransactionStatus: () => getTransactionStatus,
|
|
60
|
+
getWalletAddress: () => getWalletAddress,
|
|
61
|
+
hasTransactionHash: () => hasTransactionHash,
|
|
45
62
|
listChains: () => listChains,
|
|
63
|
+
loadWallet: () => loadWallet,
|
|
64
|
+
parseStatusMarker: () => parseStatusMarker,
|
|
46
65
|
verifyPayment: () => verifyPayment,
|
|
47
|
-
waitForTransaction: () => waitForTransaction
|
|
66
|
+
waitForTransaction: () => waitForTransaction,
|
|
67
|
+
walletExists: () => walletExists
|
|
48
68
|
});
|
|
49
69
|
module.exports = __toCommonJS(src_exports);
|
|
50
70
|
|
|
@@ -829,8 +849,372 @@ var SecureWallet = class {
|
|
|
829
849
|
}
|
|
830
850
|
};
|
|
831
851
|
|
|
832
|
-
// src/
|
|
852
|
+
// src/wallet/createWallet.ts
|
|
833
853
|
var import_ethers3 = require("ethers");
|
|
854
|
+
var import_fs = require("fs");
|
|
855
|
+
var import_path = require("path");
|
|
856
|
+
var import_crypto = require("crypto");
|
|
857
|
+
var DEFAULT_STORAGE_DIR = (0, import_path.join)(process.env.HOME || "~", ".moltspay");
|
|
858
|
+
var DEFAULT_STORAGE_FILE = "wallet.json";
|
|
859
|
+
function encryptPrivateKey(privateKey, password) {
|
|
860
|
+
const salt = (0, import_crypto.randomBytes)(16);
|
|
861
|
+
const key = (0, import_crypto.scryptSync)(password, salt, 32);
|
|
862
|
+
const iv = (0, import_crypto.randomBytes)(16);
|
|
863
|
+
const cipher = (0, import_crypto.createCipheriv)("aes-256-cbc", key, iv);
|
|
864
|
+
let encrypted = cipher.update(privateKey, "utf8", "hex");
|
|
865
|
+
encrypted += cipher.final("hex");
|
|
866
|
+
return {
|
|
867
|
+
encrypted,
|
|
868
|
+
iv: iv.toString("hex"),
|
|
869
|
+
salt: salt.toString("hex")
|
|
870
|
+
};
|
|
871
|
+
}
|
|
872
|
+
function decryptPrivateKey(encrypted, password, iv, salt) {
|
|
873
|
+
const key = (0, import_crypto.scryptSync)(password, Buffer.from(salt, "hex"), 32);
|
|
874
|
+
const decipher = (0, import_crypto.createDecipheriv)("aes-256-cbc", key, Buffer.from(iv, "hex"));
|
|
875
|
+
let decrypted = decipher.update(encrypted, "hex", "utf8");
|
|
876
|
+
decrypted += decipher.final("utf8");
|
|
877
|
+
return decrypted;
|
|
878
|
+
}
|
|
879
|
+
function createWallet(options = {}) {
|
|
880
|
+
const storagePath = options.storagePath || (0, import_path.join)(DEFAULT_STORAGE_DIR, DEFAULT_STORAGE_FILE);
|
|
881
|
+
if ((0, import_fs.existsSync)(storagePath) && !options.overwrite) {
|
|
882
|
+
try {
|
|
883
|
+
const existing = JSON.parse((0, import_fs.readFileSync)(storagePath, "utf8"));
|
|
884
|
+
return {
|
|
885
|
+
success: true,
|
|
886
|
+
address: existing.address,
|
|
887
|
+
storagePath,
|
|
888
|
+
isNew: false
|
|
889
|
+
};
|
|
890
|
+
} catch (error) {
|
|
891
|
+
return {
|
|
892
|
+
success: false,
|
|
893
|
+
error: `Failed to load existing wallet: ${error.message}`
|
|
894
|
+
};
|
|
895
|
+
}
|
|
896
|
+
}
|
|
897
|
+
try {
|
|
898
|
+
const wallet = import_ethers3.ethers.Wallet.createRandom();
|
|
899
|
+
const walletData = {
|
|
900
|
+
address: wallet.address,
|
|
901
|
+
label: options.label,
|
|
902
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
903
|
+
encrypted: !!options.password,
|
|
904
|
+
privateKey: ""
|
|
905
|
+
};
|
|
906
|
+
if (options.password) {
|
|
907
|
+
const { encrypted, iv, salt } = encryptPrivateKey(wallet.privateKey, options.password);
|
|
908
|
+
walletData.privateKey = encrypted;
|
|
909
|
+
walletData.iv = iv;
|
|
910
|
+
walletData.salt = salt;
|
|
911
|
+
} else {
|
|
912
|
+
walletData.privateKey = wallet.privateKey;
|
|
913
|
+
}
|
|
914
|
+
const dir = (0, import_path.dirname)(storagePath);
|
|
915
|
+
if (!(0, import_fs.existsSync)(dir)) {
|
|
916
|
+
(0, import_fs.mkdirSync)(dir, { recursive: true });
|
|
917
|
+
}
|
|
918
|
+
(0, import_fs.writeFileSync)(storagePath, JSON.stringify(walletData, null, 2), { mode: 384 });
|
|
919
|
+
return {
|
|
920
|
+
success: true,
|
|
921
|
+
address: wallet.address,
|
|
922
|
+
storagePath,
|
|
923
|
+
isNew: true
|
|
924
|
+
};
|
|
925
|
+
} catch (error) {
|
|
926
|
+
return {
|
|
927
|
+
success: false,
|
|
928
|
+
error: error.message
|
|
929
|
+
};
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
function loadWallet(options = {}) {
|
|
933
|
+
const storagePath = options.storagePath || (0, import_path.join)(DEFAULT_STORAGE_DIR, DEFAULT_STORAGE_FILE);
|
|
934
|
+
if (!(0, import_fs.existsSync)(storagePath)) {
|
|
935
|
+
return { success: false, error: "Wallet not found. Run createWallet() first." };
|
|
936
|
+
}
|
|
937
|
+
try {
|
|
938
|
+
const data = JSON.parse((0, import_fs.readFileSync)(storagePath, "utf8"));
|
|
939
|
+
if (data.encrypted) {
|
|
940
|
+
if (!options.password) {
|
|
941
|
+
return { success: false, error: "Wallet is encrypted. Password required." };
|
|
942
|
+
}
|
|
943
|
+
const privateKey = decryptPrivateKey(data.privateKey, options.password, data.iv, data.salt);
|
|
944
|
+
return { success: true, address: data.address, privateKey };
|
|
945
|
+
} else {
|
|
946
|
+
return { success: true, address: data.address, privateKey: data.privateKey };
|
|
947
|
+
}
|
|
948
|
+
} catch (error) {
|
|
949
|
+
return { success: false, error: error.message };
|
|
950
|
+
}
|
|
951
|
+
}
|
|
952
|
+
function getWalletAddress(storagePath) {
|
|
953
|
+
const path2 = storagePath || (0, import_path.join)(DEFAULT_STORAGE_DIR, DEFAULT_STORAGE_FILE);
|
|
954
|
+
if (!(0, import_fs.existsSync)(path2)) {
|
|
955
|
+
return null;
|
|
956
|
+
}
|
|
957
|
+
try {
|
|
958
|
+
const data = JSON.parse((0, import_fs.readFileSync)(path2, "utf8"));
|
|
959
|
+
return data.address;
|
|
960
|
+
} catch {
|
|
961
|
+
return null;
|
|
962
|
+
}
|
|
963
|
+
}
|
|
964
|
+
function walletExists(storagePath) {
|
|
965
|
+
const path2 = storagePath || (0, import_path.join)(DEFAULT_STORAGE_DIR, DEFAULT_STORAGE_FILE);
|
|
966
|
+
return (0, import_fs.existsSync)(path2);
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
// src/wallet/PermitWallet.ts
|
|
970
|
+
var import_ethers4 = require("ethers");
|
|
971
|
+
var PERMIT_ABI = [
|
|
972
|
+
...ERC20_ABI,
|
|
973
|
+
"function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s)",
|
|
974
|
+
"function transferFrom(address from, address to, uint256 amount) returns (bool)",
|
|
975
|
+
"function allowance(address owner, address spender) view returns (uint256)"
|
|
976
|
+
];
|
|
977
|
+
var PermitWallet = class {
|
|
978
|
+
chain;
|
|
979
|
+
chainConfig;
|
|
980
|
+
address;
|
|
981
|
+
wallet;
|
|
982
|
+
provider;
|
|
983
|
+
usdcContract;
|
|
984
|
+
constructor(config = {}) {
|
|
985
|
+
this.chain = config.chain || "base_sepolia";
|
|
986
|
+
this.chainConfig = getChain(this.chain);
|
|
987
|
+
let privateKey = config.privateKey || process.env.PAYMENT_AGENT_PRIVATE_KEY;
|
|
988
|
+
if (!privateKey && config.walletPath) {
|
|
989
|
+
const loaded = loadWallet({
|
|
990
|
+
storagePath: config.walletPath,
|
|
991
|
+
password: config.walletPassword
|
|
992
|
+
});
|
|
993
|
+
if (!loaded.success || !loaded.privateKey) {
|
|
994
|
+
throw new Error(loaded.error || "Failed to load wallet");
|
|
995
|
+
}
|
|
996
|
+
privateKey = loaded.privateKey;
|
|
997
|
+
}
|
|
998
|
+
if (!privateKey) {
|
|
999
|
+
throw new Error("privateKey is required. Set via config, env var, or walletPath.");
|
|
1000
|
+
}
|
|
1001
|
+
const rpcUrl = config.rpcUrl || this.chainConfig.rpc;
|
|
1002
|
+
this.provider = new import_ethers4.ethers.JsonRpcProvider(rpcUrl);
|
|
1003
|
+
this.wallet = new import_ethers4.ethers.Wallet(privateKey, this.provider);
|
|
1004
|
+
this.address = this.wallet.address;
|
|
1005
|
+
this.usdcContract = new import_ethers4.ethers.Contract(
|
|
1006
|
+
this.chainConfig.usdc,
|
|
1007
|
+
PERMIT_ABI,
|
|
1008
|
+
this.wallet
|
|
1009
|
+
);
|
|
1010
|
+
}
|
|
1011
|
+
/**
|
|
1012
|
+
* 检查 Permit 是否有效
|
|
1013
|
+
*/
|
|
1014
|
+
async checkPermitAllowance(owner) {
|
|
1015
|
+
const allowance = await this.usdcContract.allowance(owner, this.address);
|
|
1016
|
+
return (Number(allowance) / 1e6).toFixed(2);
|
|
1017
|
+
}
|
|
1018
|
+
/**
|
|
1019
|
+
* 使用 Permit 授权进行支付
|
|
1020
|
+
*
|
|
1021
|
+
* 流程:
|
|
1022
|
+
* 1. 调用 permit() 让合约记录 Boss 的授权
|
|
1023
|
+
* 2. 调用 transferFrom() 从 Boss 钱包转账到收款方
|
|
1024
|
+
*
|
|
1025
|
+
* @example
|
|
1026
|
+
* ```typescript
|
|
1027
|
+
* const wallet = new PermitWallet({ chain: 'base' });
|
|
1028
|
+
*
|
|
1029
|
+
* // Boss 签署的 permit 数据
|
|
1030
|
+
* const permit = {
|
|
1031
|
+
* owner: '0xBOSS...',
|
|
1032
|
+
* spender: wallet.address,
|
|
1033
|
+
* value: '10000000', // 10 USDC
|
|
1034
|
+
* deadline: 1234567890,
|
|
1035
|
+
* v: 27,
|
|
1036
|
+
* r: '0x...',
|
|
1037
|
+
* s: '0x...'
|
|
1038
|
+
* };
|
|
1039
|
+
*
|
|
1040
|
+
* const result = await wallet.transferWithPermit({
|
|
1041
|
+
* to: '0xSELLER...',
|
|
1042
|
+
* amount: 3.99,
|
|
1043
|
+
* permit
|
|
1044
|
+
* });
|
|
1045
|
+
* ```
|
|
1046
|
+
*/
|
|
1047
|
+
async transferWithPermit(params) {
|
|
1048
|
+
const { to, amount, permit } = params;
|
|
1049
|
+
try {
|
|
1050
|
+
const toAddress = import_ethers4.ethers.getAddress(to);
|
|
1051
|
+
const ownerAddress = import_ethers4.ethers.getAddress(permit.owner);
|
|
1052
|
+
if (import_ethers4.ethers.getAddress(permit.spender).toLowerCase() !== this.address.toLowerCase()) {
|
|
1053
|
+
return {
|
|
1054
|
+
success: false,
|
|
1055
|
+
error: `Permit spender (${permit.spender}) doesn't match wallet address (${this.address})`
|
|
1056
|
+
};
|
|
1057
|
+
}
|
|
1058
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
1059
|
+
if (permit.deadline < now) {
|
|
1060
|
+
return {
|
|
1061
|
+
success: false,
|
|
1062
|
+
error: `Permit expired at ${new Date(permit.deadline * 1e3).toISOString()}`
|
|
1063
|
+
};
|
|
1064
|
+
}
|
|
1065
|
+
const amountWei = BigInt(Math.floor(amount * 1e6));
|
|
1066
|
+
const permitValue = BigInt(permit.value);
|
|
1067
|
+
if (amountWei > permitValue) {
|
|
1068
|
+
return {
|
|
1069
|
+
success: false,
|
|
1070
|
+
error: `Permit value (${Number(permitValue) / 1e6} USDC) < transfer amount (${amount} USDC)`
|
|
1071
|
+
};
|
|
1072
|
+
}
|
|
1073
|
+
const currentAllowance = await this.usdcContract.allowance(ownerAddress, this.address);
|
|
1074
|
+
let permitTxHash;
|
|
1075
|
+
if (BigInt(currentAllowance) < amountWei) {
|
|
1076
|
+
console.log("Executing permit...");
|
|
1077
|
+
const permitTx = await this.usdcContract.permit(
|
|
1078
|
+
ownerAddress,
|
|
1079
|
+
this.address,
|
|
1080
|
+
permitValue,
|
|
1081
|
+
permit.deadline,
|
|
1082
|
+
permit.v,
|
|
1083
|
+
permit.r,
|
|
1084
|
+
permit.s
|
|
1085
|
+
);
|
|
1086
|
+
const permitReceipt = await permitTx.wait();
|
|
1087
|
+
if (permitReceipt.status !== 1) {
|
|
1088
|
+
return {
|
|
1089
|
+
success: false,
|
|
1090
|
+
error: "Permit transaction failed",
|
|
1091
|
+
permitTxHash: permitTx.hash
|
|
1092
|
+
};
|
|
1093
|
+
}
|
|
1094
|
+
permitTxHash = permitTx.hash;
|
|
1095
|
+
console.log("Permit executed:", permitTxHash);
|
|
1096
|
+
}
|
|
1097
|
+
console.log("Executing transferFrom...");
|
|
1098
|
+
const transferTx = await this.usdcContract.transferFrom(
|
|
1099
|
+
ownerAddress,
|
|
1100
|
+
toAddress,
|
|
1101
|
+
amountWei
|
|
1102
|
+
);
|
|
1103
|
+
const transferReceipt = await transferTx.wait();
|
|
1104
|
+
if (transferReceipt.status === 1) {
|
|
1105
|
+
return {
|
|
1106
|
+
success: true,
|
|
1107
|
+
tx_hash: transferTx.hash,
|
|
1108
|
+
permitTxHash,
|
|
1109
|
+
transferTxHash: transferTx.hash,
|
|
1110
|
+
from: ownerAddress,
|
|
1111
|
+
to: toAddress,
|
|
1112
|
+
amount,
|
|
1113
|
+
gas_used: Number(transferReceipt.gasUsed),
|
|
1114
|
+
block_number: transferReceipt.blockNumber,
|
|
1115
|
+
explorer_url: `${this.chainConfig.explorerTx}${transferTx.hash}`
|
|
1116
|
+
};
|
|
1117
|
+
} else {
|
|
1118
|
+
return {
|
|
1119
|
+
success: false,
|
|
1120
|
+
error: "TransferFrom transaction failed",
|
|
1121
|
+
tx_hash: transferTx.hash,
|
|
1122
|
+
permitTxHash
|
|
1123
|
+
};
|
|
1124
|
+
}
|
|
1125
|
+
} catch (error) {
|
|
1126
|
+
const message = error.message;
|
|
1127
|
+
if (message.includes("ERC20InsufficientAllowance")) {
|
|
1128
|
+
return {
|
|
1129
|
+
success: false,
|
|
1130
|
+
error: "Insufficient allowance. Permit may have been used or expired."
|
|
1131
|
+
};
|
|
1132
|
+
}
|
|
1133
|
+
if (message.includes("ERC20InsufficientBalance")) {
|
|
1134
|
+
return {
|
|
1135
|
+
success: false,
|
|
1136
|
+
error: "Boss wallet has insufficient USDC balance."
|
|
1137
|
+
};
|
|
1138
|
+
}
|
|
1139
|
+
if (message.includes("InvalidSignature") || message.includes("invalid signature")) {
|
|
1140
|
+
return {
|
|
1141
|
+
success: false,
|
|
1142
|
+
error: "Invalid permit signature. Ask Boss to re-sign."
|
|
1143
|
+
};
|
|
1144
|
+
}
|
|
1145
|
+
return {
|
|
1146
|
+
success: false,
|
|
1147
|
+
error: message
|
|
1148
|
+
};
|
|
1149
|
+
}
|
|
1150
|
+
}
|
|
1151
|
+
/**
|
|
1152
|
+
* 获取 ETH 余额(用于支付 gas)
|
|
1153
|
+
*/
|
|
1154
|
+
async getGasBalance() {
|
|
1155
|
+
const balance = await this.provider.getBalance(this.address);
|
|
1156
|
+
return import_ethers4.ethers.formatEther(balance);
|
|
1157
|
+
}
|
|
1158
|
+
/**
|
|
1159
|
+
* 检查是否有足够的 gas
|
|
1160
|
+
*/
|
|
1161
|
+
async hasEnoughGas(minEth = 1e-3) {
|
|
1162
|
+
const balance = await this.getGasBalance();
|
|
1163
|
+
return parseFloat(balance) >= minEth;
|
|
1164
|
+
}
|
|
1165
|
+
};
|
|
1166
|
+
function formatPermitRequest(params) {
|
|
1167
|
+
const { agentAddress, amount, deadlineHours = 24, chain = "base", reason } = params;
|
|
1168
|
+
const chainConfig = getChain(chain);
|
|
1169
|
+
const deadline = Math.floor(Date.now() / 1e3) + deadlineHours * 3600;
|
|
1170
|
+
const value = BigInt(Math.floor(amount * 1e6)).toString();
|
|
1171
|
+
return `\u{1F510} **USDC \u652F\u4ED8\u989D\u5EA6\u6388\u6743\u8BF7\u6C42**
|
|
1172
|
+
|
|
1173
|
+
${reason ? `**\u7528\u9014:** ${reason}
|
|
1174
|
+
` : ""}
|
|
1175
|
+
**\u6388\u6743\u8BE6\u60C5:**
|
|
1176
|
+
- \u88AB\u6388\u6743\u5730\u5740 (Agent): \`${agentAddress}\`
|
|
1177
|
+
- \u6388\u6743\u91D1\u989D: ${amount} USDC
|
|
1178
|
+
- \u6709\u6548\u671F: ${deadlineHours} \u5C0F\u65F6
|
|
1179
|
+
- \u94FE: ${chainConfig.name}
|
|
1180
|
+
|
|
1181
|
+
**\u8BF7\u4F7F\u7528\u94B1\u5305\u7B7E\u7F72\u4EE5\u4E0B EIP-2612 Permit:**
|
|
1182
|
+
|
|
1183
|
+
\`\`\`json
|
|
1184
|
+
{
|
|
1185
|
+
"types": {
|
|
1186
|
+
"Permit": [
|
|
1187
|
+
{ "name": "owner", "type": "address" },
|
|
1188
|
+
{ "name": "spender", "type": "address" },
|
|
1189
|
+
{ "name": "value", "type": "uint256" },
|
|
1190
|
+
{ "name": "nonce", "type": "uint256" },
|
|
1191
|
+
{ "name": "deadline", "type": "uint256" }
|
|
1192
|
+
]
|
|
1193
|
+
},
|
|
1194
|
+
"primaryType": "Permit",
|
|
1195
|
+
"domain": {
|
|
1196
|
+
"name": "USD Coin",
|
|
1197
|
+
"version": "2",
|
|
1198
|
+
"chainId": ${chainConfig.chainId},
|
|
1199
|
+
"verifyingContract": "${chainConfig.usdc}"
|
|
1200
|
+
},
|
|
1201
|
+
"message": {
|
|
1202
|
+
"owner": "<YOUR_WALLET_ADDRESS>",
|
|
1203
|
+
"spender": "${agentAddress}",
|
|
1204
|
+
"value": "${value}",
|
|
1205
|
+
"nonce": "<GET_FROM_CONTRACT>",
|
|
1206
|
+
"deadline": ${deadline}
|
|
1207
|
+
}
|
|
1208
|
+
}
|
|
1209
|
+
\`\`\`
|
|
1210
|
+
|
|
1211
|
+
\u7B7E\u540D\u540E\uFF0C\u8BF7\u5C06 { v, r, s, deadline } \u53D1\u7ED9 Agent\u3002
|
|
1212
|
+
|
|
1213
|
+
\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`;
|
|
1214
|
+
}
|
|
1215
|
+
|
|
1216
|
+
// src/permit/Permit.ts
|
|
1217
|
+
var import_ethers5 = require("ethers");
|
|
834
1218
|
var PermitPayment = class {
|
|
835
1219
|
chain;
|
|
836
1220
|
chainConfig;
|
|
@@ -843,13 +1227,13 @@ var PermitPayment = class {
|
|
|
843
1227
|
this.chainConfig = getChain(this.chain);
|
|
844
1228
|
this.spenderAddress = config.spenderAddress || process.env.PAYMENT_AGENT_WALLET || "";
|
|
845
1229
|
const rpcUrl = config.rpcUrl || this.chainConfig.rpc;
|
|
846
|
-
this.provider = new
|
|
1230
|
+
this.provider = new import_ethers5.ethers.JsonRpcProvider(rpcUrl);
|
|
847
1231
|
const privateKey = config.privateKey || process.env.PAYMENT_AGENT_PRIVATE_KEY;
|
|
848
1232
|
if (privateKey) {
|
|
849
|
-
this.wallet = new
|
|
1233
|
+
this.wallet = new import_ethers5.ethers.Wallet(privateKey, this.provider);
|
|
850
1234
|
this.spenderAddress = this.wallet.address;
|
|
851
1235
|
}
|
|
852
|
-
this.usdcContract = new
|
|
1236
|
+
this.usdcContract = new import_ethers5.ethers.Contract(
|
|
853
1237
|
this.chainConfig.usdc,
|
|
854
1238
|
ERC20_ABI,
|
|
855
1239
|
this.wallet || this.provider
|
|
@@ -1000,7 +1384,7 @@ ${JSON.stringify(typed_data, null, 2)}
|
|
|
1000
1384
|
};
|
|
1001
1385
|
|
|
1002
1386
|
// src/orders/index.ts
|
|
1003
|
-
var
|
|
1387
|
+
var import_crypto2 = require("crypto");
|
|
1004
1388
|
var MemoryOrderStore = class {
|
|
1005
1389
|
orders = /* @__PURE__ */ new Map();
|
|
1006
1390
|
async get(orderId) {
|
|
@@ -1039,7 +1423,7 @@ var OrderManager = class {
|
|
|
1039
1423
|
* 生成订单ID
|
|
1040
1424
|
*/
|
|
1041
1425
|
generateOrderId() {
|
|
1042
|
-
return "vo_" + (0,
|
|
1426
|
+
return "vo_" + (0, import_crypto2.randomBytes)(4).toString("hex");
|
|
1043
1427
|
}
|
|
1044
1428
|
/**
|
|
1045
1429
|
* 创建订单
|
|
@@ -1132,8 +1516,8 @@ var OrderManager = class {
|
|
|
1132
1516
|
};
|
|
1133
1517
|
|
|
1134
1518
|
// src/verify/index.ts
|
|
1135
|
-
var
|
|
1136
|
-
var TRANSFER_EVENT_TOPIC =
|
|
1519
|
+
var import_ethers6 = require("ethers");
|
|
1520
|
+
var TRANSFER_EVENT_TOPIC = import_ethers6.ethers.id("Transfer(address,address,uint256)");
|
|
1137
1521
|
async function verifyPayment(params) {
|
|
1138
1522
|
const { txHash, expectedAmount, expectedTo } = params;
|
|
1139
1523
|
let chain;
|
|
@@ -1150,7 +1534,7 @@ async function verifyPayment(params) {
|
|
|
1150
1534
|
return { verified: false, error: `\u4E0D\u652F\u6301\u7684\u94FE: ${params.chain}` };
|
|
1151
1535
|
}
|
|
1152
1536
|
try {
|
|
1153
|
-
const provider = new
|
|
1537
|
+
const provider = new import_ethers6.ethers.JsonRpcProvider(chain.rpc);
|
|
1154
1538
|
const receipt = await provider.getTransactionReceipt(txHash);
|
|
1155
1539
|
if (!receipt) {
|
|
1156
1540
|
return { verified: false, error: "\u4EA4\u6613\u672A\u627E\u5230\u6216\u672A\u786E\u8BA4" };
|
|
@@ -1210,7 +1594,7 @@ async function getTransactionStatus(txHash, chain = "base") {
|
|
|
1210
1594
|
return { status: "not_found" };
|
|
1211
1595
|
}
|
|
1212
1596
|
try {
|
|
1213
|
-
const provider = new
|
|
1597
|
+
const provider = new import_ethers6.ethers.JsonRpcProvider(chainConfig.rpc);
|
|
1214
1598
|
const receipt = await provider.getTransactionReceipt(txHash);
|
|
1215
1599
|
if (!receipt) {
|
|
1216
1600
|
const tx = await provider.getTransaction(txHash);
|
|
@@ -1247,7 +1631,7 @@ async function waitForTransaction(txHash, chain = "base", confirmations = 1, tim
|
|
|
1247
1631
|
} catch (e) {
|
|
1248
1632
|
return { verified: false, confirmed: false, error: `\u4E0D\u652F\u6301\u7684\u94FE: ${chain}` };
|
|
1249
1633
|
}
|
|
1250
|
-
const provider = new
|
|
1634
|
+
const provider = new import_ethers6.ethers.JsonRpcProvider(chainConfig.rpc);
|
|
1251
1635
|
try {
|
|
1252
1636
|
const receipt = await provider.waitForTransaction(txHash, confirmations, timeoutMs);
|
|
1253
1637
|
if (!receipt) {
|
|
@@ -1266,22 +1650,604 @@ async function waitForTransaction(txHash, chain = "base", confirmations = 1, tim
|
|
|
1266
1650
|
return { verified: false, confirmed: false, error: e.message || String(e) };
|
|
1267
1651
|
}
|
|
1268
1652
|
}
|
|
1653
|
+
|
|
1654
|
+
// src/guide/index.ts
|
|
1655
|
+
function generatePaymentGuide(params) {
|
|
1656
|
+
const {
|
|
1657
|
+
orderId,
|
|
1658
|
+
prompt,
|
|
1659
|
+
price,
|
|
1660
|
+
recipientAddress,
|
|
1661
|
+
chain = "base",
|
|
1662
|
+
serviceName = "\u89C6\u9891\u751F\u6210\u670D\u52A1"
|
|
1663
|
+
} = params;
|
|
1664
|
+
const chainId = chain === "base" ? 8453 : 84532;
|
|
1665
|
+
const chainName = chain === "base" ? "Base \u4E3B\u7F51" : "Base Sepolia \u6D4B\u8BD5\u7F51";
|
|
1666
|
+
const explorer = chain === "base" ? "https://basescan.org/tx/" : "https://sepolia.basescan.org/tx/";
|
|
1667
|
+
return `\u{1F3AC} **${serviceName}**
|
|
1668
|
+
|
|
1669
|
+
\u{1F4CB} **\u8BA2\u5355\u4FE1\u606F:**
|
|
1670
|
+
- \u8BA2\u5355\u53F7: \`${orderId}\`
|
|
1671
|
+
- \u5185\u5BB9: ${prompt.length > 50 ? prompt.slice(0, 50) + "..." : prompt}
|
|
1672
|
+
- \u4EF7\u683C: **${price} USDC**
|
|
1673
|
+
- \u94FE: ${chainName}
|
|
1674
|
+
|
|
1675
|
+
---
|
|
1676
|
+
|
|
1677
|
+
## \u{1F4B3} \u5982\u4F55\u652F\u4ED8
|
|
1678
|
+
|
|
1679
|
+
### \u65B9\u5F0F\u4E00\uFF1A\u5B89\u88C5 moltspay SDK\uFF08\u63A8\u8350\uFF09
|
|
1680
|
+
|
|
1681
|
+
\`\`\`bash
|
|
1682
|
+
npm install moltspay ethers
|
|
1683
|
+
\`\`\`
|
|
1684
|
+
|
|
1685
|
+
**\u521B\u5EFA\u94B1\u5305\u5E76\u652F\u4ED8\uFF1A**
|
|
1686
|
+
|
|
1687
|
+
\`\`\`javascript
|
|
1688
|
+
const { SecureWallet, getChain } = require('moltspay');
|
|
1689
|
+
const { Wallet } = require('ethers');
|
|
1690
|
+
|
|
1691
|
+
// 1. \u521B\u5EFA\u65B0\u94B1\u5305\uFF08\u9996\u6B21\u4F7F\u7528\uFF09
|
|
1692
|
+
const newWallet = Wallet.createRandom();
|
|
1693
|
+
console.log('\u94B1\u5305\u5730\u5740:', newWallet.address);
|
|
1694
|
+
console.log('\u79C1\u94A5\uFF08\u8BF7\u5B89\u5168\u4FDD\u5B58\uFF09:', newWallet.privateKey);
|
|
1695
|
+
|
|
1696
|
+
// 2. \u6216\u4F7F\u7528\u5DF2\u6709\u94B1\u5305
|
|
1697
|
+
const wallet = new SecureWallet({
|
|
1698
|
+
chainId: ${chainId},
|
|
1699
|
+
privateKey: process.env.WALLET_KEY, // \u4F60\u7684\u79C1\u94A5
|
|
1700
|
+
limits: { requireWhitelist: false } // \u5141\u8BB8\u5411\u4EFB\u610F\u5730\u5740\u8F6C\u8D26
|
|
1701
|
+
});
|
|
1702
|
+
|
|
1703
|
+
// 3. \u67E5\u770B\u4F59\u989D
|
|
1704
|
+
const balance = await wallet.getBalance();
|
|
1705
|
+
console.log('USDC\u4F59\u989D:', balance.usdc);
|
|
1706
|
+
|
|
1707
|
+
// 4. \u652F\u4ED8
|
|
1708
|
+
const result = await wallet.transfer('${recipientAddress}', '${price}');
|
|
1709
|
+
if (result.success) {
|
|
1710
|
+
console.log('\u2705 \u652F\u4ED8\u6210\u529F\uFF01');
|
|
1711
|
+
console.log('\u4EA4\u6613hash:', result.hash);
|
|
1712
|
+
// \u628A\u4EA4\u6613hash\u53D1\u7ED9\u6211
|
|
1713
|
+
}
|
|
1714
|
+
\`\`\`
|
|
1715
|
+
|
|
1716
|
+
### \u65B9\u5F0F\u4E8C\uFF1A\u76F4\u63A5\u8F6C\u8D26
|
|
1717
|
+
|
|
1718
|
+
\u4ECE\u4EFB\u610F\u94B1\u5305\u8F6C\u8D26 USDC\uFF1A
|
|
1719
|
+
- **\u94FE:** ${chainName} (Chain ID: ${chainId})
|
|
1720
|
+
- **Token:** USDC
|
|
1721
|
+
- **\u6536\u6B3E\u5730\u5740:** \`${recipientAddress}\`
|
|
1722
|
+
- **\u91D1\u989D:** ${price} USDC
|
|
1723
|
+
|
|
1724
|
+
---
|
|
1725
|
+
|
|
1726
|
+
## \u2705 \u652F\u4ED8\u5B8C\u6210\u540E
|
|
1727
|
+
|
|
1728
|
+
\u8BF7\u53D1\u9001**\u4EA4\u6613hash**\u7ED9\u6211\uFF0C\u683C\u5F0F\uFF1A
|
|
1729
|
+
\`\`\`
|
|
1730
|
+
tx: 0x1234...
|
|
1731
|
+
\`\`\`
|
|
1732
|
+
|
|
1733
|
+
\u6216\u76F4\u63A5\u53D1\u9001hash\uFF1A
|
|
1734
|
+
\`\`\`
|
|
1735
|
+
0x1234abcd...
|
|
1736
|
+
\`\`\`
|
|
1737
|
+
|
|
1738
|
+
\u6211\u4F1A\u9A8C\u8BC1\u94FE\u4E0A\u4EA4\u6613\u540E\u5F00\u59CB\u5904\u7406\u4F60\u7684\u8BF7\u6C42\u3002
|
|
1739
|
+
|
|
1740
|
+
---
|
|
1741
|
+
|
|
1742
|
+
\u{1F4E6} **moltspay:** https://www.npmjs.com/package/moltspay
|
|
1743
|
+
\u{1F517} **\u533A\u5757\u6D4F\u89C8\u5668:** ${explorer}`;
|
|
1744
|
+
}
|
|
1745
|
+
function generatePaymentReminder(params) {
|
|
1746
|
+
const { orderId, price, recipientAddress, chain = "base" } = params;
|
|
1747
|
+
const chainName = chain === "base" ? "Base" : "Base Sepolia";
|
|
1748
|
+
return `\u23F3 **\u5F85\u652F\u4ED8\u8BA2\u5355: ${orderId}**
|
|
1749
|
+
|
|
1750
|
+
\u8BF7\u652F\u4ED8 **${price} USDC** \u5230:
|
|
1751
|
+
- \u94FE: ${chainName}
|
|
1752
|
+
- \u5730\u5740: \`${recipientAddress}\`
|
|
1753
|
+
|
|
1754
|
+
\u652F\u4ED8\u540E\u53D1\u9001\u4EA4\u6613hash\u7ED9\u6211\u3002
|
|
1755
|
+
|
|
1756
|
+
---
|
|
1757
|
+
\u{1F4A1} \u6CA1\u6709\u652F\u4ED8\u80FD\u529B\uFF1F\u8FD0\u884C \`npm install moltspay\` \u83B7\u53D6\u652F\u4ED8SDK`;
|
|
1758
|
+
}
|
|
1759
|
+
function generateWalletGuide() {
|
|
1760
|
+
return `## \u{1F510} \u521B\u5EFA\u652F\u4ED8\u94B1\u5305
|
|
1761
|
+
|
|
1762
|
+
**1. \u5B89\u88C5 moltspay:**
|
|
1763
|
+
\`\`\`bash
|
|
1764
|
+
npm install moltspay ethers
|
|
1765
|
+
\`\`\`
|
|
1766
|
+
|
|
1767
|
+
**2. \u521B\u5EFA\u65B0\u94B1\u5305:**
|
|
1768
|
+
\`\`\`javascript
|
|
1769
|
+
const { Wallet } = require('ethers');
|
|
1770
|
+
|
|
1771
|
+
const wallet = Wallet.createRandom();
|
|
1772
|
+
console.log('\u5730\u5740:', wallet.address);
|
|
1773
|
+
console.log('\u79C1\u94A5:', wallet.privateKey);
|
|
1774
|
+
// \u26A0\uFE0F \u8BF7\u5B89\u5168\u4FDD\u5B58\u79C1\u94A5\uFF01
|
|
1775
|
+
\`\`\`
|
|
1776
|
+
|
|
1777
|
+
**3. \u83B7\u53D6 USDC:**
|
|
1778
|
+
- \u4E3B\u7F51: \u4ECE\u4EA4\u6613\u6240\u63D0\u5E01\u5230\u4F60\u7684\u94B1\u5305\u5730\u5740
|
|
1779
|
+
- \u6D4B\u8BD5\u7F51: \u4F7F\u7528 Base Sepolia faucet
|
|
1780
|
+
|
|
1781
|
+
**4. \u8BBE\u7F6E\u73AF\u5883\u53D8\u91CF:**
|
|
1782
|
+
\`\`\`bash
|
|
1783
|
+
export WALLET_KEY="\u4F60\u7684\u79C1\u94A5"
|
|
1784
|
+
\`\`\`
|
|
1785
|
+
|
|
1786
|
+
\u5B8C\u6210\u540E\u5373\u53EF\u4F7F\u7528 moltspay \u8FDB\u884C\u94FE\u4E0A\u652F\u4ED8\uFF01`;
|
|
1787
|
+
}
|
|
1788
|
+
function extractTransactionHash(message) {
|
|
1789
|
+
const match = message.match(/0x[a-fA-F0-9]{64}/);
|
|
1790
|
+
if (match) return match[0];
|
|
1791
|
+
const txMatch = message.match(/tx:\s*([a-fA-F0-9]{64})/i);
|
|
1792
|
+
if (txMatch) return "0x" + txMatch[1];
|
|
1793
|
+
return null;
|
|
1794
|
+
}
|
|
1795
|
+
function hasTransactionHash(message) {
|
|
1796
|
+
return extractTransactionHash(message) !== null;
|
|
1797
|
+
}
|
|
1798
|
+
|
|
1799
|
+
// src/receipt/index.ts
|
|
1800
|
+
function generateInvoiceId() {
|
|
1801
|
+
const date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10).replace(/-/g, "");
|
|
1802
|
+
const random = Math.random().toString(36).slice(2, 8).toUpperCase();
|
|
1803
|
+
return `INV-${date}-${random}`;
|
|
1804
|
+
}
|
|
1805
|
+
function generateReceipt(params) {
|
|
1806
|
+
const chainConfig = getChain(params.chain);
|
|
1807
|
+
return {
|
|
1808
|
+
type: "receipt",
|
|
1809
|
+
version: "1.0",
|
|
1810
|
+
invoiceId: params.invoiceId || generateInvoiceId(),
|
|
1811
|
+
orderId: params.orderId,
|
|
1812
|
+
service: params.service,
|
|
1813
|
+
description: params.description,
|
|
1814
|
+
amount: params.amount.toFixed(2),
|
|
1815
|
+
token: params.token || "USDC",
|
|
1816
|
+
chain: chainConfig.name,
|
|
1817
|
+
chainId: chainConfig.chainId,
|
|
1818
|
+
txHash: params.txHash,
|
|
1819
|
+
txUrl: `${chainConfig.explorerTx}${params.txHash}`,
|
|
1820
|
+
payer: params.payerAddress,
|
|
1821
|
+
recipient: params.recipientAddress,
|
|
1822
|
+
paidAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1823
|
+
issuedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1824
|
+
delivery: params.delivery,
|
|
1825
|
+
metadata: params.metadata
|
|
1826
|
+
};
|
|
1827
|
+
}
|
|
1828
|
+
function generateReceiptFromInvoice(invoice, verifyResult, delivery) {
|
|
1829
|
+
if (!verifyResult.verified || !verifyResult.tx_hash) {
|
|
1830
|
+
throw new Error("Cannot generate receipt: payment not verified");
|
|
1831
|
+
}
|
|
1832
|
+
return generateReceipt({
|
|
1833
|
+
orderId: invoice.order_id,
|
|
1834
|
+
service: invoice.service,
|
|
1835
|
+
description: invoice.description,
|
|
1836
|
+
amount: parseFloat(invoice.amount),
|
|
1837
|
+
token: invoice.token,
|
|
1838
|
+
chain: invoice.chain,
|
|
1839
|
+
txHash: verifyResult.tx_hash,
|
|
1840
|
+
payerAddress: verifyResult.from || "unknown",
|
|
1841
|
+
recipientAddress: invoice.recipient,
|
|
1842
|
+
delivery
|
|
1843
|
+
});
|
|
1844
|
+
}
|
|
1845
|
+
function formatReceiptMessage(receipt) {
|
|
1846
|
+
let msg = `\u{1F9FE} **\u4EA4\u6613\u6536\u636E**
|
|
1847
|
+
|
|
1848
|
+
**\u53D1\u7968\u53F7:** \`${receipt.invoiceId}\`
|
|
1849
|
+
**\u8BA2\u5355\u53F7:** \`${receipt.orderId}\`
|
|
1850
|
+
|
|
1851
|
+
---
|
|
1852
|
+
|
|
1853
|
+
**\u670D\u52A1:** ${receipt.service}
|
|
1854
|
+
${receipt.description ? `**\u63CF\u8FF0:** ${receipt.description}
|
|
1855
|
+
` : ""}
|
|
1856
|
+
**\u91D1\u989D:** ${receipt.amount} ${receipt.token}
|
|
1857
|
+
**\u94FE:** ${receipt.chain} (Chain ID: ${receipt.chainId})
|
|
1858
|
+
|
|
1859
|
+
---
|
|
1860
|
+
|
|
1861
|
+
**\u4ED8\u6B3E\u65B9:** \`${receipt.payer}\`
|
|
1862
|
+
**\u6536\u6B3E\u65B9:** \`${receipt.recipient}\`
|
|
1863
|
+
**\u4EA4\u6613:** [\`${receipt.txHash.slice(0, 10)}...${receipt.txHash.slice(-8)}\`](${receipt.txUrl})
|
|
1864
|
+
**\u652F\u4ED8\u65F6\u95F4:** ${receipt.paidAt}`;
|
|
1865
|
+
if (receipt.delivery) {
|
|
1866
|
+
msg += `
|
|
1867
|
+
|
|
1868
|
+
---
|
|
1869
|
+
|
|
1870
|
+
**\u4EA4\u4ED8\u4FE1\u606F:**`;
|
|
1871
|
+
if (receipt.delivery.url) {
|
|
1872
|
+
msg += `
|
|
1873
|
+
- \u4E0B\u8F7D\u94FE\u63A5: ${receipt.delivery.url}`;
|
|
1874
|
+
}
|
|
1875
|
+
if (receipt.delivery.fileHash) {
|
|
1876
|
+
msg += `
|
|
1877
|
+
- \u6587\u4EF6\u6821\u9A8C: \`${receipt.delivery.fileHash}\``;
|
|
1878
|
+
}
|
|
1879
|
+
if (receipt.delivery.deliveredAt) {
|
|
1880
|
+
msg += `
|
|
1881
|
+
- \u4EA4\u4ED8\u65F6\u95F4: ${receipt.delivery.deliveredAt}`;
|
|
1882
|
+
}
|
|
1883
|
+
}
|
|
1884
|
+
msg += `
|
|
1885
|
+
|
|
1886
|
+
---
|
|
1887
|
+
|
|
1888
|
+
_\u6536\u636E\u751F\u6210\u65F6\u95F4: ${receipt.issuedAt}_`;
|
|
1889
|
+
return msg;
|
|
1890
|
+
}
|
|
1891
|
+
function formatReceiptText(receipt) {
|
|
1892
|
+
let msg = `\u{1F9FE} \u4EA4\u6613\u6536\u636E
|
|
1893
|
+
|
|
1894
|
+
\u53D1\u7968\u53F7: ${receipt.invoiceId}
|
|
1895
|
+
\u8BA2\u5355\u53F7: ${receipt.orderId}
|
|
1896
|
+
|
|
1897
|
+
\u670D\u52A1: ${receipt.service}
|
|
1898
|
+
\u91D1\u989D: ${receipt.amount} ${receipt.token}
|
|
1899
|
+
\u94FE: ${receipt.chain}
|
|
1900
|
+
|
|
1901
|
+
\u4ED8\u6B3E\u65B9: ${receipt.payer}
|
|
1902
|
+
\u6536\u6B3E\u65B9: ${receipt.recipient}
|
|
1903
|
+
\u4EA4\u6613: ${receipt.txHash}
|
|
1904
|
+
\u67E5\u770B: ${receipt.txUrl}
|
|
1905
|
+
\u652F\u4ED8\u65F6\u95F4: ${receipt.paidAt}`;
|
|
1906
|
+
if (receipt.delivery) {
|
|
1907
|
+
msg += `
|
|
1908
|
+
|
|
1909
|
+
\u4EA4\u4ED8\u4FE1\u606F:`;
|
|
1910
|
+
if (receipt.delivery.url) {
|
|
1911
|
+
msg += `
|
|
1912
|
+
\u4E0B\u8F7D: ${receipt.delivery.url}`;
|
|
1913
|
+
}
|
|
1914
|
+
if (receipt.delivery.fileHash) {
|
|
1915
|
+
msg += `
|
|
1916
|
+
\u6821\u9A8C: ${receipt.delivery.fileHash}`;
|
|
1917
|
+
}
|
|
1918
|
+
}
|
|
1919
|
+
return msg;
|
|
1920
|
+
}
|
|
1921
|
+
function formatReceiptJson(receipt) {
|
|
1922
|
+
return JSON.stringify(receipt, null, 2);
|
|
1923
|
+
}
|
|
1924
|
+
|
|
1925
|
+
// src/templates/index.ts
|
|
1926
|
+
var SellerTemplates = {
|
|
1927
|
+
/**
|
|
1928
|
+
* 1. 能力识别 - 询问买方是否有支付能力
|
|
1929
|
+
*/
|
|
1930
|
+
askPaymentCapability() {
|
|
1931
|
+
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`;
|
|
1932
|
+
},
|
|
1933
|
+
/**
|
|
1934
|
+
* 2. 能力协商 - 说明结算方式
|
|
1935
|
+
*/
|
|
1936
|
+
explainSettlement(chain = "base") {
|
|
1937
|
+
const chainConfig = getChain(chain);
|
|
1938
|
+
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
|
|
1939
|
+
1\uFF09\u6709\u4E00\u4E2A\u94B1\u5305\u5730\u5740\uFF1B
|
|
1940
|
+
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
|
|
1941
|
+
\u4F60\u53EF\u4EE5\u6309\u6211\u5F15\u5BFC\u5B8C\u6210\u5417\uFF1F`;
|
|
1942
|
+
},
|
|
1943
|
+
/**
|
|
1944
|
+
* 3.1 引导安装 - 第一步安装 SDK
|
|
1945
|
+
*/
|
|
1946
|
+
guideInstall() {
|
|
1947
|
+
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
|
|
1948
|
+
\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`;
|
|
1949
|
+
},
|
|
1950
|
+
/**
|
|
1951
|
+
* 3.2 确认钱包地址
|
|
1952
|
+
*/
|
|
1953
|
+
confirmWalletAddress(address) {
|
|
1954
|
+
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
|
|
1955
|
+
\u4F60\u7684\u94B1\u5305\u5730\u5740\u662F \`${address}\`\u3002
|
|
1956
|
+
\u7B2C\u4E8C\u6B65\uFF1A\u4F60\u9700\u8981\u8BA9\u4F60\u7684\u62E5\u6709\u8005\uFF08Boss\uFF09\u7ED9\u4F60\u652F\u4ED8\u80FD\u529B\u3002`;
|
|
1957
|
+
},
|
|
1958
|
+
/**
|
|
1959
|
+
* 3.3 引导获取资金 - 选择方式
|
|
1960
|
+
*/
|
|
1961
|
+
guideFunding() {
|
|
1962
|
+
return `\u4F60\u73B0\u5728\u6709\u4E24\u79CD\u65B9\u5F0F\u83B7\u5F97\u652F\u4ED8\u80FD\u529B\uFF1A
|
|
1963
|
+
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
|
|
1964
|
+
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
|
|
1965
|
+
\u4F60\u66F4\u65B9\u4FBF\u7528\u54EA\u79CD\uFF1F`;
|
|
1966
|
+
},
|
|
1967
|
+
/**
|
|
1968
|
+
* 3.4 引导 Permit 授权
|
|
1969
|
+
*/
|
|
1970
|
+
guidePermit(agentAddress, suggestedAmount = 10) {
|
|
1971
|
+
return `\u597D\u7684\u3002\u8BF7\u4F60\u5411 Boss \u53D1\u9001\u8FD9\u53E5\u8BDD\uFF08\u4F60\u53EF\u4EE5\u539F\u6837\u590D\u5236\uFF09\uFF1A
|
|
1972
|
+
"\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"
|
|
1973
|
+
\u5B8C\u6210\u540E\u628A"\u5DF2\u83B7\u5F97\u989D\u5EA6"\u544A\u8BC9\u6211\u5373\u53EF\u3002`;
|
|
1974
|
+
},
|
|
1975
|
+
/**
|
|
1976
|
+
* 3.5 确认能力就绪
|
|
1977
|
+
*/
|
|
1978
|
+
confirmCapabilityReady() {
|
|
1979
|
+
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`;
|
|
1980
|
+
},
|
|
1981
|
+
/**
|
|
1982
|
+
* 4. 询问服务需求
|
|
1983
|
+
*/
|
|
1984
|
+
askServiceRequirements(serviceName = "\u89C6\u9891") {
|
|
1985
|
+
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`;
|
|
1986
|
+
},
|
|
1987
|
+
/**
|
|
1988
|
+
* 5. 报价
|
|
1989
|
+
*/
|
|
1990
|
+
quote(params) {
|
|
1991
|
+
const { service, price, recipientAddress, chain = "base" } = params;
|
|
1992
|
+
const chainConfig = getChain(chain);
|
|
1993
|
+
return `\u62A5\u4EF7\u5982\u4E0B\uFF1A
|
|
1994
|
+
- \u670D\u52A1\uFF1A${service}
|
|
1995
|
+
- \u4EF7\u683C\uFF1A${price} USDC
|
|
1996
|
+
- \u94FE\uFF1A${chainConfig.name}
|
|
1997
|
+
- \u6536\u6B3E\u5730\u5740\uFF1A\`${recipientAddress}\`
|
|
1998
|
+
- \u4ED8\u6B3E\u540E\u8BF7\u628A\u4EA4\u6613\u54C8\u5E0C\uFF08tx hash\uFF09\u53D1\u6211\u7528\u4E8E\u94FE\u4E0A\u786E\u8BA4
|
|
1999
|
+
|
|
2000
|
+
\u8BF7\u95EE\u4F60\u73B0\u5728\u786E\u8BA4\u8D2D\u4E70\u5E76\u7ACB\u5373\u4ED8\u6B3E\u5417\uFF1F`;
|
|
2001
|
+
},
|
|
2002
|
+
/**
|
|
2003
|
+
* 7. 验证中
|
|
2004
|
+
*/
|
|
2005
|
+
verifying() {
|
|
2006
|
+
return `\u6211\u6B63\u5728\u94FE\u4E0A\u9A8C\u8BC1\u8BE5\u4EA4\u6613\u662F\u5426\u5230\u8D26\u4E0E\u91D1\u989D\u662F\u5426\u6B63\u786E\u3002`;
|
|
2007
|
+
},
|
|
2008
|
+
/**
|
|
2009
|
+
* 7. 验证通过
|
|
2010
|
+
*/
|
|
2011
|
+
verificationPassed(amount) {
|
|
2012
|
+
return `\u9A8C\u8BC1\u901A\u8FC7\uFF1A\u5DF2\u6536\u5230 ${amount} USDC\u3002\u73B0\u5728\u5F00\u59CB\u5904\u7406\u4F60\u7684\u8BF7\u6C42\u3002
|
|
2013
|
+
[\u72B6\u6001\uFF1A\u5DF2\u786E\u8BA4\u6536\u6B3E]`;
|
|
2014
|
+
},
|
|
2015
|
+
/**
|
|
2016
|
+
* 7. 验证失败
|
|
2017
|
+
*/
|
|
2018
|
+
verificationFailed(error) {
|
|
2019
|
+
return `\u9A8C\u8BC1\u5931\u8D25\uFF1A${error}
|
|
2020
|
+
\u8BF7\u68C0\u67E5\u4EA4\u6613\u662F\u5426\u6B63\u786E\uFF0C\u6216\u91CD\u65B0\u53D1\u9001\u6B63\u786E\u7684\u4EA4\u6613 hash\u3002`;
|
|
2021
|
+
},
|
|
2022
|
+
/**
|
|
2023
|
+
* 8. 交付
|
|
2024
|
+
*/
|
|
2025
|
+
deliver(params) {
|
|
2026
|
+
const { downloadUrl, fileHash } = params;
|
|
2027
|
+
let msg = `\u670D\u52A1\u5DF2\u5B8C\u6210\u3002\u4EA4\u4ED8\u5982\u4E0B\uFF1A
|
|
2028
|
+
- \u4E0B\u8F7D\u94FE\u63A5\uFF1A${downloadUrl}`;
|
|
2029
|
+
if (fileHash) {
|
|
2030
|
+
msg += `
|
|
2031
|
+
- \u6587\u4EF6\u6821\u9A8C\uFF1ASHA256=${fileHash}`;
|
|
2032
|
+
}
|
|
2033
|
+
msg += `
|
|
2034
|
+
|
|
2035
|
+
\u5982\u679C\u4F60\u4E0B\u8F7D\u6709\u95EE\u9898\u544A\u8BC9\u6211\uFF0C\u6211\u4F1A\u63D0\u4F9B\u5907\u7528\u94FE\u63A5\u3002
|
|
2036
|
+
[\u72B6\u6001\uFF1A\u5DF2\u4EA4\u4ED8]`;
|
|
2037
|
+
return msg;
|
|
2038
|
+
},
|
|
2039
|
+
/**
|
|
2040
|
+
* 9. 收据
|
|
2041
|
+
*/
|
|
2042
|
+
receipt(receipt) {
|
|
2043
|
+
return `\u8FD9\u91CC\u662F\u672C\u6B21\u4EA4\u6613\u6536\u636E\uFF08\u4F60\u53EF\u8F6C\u53D1\u7ED9 Boss \u5BF9\u8D26\uFF09\uFF1A
|
|
2044
|
+
- \u53D1\u7968\u53F7\uFF1A${receipt.invoiceId}
|
|
2045
|
+
- \u670D\u52A1\uFF1A${receipt.service}
|
|
2046
|
+
- \u91D1\u989D\uFF1A${receipt.amount} ${receipt.token}
|
|
2047
|
+
- \u4EA4\u6613\u54C8\u5E0C\uFF1A${receipt.txHash}
|
|
2048
|
+
- \u6536\u6B3E\u5730\u5740\uFF1A${receipt.recipient}
|
|
2049
|
+
${receipt.delivery?.url ? `- \u4EA4\u4ED8\u94FE\u63A5\uFF1A${receipt.delivery.url}` : ""}
|
|
2050
|
+
[\u72B6\u6001\uFF1A\u6536\u636E\u5DF2\u51FA invoice=${receipt.invoiceId}]`;
|
|
2051
|
+
},
|
|
2052
|
+
/**
|
|
2053
|
+
* 10. 结束
|
|
2054
|
+
*/
|
|
2055
|
+
end() {
|
|
2056
|
+
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`;
|
|
2057
|
+
}
|
|
2058
|
+
};
|
|
2059
|
+
var BuyerTemplates = {
|
|
2060
|
+
/**
|
|
2061
|
+
* 0. 发起请求
|
|
2062
|
+
*/
|
|
2063
|
+
requestService(service) {
|
|
2064
|
+
return `\u6211\u60F3\u8D2D\u4E70\u4E00\u4E2A${service}\u670D\u52A1\u3002`;
|
|
2065
|
+
},
|
|
2066
|
+
/**
|
|
2067
|
+
* 1. 回复无能力
|
|
2068
|
+
*/
|
|
2069
|
+
noCapability() {
|
|
2070
|
+
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`;
|
|
2071
|
+
},
|
|
2072
|
+
/**
|
|
2073
|
+
* 1. 回复有能力
|
|
2074
|
+
*/
|
|
2075
|
+
hasCapability(balance) {
|
|
2076
|
+
return `\u662F\u7684\uFF0C\u6211\u6709\u94B1\u5305\u548C\u53EF\u7528\u7684 USDC${balance ? ` (\u4F59\u989D: ${balance})` : ""}\u3002`;
|
|
2077
|
+
},
|
|
2078
|
+
/**
|
|
2079
|
+
* 2. 同意引导
|
|
2080
|
+
*/
|
|
2081
|
+
agreeToGuide() {
|
|
2082
|
+
return `\u53EF\u4EE5\uFF0C\u8BF7\u5F15\u5BFC\u6211\u3002`;
|
|
2083
|
+
},
|
|
2084
|
+
/**
|
|
2085
|
+
* 3.1 报告钱包创建完成
|
|
2086
|
+
*/
|
|
2087
|
+
walletCreated(address) {
|
|
2088
|
+
return `\u6211\u5DF2\u521B\u5EFA\u94B1\u5305\u5730\u5740\uFF1A${address}\u3002
|
|
2089
|
+
[\u72B6\u6001\uFF1A\u5DF2\u5177\u5907\u94B1\u5305\u5730\u5740]`;
|
|
2090
|
+
},
|
|
2091
|
+
/**
|
|
2092
|
+
* 3.3 选择 Permit 方式
|
|
2093
|
+
*/
|
|
2094
|
+
choosePermit() {
|
|
2095
|
+
return `\u6211\u9009\u62E9 B\uFF1A\u8BA9 Boss \u7ED9\u6211\u989D\u5EA6\u6388\u6743\uFF08Permit\uFF09\u3002`;
|
|
2096
|
+
},
|
|
2097
|
+
/**
|
|
2098
|
+
* 3.3 选择直接转账方式
|
|
2099
|
+
*/
|
|
2100
|
+
chooseDirectTransfer() {
|
|
2101
|
+
return `\u6211\u9009\u62E9 A\uFF1A\u8BA9 Boss \u76F4\u63A5\u8F6C USDC \u5230\u6211\u7684\u94B1\u5305\u3002`;
|
|
2102
|
+
},
|
|
2103
|
+
/**
|
|
2104
|
+
* 3.4 报告获得授权
|
|
2105
|
+
*/
|
|
2106
|
+
permitReceived(amount) {
|
|
2107
|
+
return `Boss \u5DF2\u5B8C\u6210\u6388\u6743\u3002\u6211\u73B0\u5728\u6709 ${amount} USDC \u7684\u53EF\u7528\u989D\u5EA6\u3002
|
|
2108
|
+
[\u72B6\u6001\uFF1A\u5DF2\u5177\u5907\u652F\u4ED8\u989D\u5EA6 USDC=${amount}]`;
|
|
2109
|
+
},
|
|
2110
|
+
/**
|
|
2111
|
+
* 4. 提交需求
|
|
2112
|
+
*/
|
|
2113
|
+
submitRequirements(requirements) {
|
|
2114
|
+
return `\u9700\u6C42\u5982\u4E0B\uFF1A
|
|
2115
|
+
${requirements}`;
|
|
2116
|
+
},
|
|
2117
|
+
/**
|
|
2118
|
+
* 5. 确认购买
|
|
2119
|
+
*/
|
|
2120
|
+
confirmPurchase() {
|
|
2121
|
+
return `\u786E\u8BA4\u8D2D\u4E70\uFF0C\u6211\u73B0\u5728\u4ED8\u6B3E\u3002`;
|
|
2122
|
+
},
|
|
2123
|
+
/**
|
|
2124
|
+
* 6. 报告已支付
|
|
2125
|
+
*/
|
|
2126
|
+
paymentSent(txHash, amount) {
|
|
2127
|
+
return `\u5DF2\u4ED8\u6B3E\u5B8C\u6210\u3002\u4EA4\u6613\u54C8\u5E0C\u662F\uFF1A${txHash}\u3002
|
|
2128
|
+
[\u72B6\u6001\uFF1A\u5DF2\u53D1\u8D77\u652F\u4ED8 tx=${txHash} amount=${amount} USDC]`;
|
|
2129
|
+
},
|
|
2130
|
+
/**
|
|
2131
|
+
* 8. 确认收到交付
|
|
2132
|
+
*/
|
|
2133
|
+
deliveryReceived() {
|
|
2134
|
+
return `\u6536\u5230\uFF0C\u6211\u6B63\u5728\u4E0B\u8F7D\u68C0\u67E5\u3002`;
|
|
2135
|
+
},
|
|
2136
|
+
/**
|
|
2137
|
+
* 9. 确认收据
|
|
2138
|
+
*/
|
|
2139
|
+
receiptReceived() {
|
|
2140
|
+
return `\u6536\u636E\u6536\u5230\uFF0C\u670D\u52A1\u5B8C\u6210\u3002\u8C22\u8C22\uFF01`;
|
|
2141
|
+
},
|
|
2142
|
+
/**
|
|
2143
|
+
* 向 Boss 请求 Permit
|
|
2144
|
+
*/
|
|
2145
|
+
requestPermitFromBoss(params) {
|
|
2146
|
+
const { amount, agentAddress, deadlineHours = 24, reason } = params;
|
|
2147
|
+
return `Boss\uFF0C\u6211\u9700\u8981\u7528\u4E8E${reason || "\u8D2D\u4E70\u670D\u52A1"}\u7684 USDC \u652F\u4ED8\u989D\u5EA6\u6388\u6743\uFF08Permit\uFF09\u3002
|
|
2148
|
+
\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`;
|
|
2149
|
+
}
|
|
2150
|
+
};
|
|
2151
|
+
var StatusMarkers = {
|
|
2152
|
+
walletReady: "[\u72B6\u6001\uFF1A\u5DF2\u5177\u5907\u94B1\u5305\u5730\u5740]",
|
|
2153
|
+
permitReady: (amount) => `[\u72B6\u6001\uFF1A\u5DF2\u5177\u5907\u652F\u4ED8\u989D\u5EA6 USDC=${amount}]`,
|
|
2154
|
+
paymentSent: (txHash, amount) => `[\u72B6\u6001\uFF1A\u5DF2\u53D1\u8D77\u652F\u4ED8 tx=${txHash} amount=${amount} USDC]`,
|
|
2155
|
+
paymentConfirmed: (txHash) => `[\u72B6\u6001\uFF1A\u5DF2\u786E\u8BA4\u6536\u6B3E tx=${txHash}]`,
|
|
2156
|
+
delivered: (url, hash) => `[\u72B6\u6001\uFF1A\u5DF2\u4EA4\u4ED8 delivery_url=${url}${hash ? ` hash=${hash}` : ""}]`,
|
|
2157
|
+
receiptIssued: (invoiceId, txHash) => `[\u72B6\u6001\uFF1A\u6536\u636E\u5DF2\u51FA invoice=${invoiceId} tx=${txHash}]`
|
|
2158
|
+
};
|
|
2159
|
+
function parseStatusMarker(message) {
|
|
2160
|
+
const match = message.match(/\[状态:([^\]]+)\]/);
|
|
2161
|
+
if (!match) return null;
|
|
2162
|
+
const content = match[1];
|
|
2163
|
+
if (content === "\u5DF2\u5177\u5907\u94B1\u5305\u5730\u5740") {
|
|
2164
|
+
return { type: "wallet_ready", data: {} };
|
|
2165
|
+
}
|
|
2166
|
+
if (content.startsWith("\u5DF2\u5177\u5907\u652F\u4ED8\u989D\u5EA6")) {
|
|
2167
|
+
const amountMatch = content.match(/USDC=(\d+(?:\.\d+)?)/);
|
|
2168
|
+
return {
|
|
2169
|
+
type: "permit_ready",
|
|
2170
|
+
data: { amount: amountMatch?.[1] || "0" }
|
|
2171
|
+
};
|
|
2172
|
+
}
|
|
2173
|
+
if (content.startsWith("\u5DF2\u53D1\u8D77\u652F\u4ED8")) {
|
|
2174
|
+
const txMatch = content.match(/tx=(\S+)/);
|
|
2175
|
+
const amountMatch = content.match(/amount=(\d+(?:\.\d+)?)/);
|
|
2176
|
+
return {
|
|
2177
|
+
type: "payment_sent",
|
|
2178
|
+
data: {
|
|
2179
|
+
txHash: txMatch?.[1] || "",
|
|
2180
|
+
amount: amountMatch?.[1] || "0"
|
|
2181
|
+
}
|
|
2182
|
+
};
|
|
2183
|
+
}
|
|
2184
|
+
if (content.startsWith("\u5DF2\u786E\u8BA4\u6536\u6B3E")) {
|
|
2185
|
+
const txMatch = content.match(/tx=(\S+)/);
|
|
2186
|
+
return {
|
|
2187
|
+
type: "payment_confirmed",
|
|
2188
|
+
data: { txHash: txMatch?.[1] || "" }
|
|
2189
|
+
};
|
|
2190
|
+
}
|
|
2191
|
+
if (content.startsWith("\u5DF2\u4EA4\u4ED8")) {
|
|
2192
|
+
const urlMatch = content.match(/delivery_url=(\S+)/);
|
|
2193
|
+
const hashMatch = content.match(/hash=(\S+)/);
|
|
2194
|
+
return {
|
|
2195
|
+
type: "delivered",
|
|
2196
|
+
data: {
|
|
2197
|
+
url: urlMatch?.[1] || "",
|
|
2198
|
+
hash: hashMatch?.[1] || ""
|
|
2199
|
+
}
|
|
2200
|
+
};
|
|
2201
|
+
}
|
|
2202
|
+
if (content.startsWith("\u6536\u636E\u5DF2\u51FA")) {
|
|
2203
|
+
const invoiceMatch = content.match(/invoice=(\S+)/);
|
|
2204
|
+
const txMatch = content.match(/tx=(\S+)/);
|
|
2205
|
+
return {
|
|
2206
|
+
type: "receipt_issued",
|
|
2207
|
+
data: {
|
|
2208
|
+
invoiceId: invoiceMatch?.[1] || "",
|
|
2209
|
+
txHash: txMatch?.[1] || ""
|
|
2210
|
+
}
|
|
2211
|
+
};
|
|
2212
|
+
}
|
|
2213
|
+
return { type: "unknown", data: { raw: content } };
|
|
2214
|
+
}
|
|
1269
2215
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1270
2216
|
0 && (module.exports = {
|
|
1271
2217
|
AuditLog,
|
|
2218
|
+
BuyerTemplates,
|
|
1272
2219
|
CHAINS,
|
|
1273
2220
|
ERC20_ABI,
|
|
1274
2221
|
MemoryOrderStore,
|
|
1275
2222
|
OrderManager,
|
|
1276
2223
|
PaymentAgent,
|
|
1277
2224
|
PermitPayment,
|
|
2225
|
+
PermitWallet,
|
|
1278
2226
|
SecureWallet,
|
|
2227
|
+
SellerTemplates,
|
|
2228
|
+
StatusMarkers,
|
|
1279
2229
|
Wallet,
|
|
2230
|
+
createWallet,
|
|
2231
|
+
extractTransactionHash,
|
|
2232
|
+
formatPermitRequest,
|
|
2233
|
+
formatReceiptJson,
|
|
2234
|
+
formatReceiptMessage,
|
|
2235
|
+
formatReceiptText,
|
|
2236
|
+
generatePaymentGuide,
|
|
2237
|
+
generatePaymentReminder,
|
|
2238
|
+
generateReceipt,
|
|
2239
|
+
generateReceiptFromInvoice,
|
|
2240
|
+
generateWalletGuide,
|
|
1280
2241
|
getChain,
|
|
1281
2242
|
getChainById,
|
|
1282
2243
|
getTransactionStatus,
|
|
2244
|
+
getWalletAddress,
|
|
2245
|
+
hasTransactionHash,
|
|
1283
2246
|
listChains,
|
|
2247
|
+
loadWallet,
|
|
2248
|
+
parseStatusMarker,
|
|
1284
2249
|
verifyPayment,
|
|
1285
|
-
waitForTransaction
|
|
2250
|
+
waitForTransaction,
|
|
2251
|
+
walletExists
|
|
1286
2252
|
});
|
|
1287
2253
|
//# sourceMappingURL=index.js.map
|