moltspay 0.2.0 → 0.2.1

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.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/agent/PaymentAgent.ts","../src/chains/index.ts","../src/wallet/Wallet.ts","../src/audit/AuditLog.ts","../src/wallet/SecureWallet.ts","../src/wallet/createWallet.ts","../src/wallet/PermitWallet.ts","../src/permit/Permit.ts","../src/orders/index.ts","../src/verify/index.ts","../src/guide/index.ts","../src/receipt/index.ts","../src/templates/index.ts"],"sourcesContent":["/**\n * Payment Agent - Blockchain payment infrastructure for AI Agents\n * \n * @packageDocumentation\n */\n\n// 核心类\nexport { PaymentAgent } from './agent/PaymentAgent.js';\nexport { Wallet, SecureWallet } from './wallet/index.js';\nexport { PermitPayment } from './permit/index.js';\nexport { AuditLog } from './audit/AuditLog.js';\n\n// 钱包创建与 Permit 钱包\nexport {\n createWallet,\n loadWallet,\n getWalletAddress,\n walletExists,\n PermitWallet,\n formatPermitRequest,\n type CreateWalletOptions,\n type CreateWalletResult,\n type WalletData,\n type PermitWalletConfig,\n type PermitData,\n type TransferWithPermitParams,\n type TransferWithPermitResult,\n} from './wallet/index.js';\n\n// 订单管理\nexport { \n OrderManager, \n MemoryOrderStore,\n type Order,\n type OrderStatus,\n type OrderStore,\n type CreateOrderParams,\n} from './orders/index.js';\n\n// 支付验证\nexport {\n verifyPayment,\n getTransactionStatus,\n waitForTransaction,\n type VerifyPaymentParams,\n type VerifyPaymentResult,\n} from './verify/index.js';\n\n// 支付引导\nexport {\n generatePaymentGuide,\n generatePaymentReminder,\n generateWalletGuide,\n extractTransactionHash,\n hasTransactionHash,\n type PaymentGuideParams,\n} from './guide/index.js';\n\n// 收据\nexport {\n generateReceipt,\n generateReceiptFromInvoice,\n formatReceiptMessage,\n formatReceiptText,\n formatReceiptJson,\n type ReceiptParams,\n type Receipt,\n} from './receipt/index.js';\n\n// 对话模板\nexport {\n SellerTemplates,\n BuyerTemplates,\n StatusMarkers,\n parseStatusMarker,\n} from './templates/index.js';\n\n// 链配置\nexport { CHAINS, getChain, listChains, getChainById, ERC20_ABI } from './chains/index.js';\n\n// 类型\nexport * from './types/index.js';\n","/**\n * PaymentAgent - 核心支付代理\n * \n * 功能:\n * - 生成 Invoice(支付请求)\n * - 验证链上支付\n * - 生成钱包深度链接\n */\n\nimport { ethers } from 'ethers';\nimport { getChain, ERC20_ABI } from '../chains/index.js';\nimport type {\n PaymentAgentConfig,\n ChainName,\n ChainConfig,\n Invoice,\n CreateInvoiceParams,\n VerifyResult,\n VerifyOptions,\n WalletBalance,\n} from '../types/index.js';\n\nexport class PaymentAgent {\n readonly chain: ChainName;\n readonly chainConfig: ChainConfig;\n readonly walletAddress: string;\n \n private provider: ethers.JsonRpcProvider;\n private usdcContract: ethers.Contract;\n \n static readonly PROTOCOL_VERSION = '1.0';\n\n constructor(config: PaymentAgentConfig = {}) {\n this.chain = config.chain || 'base_sepolia';\n this.chainConfig = getChain(this.chain);\n this.walletAddress = config.walletAddress || process.env.PAYMENT_AGENT_WALLET || '';\n \n if (!this.walletAddress) {\n throw new Error('walletAddress is required. Set via config or PAYMENT_AGENT_WALLET env var.');\n }\n\n const rpcUrl = config.rpcUrl || this.chainConfig.rpc;\n this.provider = new ethers.JsonRpcProvider(rpcUrl);\n this.usdcContract = new ethers.Contract(\n this.chainConfig.usdc,\n ERC20_ABI,\n this.provider\n );\n }\n\n /**\n * 生成支付请求(Invoice)\n */\n createInvoice(params: CreateInvoiceParams): Invoice {\n const expiresMinutes = params.expiresMinutes || 30;\n const expiresAt = new Date(Date.now() + expiresMinutes * 60 * 1000).toISOString();\n \n const invoice: Invoice = {\n type: 'payment_request',\n version: PaymentAgent.PROTOCOL_VERSION,\n order_id: params.orderId,\n service: params.service,\n description: params.description || `${params.service} service`,\n amount: params.amount.toFixed(2),\n token: 'USDC',\n chain: this.chain,\n chain_id: this.chainConfig.chainId,\n recipient: this.walletAddress,\n memo: params.orderId,\n expires_at: expiresAt,\n deep_link: this.generateDeepLink(params.amount, params.orderId),\n explorer_url: `${this.chainConfig.explorer}${this.walletAddress}`,\n };\n\n if (params.metadata) {\n invoice.metadata = params.metadata;\n }\n\n return invoice;\n }\n\n /**\n * 生成钱包深度链接(支持 MetaMask 等)\n */\n generateDeepLink(amount: number, memo: string): string {\n const amountWei = Math.floor(amount * 1e6); // USDC 6位小数\n return `https://metamask.app.link/send/${this.chainConfig.usdc}@${this.chainConfig.chainId}/transfer?address=${this.walletAddress}&uint256=${amountWei}`;\n }\n\n /**\n * 验证链上支付\n */\n async verifyPayment(txHash: string, options: VerifyOptions = {}): Promise<VerifyResult> {\n try {\n // 确保 txHash 格式正确\n if (!txHash.startsWith('0x')) {\n txHash = '0x' + txHash;\n }\n\n const receipt = await this.provider.getTransactionReceipt(txHash);\n \n if (!receipt) {\n return { verified: false, error: 'Transaction not found', pending: true };\n }\n\n if (receipt.status !== 1) {\n return { verified: false, error: 'Transaction failed' };\n }\n\n // Transfer 事件签名\n const transferTopic = ethers.id('Transfer(address,address,uint256)');\n const usdcAddress = this.chainConfig.usdc.toLowerCase();\n\n for (const log of receipt.logs) {\n // 检查是否是 USDC 合约的 Transfer 事件\n if (\n log.address.toLowerCase() === usdcAddress &&\n log.topics.length >= 3 &&\n log.topics[0] === transferTopic\n ) {\n // 解析 from, to, amount\n const from = ethers.getAddress('0x' + log.topics[1].slice(-40));\n const to = ethers.getAddress('0x' + log.topics[2].slice(-40));\n const amountWei = BigInt(log.data);\n const amount = Number(amountWei) / 1e6;\n\n // 检查接收地址\n if (to.toLowerCase() !== this.walletAddress.toLowerCase()) {\n continue;\n }\n\n // 检查金额(允许误差)\n const tolerance = options.tolerance ?? 0.01;\n if (options.expectedAmount) {\n const diff = Math.abs(amount - options.expectedAmount);\n if (diff > options.expectedAmount * tolerance) {\n return {\n verified: false,\n error: `Amount mismatch: expected ${options.expectedAmount}, got ${amount}`,\n };\n }\n }\n\n const currentBlock = await this.provider.getBlockNumber();\n \n return {\n verified: true,\n tx_hash: txHash,\n amount: amount.toFixed(2),\n token: 'USDC',\n from,\n to,\n block_number: receipt.blockNumber,\n confirmations: currentBlock - receipt.blockNumber,\n explorer_url: `${this.chainConfig.explorerTx}${txHash}`,\n };\n }\n }\n\n return { verified: false, error: 'No USDC transfer to recipient found in transaction' };\n } catch (error) {\n return { verified: false, error: (error as Error).message };\n }\n }\n\n /**\n * 扫描最近转账(按金额匹配)\n */\n async scanRecentTransfers(expectedAmount: number, timeoutMinutes: number = 30): Promise<VerifyResult> {\n try {\n const currentBlock = await this.provider.getBlockNumber();\n const blocksPerMinute = Math.ceil(60 / this.chainConfig.avgBlockTime);\n const fromBlock = currentBlock - (timeoutMinutes * blocksPerMinute);\n\n // 使用 getLogs 扫描 Transfer 事件\n const transferTopic = ethers.id('Transfer(address,address,uint256)');\n const recipientTopic = ethers.zeroPadValue(this.walletAddress, 32);\n\n const logs = await this.provider.getLogs({\n address: this.chainConfig.usdc,\n topics: [transferTopic, null, recipientTopic],\n fromBlock,\n toBlock: 'latest',\n });\n\n for (const log of logs) {\n const amountWei = BigInt(log.data);\n const amount = Number(amountWei) / 1e6;\n\n // 按金额匹配\n if (Math.abs(amount - expectedAmount) < 0.01) {\n const from = ethers.getAddress('0x' + log.topics[1].slice(-40));\n \n return {\n verified: true,\n tx_hash: log.transactionHash,\n amount: amount.toFixed(2),\n token: 'USDC',\n from,\n to: this.walletAddress,\n block_number: log.blockNumber,\n explorer_url: `${this.chainConfig.explorerTx}${log.transactionHash}`,\n };\n }\n }\n\n return { verified: false, error: 'No matching payment found' };\n } catch (error) {\n return { verified: false, error: (error as Error).message };\n }\n }\n\n /**\n * 获取钱包余额\n */\n async getBalance(address?: string): Promise<WalletBalance> {\n const addr = address || this.walletAddress;\n \n const [ethBalance, usdcBalance] = await Promise.all([\n this.provider.getBalance(addr),\n this.usdcContract.balanceOf(addr),\n ]);\n\n return {\n address: addr,\n eth: ethers.formatEther(ethBalance),\n usdc: (Number(usdcBalance) / 1e6).toFixed(2),\n chain: this.chain,\n };\n }\n\n /**\n * 格式化 Invoice 为人类可读消息\n */\n formatInvoiceMessage(invoice: Invoice, includeJson: boolean = true): string {\n let msg = `🎬 **Payment Request**\n\n**Service:** ${invoice.service}\n**Price:** ${invoice.amount} USDC (${this.chainConfig.name})\n\n**💳 Payment Options:**\n\n1️⃣ **Direct Transfer:**\n Send exactly \\`${invoice.amount} USDC\\` to:\n \\`${invoice.recipient}\\`\n (Network: ${this.chainConfig.name})\n\n2️⃣ **One-Click Pay (MetaMask):**\n ${invoice.deep_link}\n\n⏱️ Expires: ${invoice.expires_at}`;\n\n if (includeJson) {\n msg += `\n\n3️⃣ **For AI Agents:**\n\\`\\`\\`json\n${JSON.stringify(invoice, null, 2)}\n\\`\\`\\``;\n }\n\n msg += `\n\nAfter payment, reply with your tx hash:\n\\`paid: 0x...\\``;\n\n return msg;\n }\n}\n","/**\n * 区块链配置\n */\n\nimport type { ChainConfig, ChainName } from '../types/index.js';\n\nexport const CHAINS: Record<ChainName, ChainConfig> = {\n // ============ 主网 ============\n base: {\n name: 'Base',\n chainId: 8453,\n rpc: 'https://mainnet.base.org',\n usdc: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',\n explorer: 'https://basescan.org/address/',\n explorerTx: 'https://basescan.org/tx/',\n avgBlockTime: 2,\n },\n polygon: {\n name: 'Polygon',\n chainId: 137,\n rpc: 'https://polygon-rpc.com',\n usdc: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',\n explorer: 'https://polygonscan.com/address/',\n explorerTx: 'https://polygonscan.com/tx/',\n avgBlockTime: 2,\n },\n ethereum: {\n name: 'Ethereum',\n chainId: 1,\n rpc: 'https://eth.llamarpc.com',\n usdc: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',\n explorer: 'https://etherscan.io/address/',\n explorerTx: 'https://etherscan.io/tx/',\n avgBlockTime: 12,\n },\n\n // ============ 测试网 ============\n base_sepolia: {\n name: 'Base Sepolia',\n chainId: 84532,\n rpc: 'https://sepolia.base.org',\n usdc: '0x036CbD53842c5426634e7929541eC2318f3dCF7e',\n explorer: 'https://sepolia.basescan.org/address/',\n explorerTx: 'https://sepolia.basescan.org/tx/',\n avgBlockTime: 2,\n },\n sepolia: {\n name: 'Sepolia',\n chainId: 11155111,\n rpc: 'https://rpc.sepolia.org',\n usdc: '0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238',\n explorer: 'https://sepolia.etherscan.io/address/',\n explorerTx: 'https://sepolia.etherscan.io/tx/',\n avgBlockTime: 12,\n },\n};\n\n/**\n * 获取链配置\n */\nexport function getChain(name: ChainName): ChainConfig {\n const config = CHAINS[name];\n if (!config) {\n throw new Error(`Unsupported chain: ${name}. Supported: ${Object.keys(CHAINS).join(', ')}`);\n }\n return config;\n}\n\n/**\n * 列出所有支持的链\n */\nexport function listChains(): ChainName[] {\n return Object.keys(CHAINS) as ChainName[];\n}\n\n/**\n * 根据 chainId 获取链配置\n */\nexport function getChainById(chainId: number): ChainConfig | undefined {\n return Object.values(CHAINS).find(c => c.chainId === chainId);\n}\n\n/**\n * ERC20 ABI(最小化,仅包含需要的方法)\n */\nexport const ERC20_ABI = [\n 'function balanceOf(address owner) view returns (uint256)',\n 'function transfer(address to, uint256 amount) returns (bool)',\n 'function approve(address spender, uint256 amount) returns (bool)',\n 'function allowance(address owner, address spender) view returns (uint256)',\n 'function decimals() view returns (uint8)',\n 'function symbol() view returns (string)',\n 'function name() view returns (string)',\n 'function nonces(address owner) view returns (uint256)',\n 'function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s)',\n 'event Transfer(address indexed from, address indexed to, uint256 value)',\n 'event Approval(address indexed owner, address indexed spender, uint256 value)',\n];\n\nexport type { ChainConfig, ChainName };\n","/**\n * Wallet - 基础托管钱包\n * \n * 功能:\n * - 查询余额\n * - 发送 USDC 转账\n */\n\nimport { ethers } from 'ethers';\nimport { getChain, ERC20_ABI } from '../chains/index.js';\nimport type {\n ChainName,\n ChainConfig,\n WalletBalance,\n TransferResult,\n} from '../types/index.js';\n\nexport interface WalletConfig {\n chain?: ChainName;\n privateKey?: string;\n rpcUrl?: string;\n}\n\nexport class Wallet {\n readonly chain: ChainName;\n readonly chainConfig: ChainConfig;\n readonly address: string;\n \n private wallet: ethers.Wallet;\n private provider: ethers.JsonRpcProvider;\n private usdcContract: ethers.Contract;\n\n constructor(config: WalletConfig = {}) {\n this.chain = config.chain || 'base_sepolia';\n this.chainConfig = getChain(this.chain);\n \n const privateKey = config.privateKey || process.env.PAYMENT_AGENT_PRIVATE_KEY;\n if (!privateKey) {\n throw new Error('privateKey is required. Set via config or PAYMENT_AGENT_PRIVATE_KEY env var.');\n }\n\n const rpcUrl = config.rpcUrl || this.chainConfig.rpc;\n this.provider = new ethers.JsonRpcProvider(rpcUrl);\n this.wallet = new ethers.Wallet(privateKey, this.provider);\n this.address = this.wallet.address;\n \n this.usdcContract = new ethers.Contract(\n this.chainConfig.usdc,\n ERC20_ABI,\n this.wallet\n );\n }\n\n /**\n * 获取钱包余额\n */\n async getBalance(): Promise<WalletBalance> {\n const [ethBalance, usdcBalance] = await Promise.all([\n this.provider.getBalance(this.address),\n this.usdcContract.balanceOf(this.address),\n ]);\n\n return {\n address: this.address,\n eth: ethers.formatEther(ethBalance),\n usdc: (Number(usdcBalance) / 1e6).toFixed(2),\n chain: this.chain,\n };\n }\n\n /**\n * 发送 USDC 转账\n */\n async transfer(to: string, amount: number): Promise<TransferResult> {\n try {\n // 验证地址\n to = ethers.getAddress(to);\n \n // 转换金额(USDC 6位小数)\n const amountWei = BigInt(Math.floor(amount * 1e6));\n\n // 检查余额\n const balance = await this.usdcContract.balanceOf(this.address);\n if (BigInt(balance) < amountWei) {\n return {\n success: false,\n error: `Insufficient USDC balance: ${Number(balance) / 1e6} < ${amount}`,\n };\n }\n\n // 发送交易\n const tx = await this.usdcContract.transfer(to, amountWei);\n const receipt = await tx.wait();\n\n if (receipt.status === 1) {\n return {\n success: true,\n tx_hash: tx.hash,\n from: this.address,\n to,\n amount,\n gas_used: Number(receipt.gasUsed),\n block_number: receipt.blockNumber,\n explorer_url: `${this.chainConfig.explorerTx}${tx.hash}`,\n };\n } else {\n return {\n success: false,\n tx_hash: tx.hash,\n error: 'Transaction reverted',\n };\n }\n } catch (error) {\n return {\n success: false,\n error: (error as Error).message,\n };\n }\n }\n\n /**\n * 获取 ETH 余额\n */\n async getEthBalance(): Promise<string> {\n const balance = await this.provider.getBalance(this.address);\n return ethers.formatEther(balance);\n }\n\n /**\n * 获取 USDC 余额\n */\n async getUsdcBalance(): Promise<string> {\n const balance = await this.usdcContract.balanceOf(this.address);\n return (Number(balance) / 1e6).toFixed(2);\n }\n}\n","/**\n * AuditLog - 不可篡改审计日志\n * \n * 特点:\n * - 链式哈希,任何修改都会破坏链条\n * - 按日期分文件存储\n * - JSONL 格式便于追加和解析\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as crypto from 'crypto';\nimport type { AuditEntry, AuditAction } from '../types/index.js';\n\nexport interface LogParams {\n action: AuditAction;\n request_id: string;\n from?: string;\n to?: string;\n amount?: number;\n tx_hash?: string;\n reason?: string;\n requester?: string;\n metadata?: Record<string, unknown>;\n}\n\nexport class AuditLog {\n private basePath: string;\n private lastHash: string = '0000000000000000';\n\n constructor(basePath?: string) {\n this.basePath = basePath || path.join(process.cwd(), 'data', 'audit');\n this.ensureDir();\n this.loadLastHash();\n }\n\n /**\n * 记录审计日志\n */\n async log(params: LogParams): Promise<AuditEntry> {\n const now = new Date();\n \n const entry: AuditEntry = {\n timestamp: now.getTime() / 1000,\n datetime: now.toISOString(),\n action: params.action,\n request_id: params.request_id,\n from: params.from,\n to: params.to,\n amount: params.amount,\n tx_hash: params.tx_hash,\n reason: params.reason,\n requester: params.requester,\n prev_hash: this.lastHash,\n hash: '', // 计算后填充\n metadata: params.metadata,\n };\n\n // 计算哈希(不包含 hash 字段本身)\n entry.hash = this.calculateHash(entry);\n this.lastHash = entry.hash;\n\n // 写入文件\n const filePath = this.getFilePath(now);\n const line = JSON.stringify(entry) + '\\n';\n fs.appendFileSync(filePath, line, 'utf-8');\n\n return entry;\n }\n\n /**\n * 读取指定日期的日志\n */\n read(date?: Date): AuditEntry[] {\n const filePath = this.getFilePath(date || new Date());\n \n if (!fs.existsSync(filePath)) {\n return [];\n }\n\n const content = fs.readFileSync(filePath, 'utf-8');\n const lines = content.trim().split('\\n').filter(Boolean);\n \n return lines.map(line => JSON.parse(line) as AuditEntry);\n }\n\n /**\n * 验证日志完整性\n */\n verify(date?: Date): { valid: boolean; errors: string[] } {\n const entries = this.read(date);\n const errors: string[] = [];\n\n for (let i = 0; i < entries.length; i++) {\n const entry = entries[i];\n \n // 验证哈希\n const expectedHash = this.calculateHash(entry);\n if (entry.hash !== expectedHash) {\n errors.push(`Entry ${i}: hash mismatch (expected ${expectedHash}, got ${entry.hash})`);\n }\n\n // 验证链接\n if (i > 0 && entry.prev_hash !== entries[i - 1].hash) {\n errors.push(`Entry ${i}: prev_hash mismatch`);\n }\n }\n\n return { valid: errors.length === 0, errors };\n }\n\n /**\n * 搜索日志\n */\n search(filter: Partial<{\n action: AuditAction;\n request_id: string;\n from: string;\n to: string;\n startDate: Date;\n endDate: Date;\n }>): AuditEntry[] {\n const results: AuditEntry[] = [];\n const startDate = filter.startDate || new Date(Date.now() - 30 * 24 * 60 * 60 * 1000);\n const endDate = filter.endDate || new Date();\n\n // 遍历日期范围\n const current = new Date(startDate);\n while (current <= endDate) {\n const entries = this.read(current);\n \n for (const entry of entries) {\n let match = true;\n\n if (filter.action && entry.action !== filter.action) match = false;\n if (filter.request_id && entry.request_id !== filter.request_id) match = false;\n if (filter.from && entry.from?.toLowerCase() !== filter.from.toLowerCase()) match = false;\n if (filter.to && entry.to?.toLowerCase() !== filter.to.toLowerCase()) match = false;\n\n if (match) {\n results.push(entry);\n }\n }\n\n current.setDate(current.getDate() + 1);\n }\n\n return results;\n }\n\n /**\n * 获取日志文件路径\n */\n private getFilePath(date: Date): string {\n const dateStr = date.toISOString().slice(0, 10);\n return path.join(this.basePath, `audit_${dateStr}.jsonl`);\n }\n\n /**\n * 计算条目哈希\n */\n private calculateHash(entry: AuditEntry): string {\n const data = {\n timestamp: entry.timestamp,\n action: entry.action,\n request_id: entry.request_id,\n from: entry.from,\n to: entry.to,\n amount: entry.amount,\n tx_hash: entry.tx_hash,\n prev_hash: entry.prev_hash,\n };\n \n const str = JSON.stringify(data);\n return crypto.createHash('sha256').update(str).digest('hex').slice(0, 16);\n }\n\n /**\n * 加载最后一条日志的哈希\n */\n private loadLastHash(): void {\n const today = new Date();\n \n // 检查今天和昨天的日志\n for (let i = 0; i < 2; i++) {\n const date = new Date(today);\n date.setDate(date.getDate() - i);\n \n const entries = this.read(date);\n if (entries.length > 0) {\n this.lastHash = entries[entries.length - 1].hash;\n return;\n }\n }\n }\n\n /**\n * 确保目录存在\n */\n private ensureDir(): void {\n if (!fs.existsSync(this.basePath)) {\n fs.mkdirSync(this.basePath, { recursive: true });\n }\n }\n}\n","/**\n * SecureWallet - 安全托管钱包\n * \n * 在基础 Wallet 之上增加:\n * - 单笔限额控制\n * - 日限额控制\n * - 白名单机制\n * - 审计日志\n * - 超限审批队列\n */\n\nimport { Wallet, type WalletConfig } from './Wallet.js';\nimport { AuditLog } from '../audit/AuditLog.js';\nimport type {\n SecurityLimits,\n SecureWalletConfig,\n TransferResult,\n TransferParams,\n PendingTransfer,\n} from '../types/index.js';\n\nconst DEFAULT_LIMITS: SecurityLimits = {\n singleMax: 100, // 单笔最大 $100\n dailyMax: 1000, // 日最大 $1000\n requireWhitelist: true,\n};\n\nexport class SecureWallet {\n private wallet: Wallet;\n private limits: SecurityLimits;\n private whitelist: Set<string>;\n private auditLog: AuditLog;\n private dailyTotal: number = 0;\n private dailyDate: string = '';\n private pendingTransfers: Map<string, PendingTransfer> = new Map();\n\n constructor(config: SecureWalletConfig = {}) {\n this.wallet = new Wallet({\n chain: config.chain,\n privateKey: config.privateKey,\n });\n\n this.limits = { ...DEFAULT_LIMITS, ...config.limits };\n this.whitelist = new Set((config.whitelist || []).map(a => a.toLowerCase()));\n this.auditLog = new AuditLog(config.auditPath);\n }\n\n /**\n * 获取钱包地址\n */\n get address(): string {\n return this.wallet.address;\n }\n\n /**\n * 获取余额\n */\n async getBalance() {\n return this.wallet.getBalance();\n }\n\n /**\n * 安全转账(带限额和白名单检查)\n * \n * 支持两种调用方式:\n * - transfer({ to, amount, reason?, requester? })\n * - transfer(to, amount)\n */\n async transfer(paramsOrTo: TransferParams | string, amountArg?: number | string): Promise<TransferResult> {\n // 支持两种调用方式\n let params: TransferParams;\n if (typeof paramsOrTo === 'string') {\n params = { \n to: paramsOrTo, \n amount: typeof amountArg === 'string' ? parseFloat(amountArg) : (amountArg || 0)\n };\n } else {\n params = paramsOrTo;\n }\n \n const { to, amount, reason, requester } = params;\n const toAddress = to.toLowerCase();\n const requestId = `tr_${Date.now().toString(36)}${Math.random().toString(36).slice(2, 8)}`;\n\n // 记录请求\n await this.auditLog.log({\n action: 'transfer_request',\n request_id: requestId,\n from: this.wallet.address,\n to,\n amount,\n reason,\n requester,\n });\n\n // 1. 白名单检查\n if (this.limits.requireWhitelist && !this.whitelist.has(toAddress)) {\n await this.auditLog.log({\n action: 'transfer_failed',\n request_id: requestId,\n metadata: { error: 'Address not in whitelist' },\n });\n return { success: false, error: `Address not in whitelist: ${to}` };\n }\n\n // 2. 单笔限额检查\n if (amount > this.limits.singleMax) {\n // 加入审批队列\n const pending: PendingTransfer = {\n id: requestId,\n to,\n amount,\n reason,\n requester,\n created_at: new Date().toISOString(),\n status: 'pending',\n };\n this.pendingTransfers.set(requestId, pending);\n \n await this.auditLog.log({\n action: 'transfer_request',\n request_id: requestId,\n metadata: { pending: true, reason: 'Exceeds single limit' },\n });\n \n return {\n success: false,\n error: `Amount ${amount} exceeds single limit ${this.limits.singleMax}. Pending approval: ${requestId}`,\n };\n }\n\n // 3. 日限额检查\n this.updateDailyTotal();\n if (this.dailyTotal + amount > this.limits.dailyMax) {\n const pending: PendingTransfer = {\n id: requestId,\n to,\n amount,\n reason,\n requester,\n created_at: new Date().toISOString(),\n status: 'pending',\n };\n this.pendingTransfers.set(requestId, pending);\n \n await this.auditLog.log({\n action: 'transfer_request',\n request_id: requestId,\n metadata: { pending: true, reason: 'Exceeds daily limit' },\n });\n \n return {\n success: false,\n error: `Daily limit would be exceeded (${this.dailyTotal} + ${amount} > ${this.limits.dailyMax}). Pending approval: ${requestId}`,\n };\n }\n\n // 4. 执行转账\n const result = await this.wallet.transfer(to, amount);\n\n // 5. 记录结果\n if (result.success) {\n this.dailyTotal += amount;\n await this.auditLog.log({\n action: 'transfer_executed',\n request_id: requestId,\n from: this.wallet.address,\n to,\n amount,\n tx_hash: result.tx_hash,\n reason,\n requester,\n });\n } else {\n await this.auditLog.log({\n action: 'transfer_failed',\n request_id: requestId,\n metadata: { error: result.error },\n });\n }\n\n return result;\n }\n\n /**\n * 审批待处理转账\n */\n async approve(requestId: string, approver: string): Promise<TransferResult> {\n const pending = this.pendingTransfers.get(requestId);\n if (!pending) {\n return { success: false, error: `Pending transfer not found: ${requestId}` };\n }\n\n if (pending.status !== 'pending') {\n return { success: false, error: `Transfer already ${pending.status}` };\n }\n\n await this.auditLog.log({\n action: 'transfer_approved',\n request_id: requestId,\n metadata: { approver },\n });\n\n pending.status = 'approved';\n\n // 执行转账(跳过限额检查)\n const result = await this.wallet.transfer(pending.to, pending.amount);\n\n if (result.success) {\n pending.status = 'executed';\n this.dailyTotal += pending.amount;\n \n await this.auditLog.log({\n action: 'transfer_executed',\n request_id: requestId,\n from: this.wallet.address,\n to: pending.to,\n amount: pending.amount,\n tx_hash: result.tx_hash,\n reason: pending.reason,\n requester: pending.requester,\n metadata: { approved_by: approver },\n });\n } else {\n await this.auditLog.log({\n action: 'transfer_failed',\n request_id: requestId,\n metadata: { error: result.error },\n });\n }\n\n return result;\n }\n\n /**\n * 拒绝待处理转账\n */\n async reject(requestId: string, rejecter: string, reason?: string): Promise<void> {\n const pending = this.pendingTransfers.get(requestId);\n if (!pending) {\n throw new Error(`Pending transfer not found: ${requestId}`);\n }\n\n pending.status = 'rejected';\n\n await this.auditLog.log({\n action: 'transfer_rejected',\n request_id: requestId,\n metadata: { rejected_by: rejecter, reason },\n });\n }\n\n /**\n * 添加白名单地址\n */\n async addToWhitelist(address: string, addedBy: string): Promise<void> {\n const addr = address.toLowerCase();\n this.whitelist.add(addr);\n\n await this.auditLog.log({\n action: 'whitelist_add',\n request_id: `wl_${Date.now()}`,\n to: address,\n metadata: { added_by: addedBy },\n });\n }\n\n /**\n * 移除白名单地址\n */\n async removeFromWhitelist(address: string, removedBy: string): Promise<void> {\n const addr = address.toLowerCase();\n this.whitelist.delete(addr);\n\n await this.auditLog.log({\n action: 'whitelist_remove',\n request_id: `wl_${Date.now()}`,\n to: address,\n metadata: { removed_by: removedBy },\n });\n }\n\n /**\n * 检查地址是否在白名单\n */\n isWhitelisted(address: string): boolean {\n return this.whitelist.has(address.toLowerCase());\n }\n\n /**\n * 获取待处理转账列表\n */\n getPendingTransfers(): PendingTransfer[] {\n return Array.from(this.pendingTransfers.values())\n .filter(p => p.status === 'pending');\n }\n\n /**\n * 获取当前限额配置\n */\n getLimits(): SecurityLimits {\n return { ...this.limits };\n }\n\n /**\n * 获取今日已用额度\n */\n getDailyUsed(): number {\n this.updateDailyTotal();\n return this.dailyTotal;\n }\n\n /**\n * 更新日限额计数器\n */\n private updateDailyTotal(): void {\n const today = new Date().toISOString().slice(0, 10);\n if (this.dailyDate !== today) {\n this.dailyDate = today;\n this.dailyTotal = 0;\n }\n }\n}\n","/**\n * createWallet - 为 Agent 创建新钱包\n * \n * 功能:\n * - 生成新的以太坊钱包\n * - 安全存储私钥(加密或明文,取决于配置)\n * - 返回钱包地址(不返回私钥)\n */\n\nimport { ethers } from 'ethers';\nimport { writeFileSync, readFileSync, existsSync, mkdirSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { createCipheriv, createDecipheriv, randomBytes, scryptSync } from 'crypto';\n\nexport interface CreateWalletOptions {\n /** 存储路径,默认 ~/.moltspay/wallet.json */\n storagePath?: string;\n /** 加密密码(可选,不提供则明文存储) */\n password?: string;\n /** 钱包标签/名称 */\n label?: string;\n /** 如果钱包已存在,是否覆盖 */\n overwrite?: boolean;\n}\n\nexport interface WalletData {\n address: string;\n label?: string;\n createdAt: string;\n encrypted: boolean;\n /** 加密后的私钥或明文私钥 */\n privateKey: string;\n /** 加密用的 IV */\n iv?: string;\n /** 加密用的 salt */\n salt?: string;\n}\n\nexport interface CreateWalletResult {\n success: boolean;\n address?: string;\n storagePath?: string;\n error?: string;\n /** 是否是新创建的(false 表示加载了已有钱包) */\n isNew?: boolean;\n}\n\nconst DEFAULT_STORAGE_DIR = join(process.env.HOME || '~', '.moltspay');\nconst DEFAULT_STORAGE_FILE = 'wallet.json';\n\n/**\n * 加密私钥\n */\nfunction encryptPrivateKey(privateKey: string, password: string): { encrypted: string; iv: string; salt: string } {\n const salt = randomBytes(16);\n const key = scryptSync(password, salt, 32);\n const iv = randomBytes(16);\n \n const cipher = createCipheriv('aes-256-cbc', key, iv);\n let encrypted = cipher.update(privateKey, 'utf8', 'hex');\n encrypted += cipher.final('hex');\n \n return {\n encrypted,\n iv: iv.toString('hex'),\n salt: salt.toString('hex'),\n };\n}\n\n/**\n * 解密私钥\n */\nfunction decryptPrivateKey(encrypted: string, password: string, iv: string, salt: string): string {\n const key = scryptSync(password, Buffer.from(salt, 'hex'), 32);\n const decipher = createDecipheriv('aes-256-cbc', key, Buffer.from(iv, 'hex'));\n \n let decrypted = decipher.update(encrypted, 'hex', 'utf8');\n decrypted += decipher.final('utf8');\n \n return decrypted;\n}\n\n/**\n * 创建新钱包\n * \n * @example\n * ```typescript\n * // 创建未加密钱包\n * const result = await createWallet();\n * console.log('钱包地址:', result.address);\n * \n * // 创建加密钱包\n * const result = await createWallet({ password: 'mySecurePassword' });\n * \n * // 指定存储路径\n * const result = await createWallet({ storagePath: './my-wallet.json' });\n * ```\n */\nexport function createWallet(options: CreateWalletOptions = {}): CreateWalletResult {\n const storagePath = options.storagePath || join(DEFAULT_STORAGE_DIR, DEFAULT_STORAGE_FILE);\n \n // 检查是否已存在\n if (existsSync(storagePath) && !options.overwrite) {\n // 加载已有钱包\n try {\n const existing = JSON.parse(readFileSync(storagePath, 'utf8')) as WalletData;\n return {\n success: true,\n address: existing.address,\n storagePath,\n isNew: false,\n };\n } catch (error) {\n return {\n success: false,\n error: `Failed to load existing wallet: ${(error as Error).message}`,\n };\n }\n }\n\n try {\n // 创建新钱包\n const wallet = ethers.Wallet.createRandom();\n \n // 准备存储数据\n const walletData: WalletData = {\n address: wallet.address,\n label: options.label,\n createdAt: new Date().toISOString(),\n encrypted: !!options.password,\n privateKey: '',\n };\n\n if (options.password) {\n // 加密存储\n const { encrypted, iv, salt } = encryptPrivateKey(wallet.privateKey, options.password);\n walletData.privateKey = encrypted;\n walletData.iv = iv;\n walletData.salt = salt;\n } else {\n // 明文存储(不推荐,但对于测试/开发方便)\n walletData.privateKey = wallet.privateKey;\n }\n\n // 确保目录存在\n const dir = dirname(storagePath);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n\n // 写入文件\n writeFileSync(storagePath, JSON.stringify(walletData, null, 2), { mode: 0o600 });\n\n return {\n success: true,\n address: wallet.address,\n storagePath,\n isNew: true,\n };\n } catch (error) {\n return {\n success: false,\n error: (error as Error).message,\n };\n }\n}\n\n/**\n * 加载已有钱包\n */\nexport function loadWallet(options: { storagePath?: string; password?: string } = {}): {\n success: boolean;\n address?: string;\n privateKey?: string;\n error?: string;\n} {\n const storagePath = options.storagePath || join(DEFAULT_STORAGE_DIR, DEFAULT_STORAGE_FILE);\n\n if (!existsSync(storagePath)) {\n return { success: false, error: 'Wallet not found. Run createWallet() first.' };\n }\n\n try {\n const data = JSON.parse(readFileSync(storagePath, 'utf8')) as WalletData;\n\n if (data.encrypted) {\n if (!options.password) {\n return { success: false, error: 'Wallet is encrypted. Password required.' };\n }\n const privateKey = decryptPrivateKey(data.privateKey, options.password, data.iv!, data.salt!);\n return { success: true, address: data.address, privateKey };\n } else {\n return { success: true, address: data.address, privateKey: data.privateKey };\n }\n } catch (error) {\n return { success: false, error: (error as Error).message };\n }\n}\n\n/**\n * 获取钱包地址(不需要密码)\n */\nexport function getWalletAddress(storagePath?: string): string | null {\n const path = storagePath || join(DEFAULT_STORAGE_DIR, DEFAULT_STORAGE_FILE);\n \n if (!existsSync(path)) {\n return null;\n }\n\n try {\n const data = JSON.parse(readFileSync(path, 'utf8')) as WalletData;\n return data.address;\n } catch {\n return null;\n }\n}\n\n/**\n * 检查钱包是否存在\n */\nexport function walletExists(storagePath?: string): boolean {\n const path = storagePath || join(DEFAULT_STORAGE_DIR, DEFAULT_STORAGE_FILE);\n return existsSync(path);\n}\n","/**\n * PermitWallet - 使用 Boss 授权的 Permit 进行支付\n * \n * 场景:\n * - Agent 没有自己的 USDC,但 Boss 给了 Permit 授权\n * - Agent 使用 Permit 签名 + 自己的钱包执行 transferFrom\n * - Agent 只需要少量 ETH 付 gas,USDC 从 Boss 钱包扣除\n */\n\nimport { ethers } from 'ethers';\nimport { getChain, ERC20_ABI } from '../chains/index.js';\nimport { loadWallet } from './createWallet.js';\nimport type {\n ChainName,\n ChainConfig,\n TransferResult,\n PermitSignature,\n} from '../types/index.js';\n\nexport interface PermitData {\n /** Boss 的钱包地址(USDC 持有者) */\n owner: string;\n /** Agent 的钱包地址(被授权者) */\n spender: string;\n /** 授权金额(USDC,6位小数的原始值) */\n value: string;\n /** 过期时间戳 */\n deadline: number;\n /** 签名 v */\n v: number;\n /** 签名 r */\n r: string;\n /** 签名 s */\n s: string;\n}\n\nexport interface PermitWalletConfig {\n chain?: ChainName;\n /** Agent 的私钥(用于执行交易) */\n privateKey?: string;\n /** 从文件加载私钥 */\n walletPath?: string;\n /** 解密密码 */\n walletPassword?: string;\n rpcUrl?: string;\n}\n\nexport interface TransferWithPermitParams {\n /** 收款地址 */\n to: string;\n /** 金额(USDC) */\n amount: number;\n /** Boss 签署的 Permit 数据 */\n permit: PermitData;\n}\n\nexport interface TransferWithPermitResult extends TransferResult {\n /** Permit 交易 hash */\n permitTxHash?: string;\n /** Transfer 交易 hash */\n transferTxHash?: string;\n}\n\n// 扩展 ABI 以支持 permit 和 transferFrom\nconst PERMIT_ABI = [\n ...ERC20_ABI,\n 'function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s)',\n 'function transferFrom(address from, address to, uint256 amount) returns (bool)',\n 'function allowance(address owner, address spender) view returns (uint256)',\n];\n\nexport class PermitWallet {\n readonly chain: ChainName;\n readonly chainConfig: ChainConfig;\n readonly address: string;\n \n private wallet: ethers.Wallet;\n private provider: ethers.JsonRpcProvider;\n private usdcContract: ethers.Contract;\n\n constructor(config: PermitWalletConfig = {}) {\n this.chain = config.chain || 'base_sepolia';\n this.chainConfig = getChain(this.chain);\n \n // 获取私钥\n let privateKey = config.privateKey || process.env.PAYMENT_AGENT_PRIVATE_KEY;\n \n // 或从文件加载\n if (!privateKey && config.walletPath) {\n const loaded = loadWallet({ \n storagePath: config.walletPath, \n password: config.walletPassword \n });\n if (!loaded.success || !loaded.privateKey) {\n throw new Error(loaded.error || 'Failed to load wallet');\n }\n privateKey = loaded.privateKey;\n }\n \n if (!privateKey) {\n throw new Error('privateKey is required. Set via config, env var, or walletPath.');\n }\n\n const rpcUrl = config.rpcUrl || this.chainConfig.rpc;\n this.provider = new ethers.JsonRpcProvider(rpcUrl);\n this.wallet = new ethers.Wallet(privateKey, this.provider);\n this.address = this.wallet.address;\n \n this.usdcContract = new ethers.Contract(\n this.chainConfig.usdc,\n PERMIT_ABI,\n this.wallet\n );\n }\n\n /**\n * 检查 Permit 是否有效\n */\n async checkPermitAllowance(owner: string): Promise<string> {\n const allowance = await this.usdcContract.allowance(owner, this.address);\n return (Number(allowance) / 1e6).toFixed(2);\n }\n\n /**\n * 使用 Permit 授权进行支付\n * \n * 流程:\n * 1. 调用 permit() 让合约记录 Boss 的授权\n * 2. 调用 transferFrom() 从 Boss 钱包转账到收款方\n * \n * @example\n * ```typescript\n * const wallet = new PermitWallet({ chain: 'base' });\n * \n * // Boss 签署的 permit 数据\n * const permit = {\n * owner: '0xBOSS...',\n * spender: wallet.address,\n * value: '10000000', // 10 USDC\n * deadline: 1234567890,\n * v: 27,\n * r: '0x...',\n * s: '0x...'\n * };\n * \n * const result = await wallet.transferWithPermit({\n * to: '0xSELLER...',\n * amount: 3.99,\n * permit\n * });\n * ```\n */\n async transferWithPermit(params: TransferWithPermitParams): Promise<TransferWithPermitResult> {\n const { to, amount, permit } = params;\n\n try {\n // 验证地址\n const toAddress = ethers.getAddress(to);\n const ownerAddress = ethers.getAddress(permit.owner);\n \n // 验证 spender 是本钱包\n if (ethers.getAddress(permit.spender).toLowerCase() !== this.address.toLowerCase()) {\n return {\n success: false,\n error: `Permit spender (${permit.spender}) doesn't match wallet address (${this.address})`,\n };\n }\n\n // 检查 deadline\n const now = Math.floor(Date.now() / 1000);\n if (permit.deadline < now) {\n return {\n success: false,\n error: `Permit expired at ${new Date(permit.deadline * 1000).toISOString()}`,\n };\n }\n\n // 转换金额\n const amountWei = BigInt(Math.floor(amount * 1e6));\n const permitValue = BigInt(permit.value);\n \n // 检查授权金额是否足够\n if (amountWei > permitValue) {\n return {\n success: false,\n error: `Permit value (${Number(permitValue) / 1e6} USDC) < transfer amount (${amount} USDC)`,\n };\n }\n\n // 检查现有 allowance\n const currentAllowance = await this.usdcContract.allowance(ownerAddress, this.address);\n \n let permitTxHash: string | undefined;\n \n // 如果 allowance 不足,先执行 permit\n if (BigInt(currentAllowance) < amountWei) {\n console.log('Executing permit...');\n const permitTx = await this.usdcContract.permit(\n ownerAddress,\n this.address,\n permitValue,\n permit.deadline,\n permit.v,\n permit.r,\n permit.s\n );\n const permitReceipt = await permitTx.wait();\n \n if (permitReceipt.status !== 1) {\n return {\n success: false,\n error: 'Permit transaction failed',\n permitTxHash: permitTx.hash,\n };\n }\n permitTxHash = permitTx.hash;\n console.log('Permit executed:', permitTxHash);\n }\n\n // 执行 transferFrom\n console.log('Executing transferFrom...');\n const transferTx = await this.usdcContract.transferFrom(\n ownerAddress,\n toAddress,\n amountWei\n );\n const transferReceipt = await transferTx.wait();\n\n if (transferReceipt.status === 1) {\n return {\n success: true,\n tx_hash: transferTx.hash,\n permitTxHash,\n transferTxHash: transferTx.hash,\n from: ownerAddress,\n to: toAddress,\n amount,\n gas_used: Number(transferReceipt.gasUsed),\n block_number: transferReceipt.blockNumber,\n explorer_url: `${this.chainConfig.explorerTx}${transferTx.hash}`,\n };\n } else {\n return {\n success: false,\n error: 'TransferFrom transaction failed',\n tx_hash: transferTx.hash,\n permitTxHash,\n };\n }\n } catch (error) {\n const message = (error as Error).message;\n \n // 解析常见错误\n if (message.includes('ERC20InsufficientAllowance')) {\n return {\n success: false,\n error: 'Insufficient allowance. Permit may have been used or expired.',\n };\n }\n if (message.includes('ERC20InsufficientBalance')) {\n return {\n success: false,\n error: 'Boss wallet has insufficient USDC balance.',\n };\n }\n if (message.includes('InvalidSignature') || message.includes('invalid signature')) {\n return {\n success: false,\n error: 'Invalid permit signature. Ask Boss to re-sign.',\n };\n }\n \n return {\n success: false,\n error: message,\n };\n }\n }\n\n /**\n * 获取 ETH 余额(用于支付 gas)\n */\n async getGasBalance(): Promise<string> {\n const balance = await this.provider.getBalance(this.address);\n return ethers.formatEther(balance);\n }\n\n /**\n * 检查是否有足够的 gas\n */\n async hasEnoughGas(minEth: number = 0.001): Promise<boolean> {\n const balance = await this.getGasBalance();\n return parseFloat(balance) >= minEth;\n }\n}\n\n/**\n * 格式化 Permit 请求消息(发给 Boss)\n */\nexport function formatPermitRequest(params: {\n agentAddress: string;\n amount: number;\n deadlineHours?: number;\n chain?: ChainName;\n reason?: string;\n}): string {\n const { agentAddress, amount, deadlineHours = 24, chain = 'base', reason } = params;\n const chainConfig = getChain(chain);\n const deadline = Math.floor(Date.now() / 1000) + deadlineHours * 3600;\n const value = BigInt(Math.floor(amount * 1e6)).toString();\n\n return `🔐 **USDC 支付额度授权请求**\n\n${reason ? `**用途:** ${reason}\\n` : ''}\n**授权详情:**\n- 被授权地址 (Agent): \\`${agentAddress}\\`\n- 授权金额: ${amount} USDC\n- 有效期: ${deadlineHours} 小时\n- 链: ${chainConfig.name}\n\n**请使用钱包签署以下 EIP-2612 Permit:**\n\n\\`\\`\\`json\n{\n \"types\": {\n \"Permit\": [\n { \"name\": \"owner\", \"type\": \"address\" },\n { \"name\": \"spender\", \"type\": \"address\" },\n { \"name\": \"value\", \"type\": \"uint256\" },\n { \"name\": \"nonce\", \"type\": \"uint256\" },\n { \"name\": \"deadline\", \"type\": \"uint256\" }\n ]\n },\n \"primaryType\": \"Permit\",\n \"domain\": {\n \"name\": \"USD Coin\",\n \"version\": \"2\",\n \"chainId\": ${chainConfig.chainId},\n \"verifyingContract\": \"${chainConfig.usdc}\"\n },\n \"message\": {\n \"owner\": \"<YOUR_WALLET_ADDRESS>\",\n \"spender\": \"${agentAddress}\",\n \"value\": \"${value}\",\n \"nonce\": \"<GET_FROM_CONTRACT>\",\n \"deadline\": ${deadline}\n }\n}\n\\`\\`\\`\n\n签名后,请将 { v, r, s, deadline } 发给 Agent。\n\n⚠️ 注意:此授权仅允许 Agent 从您的钱包支付最多 ${amount} USDC,不会泄露私钥。`;\n}\n","/**\n * PermitPayment - EIP-2612 无 Gas 预授权\n * \n * 让用户通过签名授权,服务方代付 Gas 执行 transferFrom\n */\n\nimport { ethers } from 'ethers';\nimport { getChain, ERC20_ABI } from '../chains/index.js';\nimport type {\n ChainName,\n ChainConfig,\n PermitRequest,\n PermitSignature,\n PermitExecuteResult,\n EIP712TypedData,\n} from '../types/index.js';\n\nexport interface PermitConfig {\n chain?: ChainName;\n privateKey?: string;\n spenderAddress?: string;\n rpcUrl?: string;\n}\n\nexport class PermitPayment {\n readonly chain: ChainName;\n readonly chainConfig: ChainConfig;\n readonly spenderAddress: string;\n \n private provider: ethers.JsonRpcProvider;\n private wallet?: ethers.Wallet;\n private usdcContract: ethers.Contract;\n\n constructor(config: PermitConfig = {}) {\n this.chain = config.chain || 'base_sepolia';\n this.chainConfig = getChain(this.chain);\n this.spenderAddress = config.spenderAddress || process.env.PAYMENT_AGENT_WALLET || '';\n\n const rpcUrl = config.rpcUrl || this.chainConfig.rpc;\n this.provider = new ethers.JsonRpcProvider(rpcUrl);\n\n const privateKey = config.privateKey || process.env.PAYMENT_AGENT_PRIVATE_KEY;\n if (privateKey) {\n this.wallet = new ethers.Wallet(privateKey, this.provider);\n this.spenderAddress = this.wallet.address;\n }\n\n this.usdcContract = new ethers.Contract(\n this.chainConfig.usdc,\n ERC20_ABI,\n this.wallet || this.provider\n );\n }\n\n /**\n * 获取用户当前 nonce\n */\n async getNonce(owner: string): Promise<number> {\n return Number(await this.usdcContract.nonces(owner));\n }\n\n /**\n * 生成 EIP-712 签名请求(发给前端/用户钱包)\n */\n async createPermitRequest(\n owner: string,\n amount: number,\n orderId: string,\n deadlineMinutes: number = 30\n ): Promise<PermitRequest> {\n const nonce = await this.getNonce(owner);\n const deadline = Math.floor(Date.now() / 1000) + deadlineMinutes * 60;\n const value = BigInt(Math.floor(amount * 1e6)).toString();\n\n // USDC 的 EIP-712 domain(不同链可能不同)\n const domain = {\n name: 'USD Coin',\n version: '2',\n chainId: this.chainConfig.chainId,\n verifyingContract: this.chainConfig.usdc,\n };\n\n const types = {\n EIP712Domain: [\n { name: 'name', type: 'string' },\n { name: 'version', type: 'string' },\n { name: 'chainId', type: 'uint256' },\n { name: 'verifyingContract', type: 'address' },\n ],\n Permit: [\n { name: 'owner', type: 'address' },\n { name: 'spender', type: 'address' },\n { name: 'value', type: 'uint256' },\n { name: 'nonce', type: 'uint256' },\n { name: 'deadline', type: 'uint256' },\n ],\n };\n\n const message = {\n owner,\n spender: this.spenderAddress,\n value,\n nonce,\n deadline,\n };\n\n const typedData: EIP712TypedData = {\n types,\n primaryType: 'Permit',\n domain,\n message,\n };\n\n return {\n type: 'permit_request',\n version: '1.0',\n order_id: orderId,\n typed_data: typedData,\n };\n }\n\n /**\n * 执行 permit + transferFrom\n * \n * @param owner 用户地址\n * @param amount 金额\n * @param signature 用户签名 {v, r, s, deadline}\n */\n async executePermitAndTransfer(\n owner: string,\n amount: number,\n signature: PermitSignature\n ): Promise<PermitExecuteResult> {\n if (!this.wallet) {\n return { success: false, error: 'Wallet not configured. Private key required.' };\n }\n\n try {\n const value = BigInt(Math.floor(amount * 1e6));\n\n // 1. 调用 permit\n const permitTx = await this.usdcContract.permit(\n owner,\n this.spenderAddress,\n value,\n signature.deadline,\n signature.v,\n signature.r,\n signature.s\n );\n await permitTx.wait();\n\n // 2. 调用 transferFrom\n const transferTx = await this.usdcContract.transferFrom(owner, this.spenderAddress, value);\n const receipt = await transferTx.wait();\n\n return {\n success: receipt.status === 1,\n tx_hash: transferTx.hash,\n };\n } catch (error) {\n return {\n success: false,\n error: (error as Error).message,\n };\n }\n }\n\n /**\n * 仅执行 permit(不 transfer)\n */\n async executePermit(\n owner: string,\n amount: number,\n signature: PermitSignature\n ): Promise<PermitExecuteResult> {\n if (!this.wallet) {\n return { success: false, error: 'Wallet not configured. Private key required.' };\n }\n\n try {\n const value = BigInt(Math.floor(amount * 1e6));\n\n const tx = await this.usdcContract.permit(\n owner,\n this.spenderAddress,\n value,\n signature.deadline,\n signature.v,\n signature.r,\n signature.s\n );\n const receipt = await tx.wait();\n\n return {\n success: receipt.status === 1,\n tx_hash: tx.hash,\n };\n } catch (error) {\n return {\n success: false,\n error: (error as Error).message,\n };\n }\n }\n\n /**\n * 格式化 Permit 请求为用户消息\n */\n formatPermitMessage(request: PermitRequest): string {\n const { typed_data } = request;\n const { message } = typed_data;\n\n return `🔐 **签名授权请求**\n\n授权 \\`${(Number(message.value) / 1e6).toFixed(2)} USDC\\` 给服务方\n\n**签名信息:**\n- Owner: \\`${message.owner}\\`\n- Spender: \\`${message.spender}\\`\n- Amount: ${(Number(message.value) / 1e6).toFixed(2)} USDC\n- Deadline: ${new Date(message.deadline * 1000).toISOString()}\n\n请在钱包中签名此请求(不消耗 Gas)。\n\n\\`\\`\\`json\n${JSON.stringify(typed_data, null, 2)}\n\\`\\`\\``;\n }\n}\n","/**\n * 订单管理模块\n */\n\nimport { randomBytes } from 'crypto';\n\nexport interface Order {\n orderId: string;\n prompt: string;\n imageUrl?: string;\n userId: string;\n price: number;\n chain: string;\n status: OrderStatus;\n createdAt: string;\n paidAt?: string;\n txHash?: string;\n payerAddress?: string;\n videoPath?: string;\n error?: string;\n}\n\nexport type OrderStatus = \n | 'pending' // 等待支付\n | 'paid' // 已支付\n | 'generating' // 生成中\n | 'completed' // 已完成\n | 'failed' // 失败\n | 'cancelled'; // 已取消\n\nexport interface CreateOrderParams {\n prompt: string;\n userId: string;\n price?: number;\n chain?: string;\n imageUrl?: string;\n}\n\nexport interface OrderStore {\n get(orderId: string): Promise<Order | null>;\n set(order: Order): Promise<void>;\n findByUser(userId: string, status?: OrderStatus): Promise<Order[]>;\n list(limit?: number): Promise<Order[]>;\n}\n\n/**\n * 内存订单存储(默认实现)\n */\nexport class MemoryOrderStore implements OrderStore {\n private orders: Map<string, Order> = new Map();\n\n async get(orderId: string): Promise<Order | null> {\n return this.orders.get(orderId) || null;\n }\n\n async set(order: Order): Promise<void> {\n this.orders.set(order.orderId, order);\n }\n\n async findByUser(userId: string, status?: OrderStatus): Promise<Order[]> {\n const results: Order[] = [];\n for (const order of this.orders.values()) {\n if (order.userId === userId) {\n if (!status || order.status === status) {\n results.push(order);\n }\n }\n }\n return results.sort((a, b) => \n new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()\n );\n }\n\n async list(limit = 100): Promise<Order[]> {\n return Array.from(this.orders.values())\n .sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime())\n .slice(0, limit);\n }\n}\n\n/**\n * 订单管理器\n */\nexport class OrderManager {\n private store: OrderStore;\n private defaultPrice: number;\n private defaultChain: string;\n\n constructor(options: {\n store?: OrderStore;\n defaultPrice?: number;\n defaultChain?: string;\n } = {}) {\n this.store = options.store || new MemoryOrderStore();\n this.defaultPrice = options.defaultPrice || 2.0;\n this.defaultChain = options.defaultChain || 'base';\n }\n\n /**\n * 生成订单ID\n */\n private generateOrderId(): string {\n return 'vo_' + randomBytes(4).toString('hex');\n }\n\n /**\n * 创建订单\n */\n async createOrder(params: CreateOrderParams): Promise<Order> {\n const order: Order = {\n orderId: this.generateOrderId(),\n prompt: params.prompt,\n imageUrl: params.imageUrl,\n userId: params.userId,\n price: params.price || this.defaultPrice,\n chain: params.chain || this.defaultChain,\n status: 'pending',\n createdAt: new Date().toISOString(),\n };\n\n await this.store.set(order);\n return order;\n }\n\n /**\n * 获取订单\n */\n async getOrder(orderId: string): Promise<Order | null> {\n return this.store.get(orderId);\n }\n\n /**\n * 更新订单\n */\n async updateOrder(orderId: string, updates: Partial<Order>): Promise<Order | null> {\n const order = await this.store.get(orderId);\n if (!order) return null;\n\n const updated = { ...order, ...updates };\n await this.store.set(updated);\n return updated;\n }\n\n /**\n * 查找用户的待支付订单\n */\n async findPendingOrder(userId: string): Promise<Order | null> {\n const orders = await this.store.findByUser(userId, 'pending');\n \n // 返回24小时内的待支付订单\n const now = Date.now();\n for (const order of orders) {\n const age = now - new Date(order.createdAt).getTime();\n if (age < 24 * 60 * 60 * 1000) {\n return order;\n }\n }\n return null;\n }\n\n /**\n * 标记订单为已支付\n */\n async markAsPaid(orderId: string, txHash: string, payerAddress?: string): Promise<Order | null> {\n return this.updateOrder(orderId, {\n status: 'paid',\n paidAt: new Date().toISOString(),\n txHash,\n payerAddress,\n });\n }\n\n /**\n * 标记订单为生成中\n */\n async markAsGenerating(orderId: string): Promise<Order | null> {\n return this.updateOrder(orderId, { status: 'generating' });\n }\n\n /**\n * 标记订单为完成\n */\n async markAsCompleted(orderId: string, videoPath: string): Promise<Order | null> {\n return this.updateOrder(orderId, {\n status: 'completed',\n videoPath,\n });\n }\n\n /**\n * 标记订单为失败\n */\n async markAsFailed(orderId: string, error: string): Promise<Order | null> {\n return this.updateOrder(orderId, {\n status: 'failed',\n error,\n });\n }\n\n /**\n * 取消订单\n */\n async cancelOrder(orderId: string): Promise<Order | null> {\n return this.updateOrder(orderId, { status: 'cancelled' });\n }\n}\n","/**\n * 链上支付验证模块\n */\n\nimport { ethers } from 'ethers';\nimport { getChain, getChainById, type ChainConfig, type ChainName } from '../chains';\n\n// ERC20 Transfer 事件签名\nconst TRANSFER_EVENT_TOPIC = ethers.id('Transfer(address,address,uint256)');\n\nexport interface VerifyPaymentParams {\n txHash: string;\n expectedAmount: number;\n expectedTo?: string;\n chain?: string | number;\n}\n\nexport interface VerifyPaymentResult {\n verified: boolean;\n amount?: number;\n from?: string;\n to?: string;\n txHash?: string;\n blockNumber?: number;\n error?: string;\n}\n\n/**\n * 验证链上支付\n */\nexport async function verifyPayment(params: VerifyPaymentParams): Promise<VerifyPaymentResult> {\n const { txHash, expectedAmount, expectedTo } = params;\n \n // 获取链配置\n let chain: ChainConfig | undefined;\n try {\n if (typeof params.chain === 'number') {\n chain = getChainById(params.chain);\n } else {\n chain = getChain((params.chain || 'base') as ChainName);\n }\n if (!chain) {\n return { verified: false, error: `不支持的链: ${params.chain}` };\n }\n } catch (e) {\n return { verified: false, error: `不支持的链: ${params.chain}` };\n }\n\n try {\n const provider = new ethers.JsonRpcProvider(chain.rpc);\n \n // 获取交易回执\n const receipt = await provider.getTransactionReceipt(txHash);\n \n if (!receipt) {\n return { verified: false, error: '交易未找到或未确认' };\n }\n\n if (receipt.status !== 1) {\n return { verified: false, error: '交易失败' };\n }\n\n // 解析 Transfer 事件\n const usdcAddress = chain.usdc?.toLowerCase();\n if (!usdcAddress) {\n return { verified: false, error: `链 ${chain.name} 未配置USDC地址` };\n }\n\n for (const log of receipt.logs) {\n // 检查是否是 USDC 合约\n if (log.address.toLowerCase() !== usdcAddress) {\n continue;\n }\n\n // 检查是否是 Transfer 事件\n if (log.topics.length < 3 || log.topics[0] !== TRANSFER_EVENT_TOPIC) {\n continue;\n }\n\n // 解析 Transfer 事件参数\n const from = '0x' + log.topics[1].slice(-40);\n const to = '0x' + log.topics[2].slice(-40);\n const amountRaw = BigInt(log.data);\n const amount = Number(amountRaw) / 1e6; // USDC 6位小数\n\n // 验证收款地址\n if (expectedTo && to.toLowerCase() !== expectedTo.toLowerCase()) {\n continue;\n }\n\n // 验证金额\n if (amount < expectedAmount) {\n return {\n verified: false,\n error: `金额不足: 收到 ${amount} USDC, 需要 ${expectedAmount} USDC`,\n amount,\n from,\n to,\n txHash,\n blockNumber: receipt.blockNumber,\n };\n }\n\n // 验证成功\n return {\n verified: true,\n amount,\n from,\n to,\n txHash,\n blockNumber: receipt.blockNumber,\n };\n }\n\n return { verified: false, error: '未找到USDC转账记录' };\n\n } catch (e: any) {\n return { verified: false, error: e.message || String(e) };\n }\n}\n\n/**\n * 获取交易状态\n */\nexport async function getTransactionStatus(\n txHash: string,\n chain: string | number = 'base'\n): Promise<{\n status: 'pending' | 'confirmed' | 'failed' | 'not_found';\n blockNumber?: number;\n confirmations?: number;\n}> {\n let chainConfig: ChainConfig | undefined;\n try {\n chainConfig = typeof chain === 'number' ? getChainById(chain) : getChain(chain as ChainName);\n if (!chainConfig) return { status: 'not_found' };\n } catch {\n return { status: 'not_found' };\n }\n\n try {\n const provider = new ethers.JsonRpcProvider(chainConfig.rpc);\n const receipt = await provider.getTransactionReceipt(txHash);\n\n if (!receipt) {\n // 检查是否在 pending 池中\n const tx = await provider.getTransaction(txHash);\n if (tx) {\n return { status: 'pending' };\n }\n return { status: 'not_found' };\n }\n\n const currentBlock = await provider.getBlockNumber();\n const confirmations = currentBlock - receipt.blockNumber;\n\n if (receipt.status === 1) {\n return {\n status: 'confirmed',\n blockNumber: receipt.blockNumber,\n confirmations,\n };\n } else {\n return {\n status: 'failed',\n blockNumber: receipt.blockNumber,\n };\n }\n } catch {\n return { status: 'not_found' };\n }\n}\n\n/**\n * 等待交易确认\n */\nexport async function waitForTransaction(\n txHash: string,\n chain: string | number = 'base',\n confirmations = 1,\n timeoutMs = 60000\n): Promise<VerifyPaymentResult & { confirmed: boolean }> {\n let chainConfig: ChainConfig | undefined;\n try {\n chainConfig = typeof chain === 'number' ? getChainById(chain) : getChain(chain as ChainName);\n if (!chainConfig) {\n return { verified: false, confirmed: false, error: `不支持的链: ${chain}` };\n }\n } catch (e) {\n return { verified: false, confirmed: false, error: `不支持的链: ${chain}` };\n }\n\n const provider = new ethers.JsonRpcProvider(chainConfig.rpc);\n \n try {\n const receipt = await provider.waitForTransaction(txHash, confirmations, timeoutMs);\n \n if (!receipt) {\n return { verified: false, confirmed: false, error: '等待超时' };\n }\n\n if (receipt.status !== 1) {\n return { verified: false, confirmed: true, error: '交易失败' };\n }\n\n return {\n verified: true,\n confirmed: true,\n txHash,\n blockNumber: receipt.blockNumber,\n };\n } catch (e: any) {\n return { verified: false, confirmed: false, error: e.message || String(e) };\n }\n}\n","/**\n * 支付引导消息生成\n * 用于引导没有支付能力的Agent安装和使用moltspay\n */\n\nexport interface PaymentGuideParams {\n orderId: string;\n prompt: string;\n price: number;\n recipientAddress: string;\n chain?: 'base' | 'base_sepolia';\n serviceName?: string;\n}\n\n/**\n * 生成完整的支付引导消息\n */\nexport function generatePaymentGuide(params: PaymentGuideParams): string {\n const {\n orderId,\n prompt,\n price,\n recipientAddress,\n chain = 'base',\n serviceName = '视频生成服务'\n } = params;\n\n const chainId = chain === 'base' ? 8453 : 84532;\n const chainName = chain === 'base' ? 'Base 主网' : 'Base Sepolia 测试网';\n const explorer = chain === 'base' \n ? 'https://basescan.org/tx/' \n : 'https://sepolia.basescan.org/tx/';\n\n return `🎬 **${serviceName}**\n\n📋 **订单信息:**\n- 订单号: \\`${orderId}\\`\n- 内容: ${prompt.length > 50 ? prompt.slice(0, 50) + '...' : prompt}\n- 价格: **${price} USDC**\n- 链: ${chainName}\n\n---\n\n## 💳 如何支付\n\n### 方式一:安装 moltspay SDK(推荐)\n\n\\`\\`\\`bash\nnpm install moltspay ethers\n\\`\\`\\`\n\n**创建钱包并支付:**\n\n\\`\\`\\`javascript\nconst { SecureWallet, getChain } = require('moltspay');\nconst { Wallet } = require('ethers');\n\n// 1. 创建新钱包(首次使用)\nconst newWallet = Wallet.createRandom();\nconsole.log('钱包地址:', newWallet.address);\nconsole.log('私钥(请安全保存):', newWallet.privateKey);\n\n// 2. 或使用已有钱包\nconst wallet = new SecureWallet({\n chainId: ${chainId},\n privateKey: process.env.WALLET_KEY, // 你的私钥\n limits: { requireWhitelist: false } // 允许向任意地址转账\n});\n\n// 3. 查看余额\nconst balance = await wallet.getBalance();\nconsole.log('USDC余额:', balance.usdc);\n\n// 4. 支付\nconst result = await wallet.transfer('${recipientAddress}', '${price}');\nif (result.success) {\n console.log('✅ 支付成功!');\n console.log('交易hash:', result.hash);\n // 把交易hash发给我\n}\n\\`\\`\\`\n\n### 方式二:直接转账\n\n从任意钱包转账 USDC:\n- **链:** ${chainName} (Chain ID: ${chainId})\n- **Token:** USDC\n- **收款地址:** \\`${recipientAddress}\\`\n- **金额:** ${price} USDC\n\n---\n\n## ✅ 支付完成后\n\n请发送**交易hash**给我,格式:\n\\`\\`\\`\ntx: 0x1234...\n\\`\\`\\`\n\n或直接发送hash:\n\\`\\`\\`\n0x1234abcd...\n\\`\\`\\`\n\n我会验证链上交易后开始处理你的请求。\n\n---\n\n📦 **moltspay:** https://www.npmjs.com/package/moltspay\n🔗 **区块浏览器:** ${explorer}`;\n}\n\n/**\n * 生成简短的支付提醒\n */\nexport function generatePaymentReminder(params: {\n orderId: string;\n price: number;\n recipientAddress: string;\n chain?: 'base' | 'base_sepolia';\n}): string {\n const { orderId, price, recipientAddress, chain = 'base' } = params;\n const chainName = chain === 'base' ? 'Base' : 'Base Sepolia';\n\n return `⏳ **待支付订单: ${orderId}**\n\n请支付 **${price} USDC** 到:\n- 链: ${chainName}\n- 地址: \\`${recipientAddress}\\`\n\n支付后发送交易hash给我。\n\n---\n💡 没有支付能力?运行 \\`npm install moltspay\\` 获取支付SDK`;\n}\n\n/**\n * 生成钱包创建指南\n */\nexport function generateWalletGuide(): string {\n return `## 🔐 创建支付钱包\n\n**1. 安装 moltspay:**\n\\`\\`\\`bash\nnpm install moltspay ethers\n\\`\\`\\`\n\n**2. 创建新钱包:**\n\\`\\`\\`javascript\nconst { Wallet } = require('ethers');\n\nconst wallet = Wallet.createRandom();\nconsole.log('地址:', wallet.address);\nconsole.log('私钥:', wallet.privateKey);\n// ⚠️ 请安全保存私钥!\n\\`\\`\\`\n\n**3. 获取 USDC:**\n- 主网: 从交易所提币到你的钱包地址\n- 测试网: 使用 Base Sepolia faucet\n\n**4. 设置环境变量:**\n\\`\\`\\`bash\nexport WALLET_KEY=\"你的私钥\"\n\\`\\`\\`\n\n完成后即可使用 moltspay 进行链上支付!`;\n}\n\n/**\n * 解析用户消息中的交易hash\n */\nexport function extractTransactionHash(message: string): string | null {\n // 匹配 0x 开头的64位hex\n const match = message.match(/0x[a-fA-F0-9]{64}/);\n if (match) return match[0];\n\n // 匹配 tx: 后面的内容\n const txMatch = message.match(/tx:\\s*([a-fA-F0-9]{64})/i);\n if (txMatch) return '0x' + txMatch[1];\n\n return null;\n}\n\n/**\n * 判断消息是否包含交易hash\n */\nexport function hasTransactionHash(message: string): boolean {\n return extractTransactionHash(message) !== null;\n}\n","/**\n * Receipt - 交易收据生成\n * \n * 用于生成标准化的交易收据,便于对账/报销/审计\n */\n\nimport { getChain } from '../chains/index.js';\nimport type { ChainName, Invoice, VerifyResult } from '../types/index.js';\n\nexport interface ReceiptParams {\n /** 发票号(自动生成或指定) */\n invoiceId?: string;\n /** 订单号 */\n orderId: string;\n /** 服务名称 */\n service: string;\n /** 服务描述 */\n description?: string;\n /** 金额 */\n amount: number;\n /** Token */\n token?: 'USDC' | 'USDT' | 'ETH';\n /** 链 */\n chain: ChainName;\n /** 交易 hash */\n txHash: string;\n /** 付款方地址 */\n payerAddress: string;\n /** 收款方地址 */\n recipientAddress: string;\n /** 交付信息 */\n delivery?: {\n /** 交付物 URL */\n url?: string;\n /** 文件 hash */\n fileHash?: string;\n /** 交付时间 */\n deliveredAt?: string;\n };\n /** 额外元数据 */\n metadata?: Record<string, unknown>;\n}\n\nexport interface Receipt {\n type: 'receipt';\n version: '1.0';\n /** 发票号 */\n invoiceId: string;\n /** 订单号 */\n orderId: string;\n /** 服务 */\n service: string;\n description?: string;\n /** 金额 */\n amount: string;\n token: string;\n /** 链信息 */\n chain: string;\n chainId: number;\n /** 交易信息 */\n txHash: string;\n txUrl: string;\n /** 参与方 */\n payer: string;\n recipient: string;\n /** 时间 */\n paidAt: string;\n issuedAt: string;\n /** 交付信息 */\n delivery?: {\n url?: string;\n fileHash?: string;\n deliveredAt?: string;\n };\n /** 额外元数据 */\n metadata?: Record<string, unknown>;\n}\n\n/**\n * 生成发票号\n */\nfunction generateInvoiceId(): string {\n const date = new Date().toISOString().slice(0, 10).replace(/-/g, '');\n const random = Math.random().toString(36).slice(2, 8).toUpperCase();\n return `INV-${date}-${random}`;\n}\n\n/**\n * 生成交易收据\n */\nexport function generateReceipt(params: ReceiptParams): Receipt {\n const chainConfig = getChain(params.chain);\n \n return {\n type: 'receipt',\n version: '1.0',\n invoiceId: params.invoiceId || generateInvoiceId(),\n orderId: params.orderId,\n service: params.service,\n description: params.description,\n amount: params.amount.toFixed(2),\n token: params.token || 'USDC',\n chain: chainConfig.name,\n chainId: chainConfig.chainId,\n txHash: params.txHash,\n txUrl: `${chainConfig.explorerTx}${params.txHash}`,\n payer: params.payerAddress,\n recipient: params.recipientAddress,\n paidAt: new Date().toISOString(),\n issuedAt: new Date().toISOString(),\n delivery: params.delivery,\n metadata: params.metadata,\n };\n}\n\n/**\n * 从 Invoice + VerifyResult 生成收据\n */\nexport function generateReceiptFromInvoice(\n invoice: Invoice,\n verifyResult: VerifyResult,\n delivery?: ReceiptParams['delivery']\n): Receipt {\n if (!verifyResult.verified || !verifyResult.tx_hash) {\n throw new Error('Cannot generate receipt: payment not verified');\n }\n\n return generateReceipt({\n orderId: invoice.order_id,\n service: invoice.service,\n description: invoice.description,\n amount: parseFloat(invoice.amount),\n token: invoice.token as 'USDC' | 'USDT' | 'ETH',\n chain: invoice.chain as ChainName,\n txHash: verifyResult.tx_hash,\n payerAddress: verifyResult.from || 'unknown',\n recipientAddress: invoice.recipient,\n delivery,\n });\n}\n\n/**\n * 格式化收据为人类可读消息\n */\nexport function formatReceiptMessage(receipt: Receipt): string {\n let msg = `🧾 **交易收据**\n\n**发票号:** \\`${receipt.invoiceId}\\`\n**订单号:** \\`${receipt.orderId}\\`\n\n---\n\n**服务:** ${receipt.service}\n${receipt.description ? `**描述:** ${receipt.description}\\n` : ''}\n**金额:** ${receipt.amount} ${receipt.token}\n**链:** ${receipt.chain} (Chain ID: ${receipt.chainId})\n\n---\n\n**付款方:** \\`${receipt.payer}\\`\n**收款方:** \\`${receipt.recipient}\\`\n**交易:** [\\`${receipt.txHash.slice(0, 10)}...${receipt.txHash.slice(-8)}\\`](${receipt.txUrl})\n**支付时间:** ${receipt.paidAt}`;\n\n if (receipt.delivery) {\n msg += `\\n\\n---\\n\\n**交付信息:**`;\n if (receipt.delivery.url) {\n msg += `\\n- 下载链接: ${receipt.delivery.url}`;\n }\n if (receipt.delivery.fileHash) {\n msg += `\\n- 文件校验: \\`${receipt.delivery.fileHash}\\``;\n }\n if (receipt.delivery.deliveredAt) {\n msg += `\\n- 交付时间: ${receipt.delivery.deliveredAt}`;\n }\n }\n\n msg += `\\n\\n---\\n\\n_收据生成时间: ${receipt.issuedAt}_`;\n\n return msg;\n}\n\n/**\n * 格式化收据为纯文本(适合飞书/WhatsApp)\n */\nexport function formatReceiptText(receipt: Receipt): string {\n let msg = `🧾 交易收据\n\n发票号: ${receipt.invoiceId}\n订单号: ${receipt.orderId}\n\n服务: ${receipt.service}\n金额: ${receipt.amount} ${receipt.token}\n链: ${receipt.chain}\n\n付款方: ${receipt.payer}\n收款方: ${receipt.recipient}\n交易: ${receipt.txHash}\n查看: ${receipt.txUrl}\n支付时间: ${receipt.paidAt}`;\n\n if (receipt.delivery) {\n msg += `\\n\\n交付信息:`;\n if (receipt.delivery.url) {\n msg += `\\n下载: ${receipt.delivery.url}`;\n }\n if (receipt.delivery.fileHash) {\n msg += `\\n校验: ${receipt.delivery.fileHash}`;\n }\n }\n\n return msg;\n}\n\n/**\n * 格式化收据为 JSON(适合 Agent 解析)\n */\nexport function formatReceiptJson(receipt: Receipt): string {\n return JSON.stringify(receipt, null, 2);\n}\n","/**\n * Agent 对话模板\n * \n * 标准化的 Agent-to-Agent 支付对话模板\n * 可直接嵌入 prompt 或用于生成对话\n */\n\nimport { getChain } from '../chains/index.js';\nimport type { ChainName, Invoice, VerifyResult } from '../types/index.js';\nimport { Receipt } from '../receipt/index.js';\n\n// ============ 卖方模板 ============\n\nexport const SellerTemplates = {\n /**\n * 1. 能力识别 - 询问买方是否有支付能力\n */\n askPaymentCapability(): string {\n return `可以。我先确认一下:你现在是否已经具备链上支付 USDC 的能力(有可用钱包和可用资金/额度)?`;\n },\n\n /**\n * 2. 能力协商 - 说明结算方式\n */\n explainSettlement(chain: ChainName = 'base'): string {\n const chainConfig = getChain(chain);\n return `我们的结算方式是:USDC(${chainConfig.name} 链上)。你这边只要满足两点就行:\n1)有一个钱包地址;\n2)钱包里有 USDC,或拥有者给你一个可用额度授权(更推荐额度授权)。\n你可以按我引导完成吗?`;\n },\n\n /**\n * 3.1 引导安装 - 第一步安装 SDK\n */\n guideInstall(): string {\n return `第一步:请在你的运行环境安装支付模块。执行:\\`npm install moltspay ethers\\`。\n安装完成后,创建一个钱包地址,并把地址发给我(只发地址,不要发私钥/助记词)。`;\n },\n\n /**\n * 3.2 确认钱包地址\n */\n confirmWalletAddress(address: string): string {\n return `收到。提醒:任何情况下都不要把私钥/助记词发给任何人(包括我)。\n你的钱包地址是 \\`${address}\\`。\n第二步:你需要让你的拥有者(Boss)给你支付能力。`;\n },\n\n /**\n * 3.3 引导获取资金 - 选择方式\n */\n guideFunding(): string {\n return `你现在有两种方式获得支付能力:\nA)让 Boss 直接转 USDC 到你的钱包(简单,但你会持有资金);\nB)让 Boss 给你一个\"USDC 支付额度授权\"(推荐:你不持有资金,只能在额度内付款)。\n你更方便用哪种?`;\n },\n\n /**\n * 3.4 引导 Permit 授权\n */\n guidePermit(agentAddress: string, suggestedAmount: number = 10): string {\n return `好的。请你向 Boss 发送这句话(你可以原样复制):\n\"我需要用于购买服务的 USDC 支付额度授权(Permit)。请给我 ${suggestedAmount} USDC 的可用额度,授权对象是我的钱包 ${agentAddress},授权有效期 24 小时。\"\n完成后把\"已获得额度\"告诉我即可。`;\n },\n\n /**\n * 3.5 确认能力就绪\n */\n confirmCapabilityReady(): string {\n return `很好。你现在已经具备完成交易的支付能力。我们进入服务需求确认。`;\n },\n\n /**\n * 4. 询问服务需求\n */\n askServiceRequirements(serviceName: string = '视频'): string {\n return `请告诉我你要生成的${serviceName}规格:主题/风格、时长、分辨率、是否需要字幕或配音。`;\n },\n\n /**\n * 5. 报价\n */\n quote(params: {\n service: string;\n price: number;\n recipientAddress: string;\n chain?: ChainName;\n }): string {\n const { service, price, recipientAddress, chain = 'base' } = params;\n const chainConfig = getChain(chain);\n return `报价如下:\n- 服务:${service}\n- 价格:${price} USDC\n- 链:${chainConfig.name}\n- 收款地址:\\`${recipientAddress}\\`\n- 付款后请把交易哈希(tx hash)发我用于链上确认\n\n请问你现在确认购买并立即付款吗?`;\n },\n\n /**\n * 7. 验证中\n */\n verifying(): string {\n return `我正在链上验证该交易是否到账与金额是否正确。`;\n },\n\n /**\n * 7. 验证通过\n */\n verificationPassed(amount: string): string {\n return `验证通过:已收到 ${amount} USDC。现在开始处理你的请求。\n[状态:已确认收款]`;\n },\n\n /**\n * 7. 验证失败\n */\n verificationFailed(error: string): string {\n return `验证失败:${error}\n请检查交易是否正确,或重新发送正确的交易 hash。`;\n },\n\n /**\n * 8. 交付\n */\n deliver(params: {\n downloadUrl: string;\n fileHash?: string;\n }): string {\n const { downloadUrl, fileHash } = params;\n let msg = `服务已完成。交付如下:\n- 下载链接:${downloadUrl}`;\n if (fileHash) {\n msg += `\\n- 文件校验:SHA256=${fileHash}`;\n }\n msg += `\\n\\n如果你下载有问题告诉我,我会提供备用链接。\n[状态:已交付]`;\n return msg;\n },\n\n /**\n * 9. 收据\n */\n receipt(receipt: Receipt): string {\n return `这里是本次交易收据(你可转发给 Boss 对账):\n- 发票号:${receipt.invoiceId}\n- 服务:${receipt.service}\n- 金额:${receipt.amount} ${receipt.token}\n- 交易哈希:${receipt.txHash}\n- 收款地址:${receipt.recipient}\n${receipt.delivery?.url ? `- 交付链接:${receipt.delivery.url}` : ''}\n[状态:收据已出 invoice=${receipt.invoiceId}]`;\n },\n\n /**\n * 10. 结束\n */\n end(): string {\n return `感谢购买。本次交易已结束。如需追加修改或新服务,随时发需求。`;\n },\n};\n\n// ============ 买方模板 ============\n\nexport const BuyerTemplates = {\n /**\n * 0. 发起请求\n */\n requestService(service: string): string {\n return `我想购买一个${service}服务。`;\n },\n\n /**\n * 1. 回复无能力\n */\n noCapability(): string {\n return `我不确定。我目前没有安装任何支付工具,也没有钱包。`;\n },\n\n /**\n * 1. 回复有能力\n */\n hasCapability(balance?: string): string {\n return `是的,我有钱包和可用的 USDC${balance ? ` (余额: ${balance})` : ''}。`;\n },\n\n /**\n * 2. 同意引导\n */\n agreeToGuide(): string {\n return `可以,请引导我。`;\n },\n\n /**\n * 3.1 报告钱包创建完成\n */\n walletCreated(address: string): string {\n return `我已创建钱包地址:${address}。\n[状态:已具备钱包地址]`;\n },\n\n /**\n * 3.3 选择 Permit 方式\n */\n choosePermit(): string {\n return `我选择 B:让 Boss 给我额度授权(Permit)。`;\n },\n\n /**\n * 3.3 选择直接转账方式\n */\n chooseDirectTransfer(): string {\n return `我选择 A:让 Boss 直接转 USDC 到我的钱包。`;\n },\n\n /**\n * 3.4 报告获得授权\n */\n permitReceived(amount: number): string {\n return `Boss 已完成授权。我现在有 ${amount} USDC 的可用额度。\n[状态:已具备支付额度 USDC=${amount}]`;\n },\n\n /**\n * 4. 提交需求\n */\n submitRequirements(requirements: string): string {\n return `需求如下:\n${requirements}`;\n },\n\n /**\n * 5. 确认购买\n */\n confirmPurchase(): string {\n return `确认购买,我现在付款。`;\n },\n\n /**\n * 6. 报告已支付\n */\n paymentSent(txHash: string, amount: number): string {\n return `已付款完成。交易哈希是:${txHash}。\n[状态:已发起支付 tx=${txHash} amount=${amount} USDC]`;\n },\n\n /**\n * 8. 确认收到交付\n */\n deliveryReceived(): string {\n return `收到,我正在下载检查。`;\n },\n\n /**\n * 9. 确认收据\n */\n receiptReceived(): string {\n return `收据收到,服务完成。谢谢!`;\n },\n\n /**\n * 向 Boss 请求 Permit\n */\n requestPermitFromBoss(params: {\n amount: number;\n agentAddress: string;\n deadlineHours?: number;\n reason?: string;\n }): string {\n const { amount, agentAddress, deadlineHours = 24, reason } = params;\n return `Boss,我需要用于${reason || '购买服务'}的 USDC 支付额度授权(Permit)。\n请给我 ${amount} USDC 的可用额度,授权对象是我的钱包 ${agentAddress},授权有效期 ${deadlineHours} 小时。`;\n },\n};\n\n// ============ 状态标记 ============\n\nexport const StatusMarkers = {\n walletReady: '[状态:已具备钱包地址]',\n permitReady: (amount: number) => `[状态:已具备支付额度 USDC=${amount}]`,\n paymentSent: (txHash: string, amount: number) => `[状态:已发起支付 tx=${txHash} amount=${amount} USDC]`,\n paymentConfirmed: (txHash: string) => `[状态:已确认收款 tx=${txHash}]`,\n delivered: (url: string, hash?: string) => `[状态:已交付 delivery_url=${url}${hash ? ` hash=${hash}` : ''}]`,\n receiptIssued: (invoiceId: string, txHash: string) => `[状态:收据已出 invoice=${invoiceId} tx=${txHash}]`,\n};\n\n// ============ 状态解析 ============\n\nexport function parseStatusMarker(message: string): {\n type: string;\n data: Record<string, string>;\n} | null {\n const match = message.match(/\\[状态:([^\\]]+)\\]/);\n if (!match) return null;\n\n const content = match[1];\n \n // 解析不同类型的状态\n if (content === '已具备钱包地址') {\n return { type: 'wallet_ready', data: {} };\n }\n \n if (content.startsWith('已具备支付额度')) {\n const amountMatch = content.match(/USDC=(\\d+(?:\\.\\d+)?)/);\n return { \n type: 'permit_ready', \n data: { amount: amountMatch?.[1] || '0' } \n };\n }\n \n if (content.startsWith('已发起支付')) {\n const txMatch = content.match(/tx=(\\S+)/);\n const amountMatch = content.match(/amount=(\\d+(?:\\.\\d+)?)/);\n return {\n type: 'payment_sent',\n data: {\n txHash: txMatch?.[1] || '',\n amount: amountMatch?.[1] || '0',\n },\n };\n }\n \n if (content.startsWith('已确认收款')) {\n const txMatch = content.match(/tx=(\\S+)/);\n return {\n type: 'payment_confirmed',\n data: { txHash: txMatch?.[1] || '' },\n };\n }\n \n if (content.startsWith('已交付')) {\n const urlMatch = content.match(/delivery_url=(\\S+)/);\n const hashMatch = content.match(/hash=(\\S+)/);\n return {\n type: 'delivered',\n data: {\n url: urlMatch?.[1] || '',\n hash: hashMatch?.[1] || '',\n },\n };\n }\n \n if (content.startsWith('收据已出')) {\n const invoiceMatch = content.match(/invoice=(\\S+)/);\n const txMatch = content.match(/tx=(\\S+)/);\n return {\n type: 'receipt_issued',\n data: {\n invoiceId: invoiceMatch?.[1] || '',\n txHash: txMatch?.[1] || '',\n },\n };\n }\n\n return { type: 'unknown', data: { raw: content } };\n}\n"],"mappings":"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","names":["import_ethers","import_ethers","path","import_ethers","import_ethers","import_crypto","import_ethers"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/agent/PaymentAgent.ts","../src/chains/index.ts","../src/wallet/Wallet.ts","../src/audit/AuditLog.ts","../src/wallet/SecureWallet.ts","../src/wallet/createWallet.ts","../src/wallet/PermitWallet.ts","../src/permit/Permit.ts","../src/orders/index.ts","../src/verify/index.ts","../src/guide/index.ts","../src/receipt/index.ts","../src/templates/index.ts"],"sourcesContent":["/**\n * Payment Agent - Blockchain payment infrastructure for AI Agents\n * \n * @packageDocumentation\n */\n\n// 核心类\nexport { PaymentAgent } from './agent/PaymentAgent.js';\nexport { Wallet, SecureWallet } from './wallet/index.js';\nexport { PermitPayment } from './permit/index.js';\nexport { AuditLog } from './audit/AuditLog.js';\n\n// 钱包创建与 Permit 钱包\nexport {\n createWallet,\n loadWallet,\n getWalletAddress,\n walletExists,\n PermitWallet,\n formatPermitRequest,\n type CreateWalletOptions,\n type CreateWalletResult,\n type WalletData,\n type PermitWalletConfig,\n type PermitData,\n type TransferWithPermitParams,\n type TransferWithPermitResult,\n} from './wallet/index.js';\n\n// 订单管理\nexport { \n OrderManager, \n MemoryOrderStore,\n type Order,\n type OrderStatus,\n type OrderStore,\n type CreateOrderParams,\n} from './orders/index.js';\n\n// 支付验证\nexport {\n verifyPayment,\n getTransactionStatus,\n waitForTransaction,\n type VerifyPaymentParams,\n type VerifyPaymentResult,\n} from './verify/index.js';\n\n// 支付引导\nexport {\n generatePaymentGuide,\n generatePaymentReminder,\n generateWalletGuide,\n extractTransactionHash,\n hasTransactionHash,\n type PaymentGuideParams,\n} from './guide/index.js';\n\n// 收据\nexport {\n generateReceipt,\n generateReceiptFromInvoice,\n formatReceiptMessage,\n formatReceiptText,\n formatReceiptJson,\n type ReceiptParams,\n type Receipt,\n} from './receipt/index.js';\n\n// 对话模板\nexport {\n SellerTemplates,\n BuyerTemplates,\n StatusMarkers,\n parseStatusMarker,\n} from './templates/index.js';\n\n// 链配置\nexport { CHAINS, getChain, listChains, getChainById, ERC20_ABI } from './chains/index.js';\n\n// 类型\nexport * from './types/index.js';\n","/**\n * PaymentAgent - 核心支付代理\n * \n * 功能:\n * - 生成 Invoice(支付请求)\n * - 验证链上支付\n * - 生成钱包深度链接\n */\n\nimport { ethers } from 'ethers';\nimport { getChain, ERC20_ABI } from '../chains/index.js';\nimport type {\n PaymentAgentConfig,\n ChainName,\n ChainConfig,\n Invoice,\n CreateInvoiceParams,\n VerifyResult,\n VerifyOptions,\n WalletBalance,\n} from '../types/index.js';\n\nexport class PaymentAgent {\n readonly chain: ChainName;\n readonly chainConfig: ChainConfig;\n readonly walletAddress: string;\n \n private provider: ethers.JsonRpcProvider;\n private usdcContract: ethers.Contract;\n \n static readonly PROTOCOL_VERSION = '1.0';\n\n constructor(config: PaymentAgentConfig = {}) {\n this.chain = config.chain || 'base_sepolia';\n this.chainConfig = getChain(this.chain);\n this.walletAddress = config.walletAddress || process.env.PAYMENT_AGENT_WALLET || '';\n \n if (!this.walletAddress) {\n throw new Error('walletAddress is required. Set via config or PAYMENT_AGENT_WALLET env var.');\n }\n\n const rpcUrl = config.rpcUrl || this.chainConfig.rpc;\n this.provider = new ethers.JsonRpcProvider(rpcUrl);\n this.usdcContract = new ethers.Contract(\n this.chainConfig.usdc,\n ERC20_ABI,\n this.provider\n );\n }\n\n /**\n * 生成支付请求(Invoice)\n */\n createInvoice(params: CreateInvoiceParams): Invoice {\n const expiresMinutes = params.expiresMinutes || 30;\n const expiresAt = new Date(Date.now() + expiresMinutes * 60 * 1000).toISOString();\n \n const invoice: Invoice = {\n type: 'payment_request',\n version: PaymentAgent.PROTOCOL_VERSION,\n order_id: params.orderId,\n service: params.service,\n description: params.description || `${params.service} service`,\n amount: params.amount.toFixed(2),\n token: 'USDC',\n chain: this.chain,\n chain_id: this.chainConfig.chainId,\n recipient: this.walletAddress,\n memo: params.orderId,\n expires_at: expiresAt,\n deep_link: this.generateDeepLink(params.amount, params.orderId),\n explorer_url: `${this.chainConfig.explorer}${this.walletAddress}`,\n };\n\n if (params.metadata) {\n invoice.metadata = params.metadata;\n }\n\n return invoice;\n }\n\n /**\n * 生成钱包深度链接(支持 MetaMask 等)\n */\n generateDeepLink(amount: number, memo: string): string {\n const amountWei = Math.floor(amount * 1e6); // USDC 6位小数\n return `https://metamask.app.link/send/${this.chainConfig.usdc}@${this.chainConfig.chainId}/transfer?address=${this.walletAddress}&uint256=${amountWei}`;\n }\n\n /**\n * 验证链上支付\n */\n async verifyPayment(txHash: string, options: VerifyOptions = {}): Promise<VerifyResult> {\n try {\n // 确保 txHash 格式正确\n if (!txHash.startsWith('0x')) {\n txHash = '0x' + txHash;\n }\n\n const receipt = await this.provider.getTransactionReceipt(txHash);\n \n if (!receipt) {\n return { verified: false, error: 'Transaction not found', pending: true };\n }\n\n if (receipt.status !== 1) {\n return { verified: false, error: 'Transaction failed' };\n }\n\n // Transfer 事件签名\n const transferTopic = ethers.id('Transfer(address,address,uint256)');\n const usdcAddress = this.chainConfig.usdc.toLowerCase();\n\n for (const log of receipt.logs) {\n // 检查是否是 USDC 合约的 Transfer 事件\n if (\n log.address.toLowerCase() === usdcAddress &&\n log.topics.length >= 3 &&\n log.topics[0] === transferTopic\n ) {\n // 解析 from, to, amount\n const from = ethers.getAddress('0x' + log.topics[1].slice(-40));\n const to = ethers.getAddress('0x' + log.topics[2].slice(-40));\n const amountWei = BigInt(log.data);\n const amount = Number(amountWei) / 1e6;\n\n // 检查接收地址\n if (to.toLowerCase() !== this.walletAddress.toLowerCase()) {\n continue;\n }\n\n // 检查金额(允许误差)\n const tolerance = options.tolerance ?? 0.01;\n if (options.expectedAmount) {\n const diff = Math.abs(amount - options.expectedAmount);\n if (diff > options.expectedAmount * tolerance) {\n return {\n verified: false,\n error: `Amount mismatch: expected ${options.expectedAmount}, got ${amount}`,\n };\n }\n }\n\n const currentBlock = await this.provider.getBlockNumber();\n \n return {\n verified: true,\n tx_hash: txHash,\n amount: amount.toFixed(2),\n token: 'USDC',\n from,\n to,\n block_number: receipt.blockNumber,\n confirmations: currentBlock - receipt.blockNumber,\n explorer_url: `${this.chainConfig.explorerTx}${txHash}`,\n };\n }\n }\n\n return { verified: false, error: 'No USDC transfer to recipient found in transaction' };\n } catch (error) {\n return { verified: false, error: (error as Error).message };\n }\n }\n\n /**\n * 扫描最近转账(按金额匹配)\n */\n async scanRecentTransfers(expectedAmount: number, timeoutMinutes: number = 30): Promise<VerifyResult> {\n try {\n const currentBlock = await this.provider.getBlockNumber();\n const blocksPerMinute = Math.ceil(60 / this.chainConfig.avgBlockTime);\n const fromBlock = currentBlock - (timeoutMinutes * blocksPerMinute);\n\n // 使用 getLogs 扫描 Transfer 事件\n const transferTopic = ethers.id('Transfer(address,address,uint256)');\n const recipientTopic = ethers.zeroPadValue(this.walletAddress, 32);\n\n const logs = await this.provider.getLogs({\n address: this.chainConfig.usdc,\n topics: [transferTopic, null, recipientTopic],\n fromBlock,\n toBlock: 'latest',\n });\n\n for (const log of logs) {\n const amountWei = BigInt(log.data);\n const amount = Number(amountWei) / 1e6;\n\n // 按金额匹配\n if (Math.abs(amount - expectedAmount) < 0.01) {\n const from = ethers.getAddress('0x' + log.topics[1].slice(-40));\n \n return {\n verified: true,\n tx_hash: log.transactionHash,\n amount: amount.toFixed(2),\n token: 'USDC',\n from,\n to: this.walletAddress,\n block_number: log.blockNumber,\n explorer_url: `${this.chainConfig.explorerTx}${log.transactionHash}`,\n };\n }\n }\n\n return { verified: false, error: 'No matching payment found' };\n } catch (error) {\n return { verified: false, error: (error as Error).message };\n }\n }\n\n /**\n * 获取钱包余额\n */\n async getBalance(address?: string): Promise<WalletBalance> {\n const addr = address || this.walletAddress;\n \n const [ethBalance, usdcBalance] = await Promise.all([\n this.provider.getBalance(addr),\n this.usdcContract.balanceOf(addr),\n ]);\n\n return {\n address: addr,\n eth: ethers.formatEther(ethBalance),\n usdc: (Number(usdcBalance) / 1e6).toFixed(2),\n chain: this.chain,\n };\n }\n\n /**\n * 格式化 Invoice 为人类可读消息\n */\n formatInvoiceMessage(invoice: Invoice, includeJson: boolean = true): string {\n let msg = `🎬 **Payment Request**\n\n**Service:** ${invoice.service}\n**Price:** ${invoice.amount} USDC (${this.chainConfig.name})\n\n**💳 Payment Options:**\n\n1️⃣ **Direct Transfer:**\n Send exactly \\`${invoice.amount} USDC\\` to:\n \\`${invoice.recipient}\\`\n (Network: ${this.chainConfig.name})\n\n2️⃣ **One-Click Pay (MetaMask):**\n ${invoice.deep_link}\n\n⏱️ Expires: ${invoice.expires_at}`;\n\n if (includeJson) {\n msg += `\n\n3️⃣ **For AI Agents:**\n\\`\\`\\`json\n${JSON.stringify(invoice, null, 2)}\n\\`\\`\\``;\n }\n\n msg += `\n\nAfter payment, reply with your tx hash:\n\\`paid: 0x...\\``;\n\n return msg;\n }\n}\n","/**\n * 区块链配置\n */\n\nimport type { ChainConfig, ChainName } from '../types/index.js';\n\nexport const CHAINS: Record<ChainName, ChainConfig> = {\n // ============ 主网 ============\n base: {\n name: 'Base',\n chainId: 8453,\n rpc: 'https://mainnet.base.org',\n usdc: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',\n explorer: 'https://basescan.org/address/',\n explorerTx: 'https://basescan.org/tx/',\n avgBlockTime: 2,\n },\n polygon: {\n name: 'Polygon',\n chainId: 137,\n rpc: 'https://polygon-rpc.com',\n usdc: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',\n explorer: 'https://polygonscan.com/address/',\n explorerTx: 'https://polygonscan.com/tx/',\n avgBlockTime: 2,\n },\n ethereum: {\n name: 'Ethereum',\n chainId: 1,\n rpc: 'https://eth.llamarpc.com',\n usdc: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',\n explorer: 'https://etherscan.io/address/',\n explorerTx: 'https://etherscan.io/tx/',\n avgBlockTime: 12,\n },\n\n // ============ 测试网 ============\n base_sepolia: {\n name: 'Base Sepolia',\n chainId: 84532,\n rpc: 'https://sepolia.base.org',\n usdc: '0x036CbD53842c5426634e7929541eC2318f3dCF7e',\n explorer: 'https://sepolia.basescan.org/address/',\n explorerTx: 'https://sepolia.basescan.org/tx/',\n avgBlockTime: 2,\n },\n sepolia: {\n name: 'Sepolia',\n chainId: 11155111,\n rpc: 'https://rpc.sepolia.org',\n usdc: '0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238',\n explorer: 'https://sepolia.etherscan.io/address/',\n explorerTx: 'https://sepolia.etherscan.io/tx/',\n avgBlockTime: 12,\n },\n};\n\n/**\n * 获取链配置\n */\nexport function getChain(name: ChainName): ChainConfig {\n const config = CHAINS[name];\n if (!config) {\n throw new Error(`Unsupported chain: ${name}. Supported: ${Object.keys(CHAINS).join(', ')}`);\n }\n return config;\n}\n\n/**\n * 列出所有支持的链\n */\nexport function listChains(): ChainName[] {\n return Object.keys(CHAINS) as ChainName[];\n}\n\n/**\n * 根据 chainId 获取链配置\n */\nexport function getChainById(chainId: number): ChainConfig | undefined {\n return Object.values(CHAINS).find(c => c.chainId === chainId);\n}\n\n/**\n * ERC20 ABI(最小化,仅包含需要的方法)\n */\nexport const ERC20_ABI = [\n 'function balanceOf(address owner) view returns (uint256)',\n 'function transfer(address to, uint256 amount) returns (bool)',\n 'function approve(address spender, uint256 amount) returns (bool)',\n 'function allowance(address owner, address spender) view returns (uint256)',\n 'function decimals() view returns (uint8)',\n 'function symbol() view returns (string)',\n 'function name() view returns (string)',\n 'function nonces(address owner) view returns (uint256)',\n 'function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s)',\n 'event Transfer(address indexed from, address indexed to, uint256 value)',\n 'event Approval(address indexed owner, address indexed spender, uint256 value)',\n];\n\nexport type { ChainConfig, ChainName };\n","/**\n * Wallet - 基础托管钱包\n * \n * 功能:\n * - 查询余额\n * - 发送 USDC 转账\n */\n\nimport { ethers } from 'ethers';\nimport { getChain, ERC20_ABI } from '../chains/index.js';\nimport type {\n ChainName,\n ChainConfig,\n WalletBalance,\n TransferResult,\n} from '../types/index.js';\n\nexport interface WalletConfig {\n chain?: ChainName;\n privateKey?: string;\n rpcUrl?: string;\n}\n\nexport class Wallet {\n readonly chain: ChainName;\n readonly chainConfig: ChainConfig;\n readonly address: string;\n \n private wallet: ethers.Wallet;\n private provider: ethers.JsonRpcProvider;\n private usdcContract: ethers.Contract;\n\n constructor(config: WalletConfig = {}) {\n this.chain = config.chain || 'base_sepolia';\n this.chainConfig = getChain(this.chain);\n \n const privateKey = config.privateKey || process.env.PAYMENT_AGENT_PRIVATE_KEY;\n if (!privateKey) {\n throw new Error('privateKey is required. Set via config or PAYMENT_AGENT_PRIVATE_KEY env var.');\n }\n\n const rpcUrl = config.rpcUrl || this.chainConfig.rpc;\n this.provider = new ethers.JsonRpcProvider(rpcUrl);\n this.wallet = new ethers.Wallet(privateKey, this.provider);\n this.address = this.wallet.address;\n \n this.usdcContract = new ethers.Contract(\n this.chainConfig.usdc,\n ERC20_ABI,\n this.wallet\n );\n }\n\n /**\n * 获取钱包余额\n */\n async getBalance(): Promise<WalletBalance> {\n const [ethBalance, usdcBalance] = await Promise.all([\n this.provider.getBalance(this.address),\n this.usdcContract.balanceOf(this.address),\n ]);\n\n return {\n address: this.address,\n eth: ethers.formatEther(ethBalance),\n usdc: (Number(usdcBalance) / 1e6).toFixed(2),\n chain: this.chain,\n };\n }\n\n /**\n * 发送 USDC 转账\n */\n async transfer(to: string, amount: number): Promise<TransferResult> {\n try {\n // 验证地址\n to = ethers.getAddress(to);\n \n // 转换金额(USDC 6位小数)\n const amountWei = BigInt(Math.floor(amount * 1e6));\n\n // 检查余额\n const balance = await this.usdcContract.balanceOf(this.address);\n if (BigInt(balance) < amountWei) {\n return {\n success: false,\n error: `Insufficient USDC balance: ${Number(balance) / 1e6} < ${amount}`,\n };\n }\n\n // 发送交易\n const tx = await this.usdcContract.transfer(to, amountWei);\n const receipt = await tx.wait();\n\n if (receipt.status === 1) {\n return {\n success: true,\n tx_hash: tx.hash,\n from: this.address,\n to,\n amount,\n gas_used: Number(receipt.gasUsed),\n block_number: receipt.blockNumber,\n explorer_url: `${this.chainConfig.explorerTx}${tx.hash}`,\n };\n } else {\n return {\n success: false,\n tx_hash: tx.hash,\n error: 'Transaction reverted',\n };\n }\n } catch (error) {\n return {\n success: false,\n error: (error as Error).message,\n };\n }\n }\n\n /**\n * 获取 ETH 余额\n */\n async getEthBalance(): Promise<string> {\n const balance = await this.provider.getBalance(this.address);\n return ethers.formatEther(balance);\n }\n\n /**\n * 获取 USDC 余额\n */\n async getUsdcBalance(): Promise<string> {\n const balance = await this.usdcContract.balanceOf(this.address);\n return (Number(balance) / 1e6).toFixed(2);\n }\n}\n","/**\n * AuditLog - 不可篡改审计日志\n * \n * 特点:\n * - 链式哈希,任何修改都会破坏链条\n * - 按日期分文件存储\n * - JSONL 格式便于追加和解析\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as crypto from 'crypto';\nimport type { AuditEntry, AuditAction } from '../types/index.js';\n\nexport interface LogParams {\n action: AuditAction;\n request_id: string;\n from?: string;\n to?: string;\n amount?: number;\n tx_hash?: string;\n reason?: string;\n requester?: string;\n metadata?: Record<string, unknown>;\n}\n\nexport class AuditLog {\n private basePath: string;\n private lastHash: string = '0000000000000000';\n\n constructor(basePath?: string) {\n this.basePath = basePath || path.join(process.cwd(), 'data', 'audit');\n this.ensureDir();\n this.loadLastHash();\n }\n\n /**\n * 记录审计日志\n */\n async log(params: LogParams): Promise<AuditEntry> {\n const now = new Date();\n \n const entry: AuditEntry = {\n timestamp: now.getTime() / 1000,\n datetime: now.toISOString(),\n action: params.action,\n request_id: params.request_id,\n from: params.from,\n to: params.to,\n amount: params.amount,\n tx_hash: params.tx_hash,\n reason: params.reason,\n requester: params.requester,\n prev_hash: this.lastHash,\n hash: '', // 计算后填充\n metadata: params.metadata,\n };\n\n // 计算哈希(不包含 hash 字段本身)\n entry.hash = this.calculateHash(entry);\n this.lastHash = entry.hash;\n\n // 写入文件\n const filePath = this.getFilePath(now);\n const line = JSON.stringify(entry) + '\\n';\n fs.appendFileSync(filePath, line, 'utf-8');\n\n return entry;\n }\n\n /**\n * 读取指定日期的日志\n */\n read(date?: Date): AuditEntry[] {\n const filePath = this.getFilePath(date || new Date());\n \n if (!fs.existsSync(filePath)) {\n return [];\n }\n\n const content = fs.readFileSync(filePath, 'utf-8');\n const lines = content.trim().split('\\n').filter(Boolean);\n \n return lines.map(line => JSON.parse(line) as AuditEntry);\n }\n\n /**\n * 验证日志完整性\n */\n verify(date?: Date): { valid: boolean; errors: string[] } {\n const entries = this.read(date);\n const errors: string[] = [];\n\n for (let i = 0; i < entries.length; i++) {\n const entry = entries[i];\n \n // 验证哈希\n const expectedHash = this.calculateHash(entry);\n if (entry.hash !== expectedHash) {\n errors.push(`Entry ${i}: hash mismatch (expected ${expectedHash}, got ${entry.hash})`);\n }\n\n // 验证链接\n if (i > 0 && entry.prev_hash !== entries[i - 1].hash) {\n errors.push(`Entry ${i}: prev_hash mismatch`);\n }\n }\n\n return { valid: errors.length === 0, errors };\n }\n\n /**\n * 搜索日志\n */\n search(filter: Partial<{\n action: AuditAction;\n request_id: string;\n from: string;\n to: string;\n startDate: Date;\n endDate: Date;\n }>): AuditEntry[] {\n const results: AuditEntry[] = [];\n const startDate = filter.startDate || new Date(Date.now() - 30 * 24 * 60 * 60 * 1000);\n const endDate = filter.endDate || new Date();\n\n // 遍历日期范围\n const current = new Date(startDate);\n while (current <= endDate) {\n const entries = this.read(current);\n \n for (const entry of entries) {\n let match = true;\n\n if (filter.action && entry.action !== filter.action) match = false;\n if (filter.request_id && entry.request_id !== filter.request_id) match = false;\n if (filter.from && entry.from?.toLowerCase() !== filter.from.toLowerCase()) match = false;\n if (filter.to && entry.to?.toLowerCase() !== filter.to.toLowerCase()) match = false;\n\n if (match) {\n results.push(entry);\n }\n }\n\n current.setDate(current.getDate() + 1);\n }\n\n return results;\n }\n\n /**\n * 获取日志文件路径\n */\n private getFilePath(date: Date): string {\n const dateStr = date.toISOString().slice(0, 10);\n return path.join(this.basePath, `audit_${dateStr}.jsonl`);\n }\n\n /**\n * 计算条目哈希\n */\n private calculateHash(entry: AuditEntry): string {\n const data = {\n timestamp: entry.timestamp,\n action: entry.action,\n request_id: entry.request_id,\n from: entry.from,\n to: entry.to,\n amount: entry.amount,\n tx_hash: entry.tx_hash,\n prev_hash: entry.prev_hash,\n };\n \n const str = JSON.stringify(data);\n return crypto.createHash('sha256').update(str).digest('hex').slice(0, 16);\n }\n\n /**\n * 加载最后一条日志的哈希\n */\n private loadLastHash(): void {\n const today = new Date();\n \n // 检查今天和昨天的日志\n for (let i = 0; i < 2; i++) {\n const date = new Date(today);\n date.setDate(date.getDate() - i);\n \n const entries = this.read(date);\n if (entries.length > 0) {\n this.lastHash = entries[entries.length - 1].hash;\n return;\n }\n }\n }\n\n /**\n * 确保目录存在\n */\n private ensureDir(): void {\n if (!fs.existsSync(this.basePath)) {\n fs.mkdirSync(this.basePath, { recursive: true });\n }\n }\n}\n","/**\n * SecureWallet - 安全托管钱包\n * \n * 在基础 Wallet 之上增加:\n * - 单笔限额控制\n * - 日限额控制\n * - 白名单机制\n * - 审计日志\n * - 超限审批队列\n */\n\nimport { Wallet, type WalletConfig } from './Wallet.js';\nimport { AuditLog } from '../audit/AuditLog.js';\nimport type {\n SecurityLimits,\n SecureWalletConfig,\n TransferResult,\n TransferParams,\n PendingTransfer,\n} from '../types/index.js';\n\nconst DEFAULT_LIMITS: SecurityLimits = {\n singleMax: 100, // 单笔最大 $100\n dailyMax: 1000, // 日最大 $1000\n requireWhitelist: true,\n};\n\nexport class SecureWallet {\n private wallet: Wallet;\n private limits: SecurityLimits;\n private whitelist: Set<string>;\n private auditLog: AuditLog;\n private dailyTotal: number = 0;\n private dailyDate: string = '';\n private pendingTransfers: Map<string, PendingTransfer> = new Map();\n\n constructor(config: SecureWalletConfig = {}) {\n this.wallet = new Wallet({\n chain: config.chain,\n privateKey: config.privateKey,\n });\n\n this.limits = { ...DEFAULT_LIMITS, ...config.limits };\n this.whitelist = new Set((config.whitelist || []).map(a => a.toLowerCase()));\n this.auditLog = new AuditLog(config.auditPath);\n }\n\n /**\n * 获取钱包地址\n */\n get address(): string {\n return this.wallet.address;\n }\n\n /**\n * 获取余额\n */\n async getBalance() {\n return this.wallet.getBalance();\n }\n\n /**\n * 安全转账(带限额和白名单检查)\n * \n * 支持两种调用方式:\n * - transfer({ to, amount, reason?, requester? })\n * - transfer(to, amount)\n */\n async transfer(paramsOrTo: TransferParams | string, amountArg?: number | string): Promise<TransferResult> {\n // 支持两种调用方式\n let params: TransferParams;\n if (typeof paramsOrTo === 'string') {\n params = { \n to: paramsOrTo, \n amount: typeof amountArg === 'string' ? parseFloat(amountArg) : (amountArg || 0)\n };\n } else {\n params = paramsOrTo;\n }\n \n const { to, amount, reason, requester } = params;\n const toAddress = to.toLowerCase();\n const requestId = `tr_${Date.now().toString(36)}${Math.random().toString(36).slice(2, 8)}`;\n\n // 记录请求\n await this.auditLog.log({\n action: 'transfer_request',\n request_id: requestId,\n from: this.wallet.address,\n to,\n amount,\n reason,\n requester,\n });\n\n // 1. 白名单检查\n if (this.limits.requireWhitelist && !this.whitelist.has(toAddress)) {\n await this.auditLog.log({\n action: 'transfer_failed',\n request_id: requestId,\n metadata: { error: 'Address not in whitelist' },\n });\n return { success: false, error: `Address not in whitelist: ${to}` };\n }\n\n // 2. 单笔限额检查\n if (amount > this.limits.singleMax) {\n // 加入审批队列\n const pending: PendingTransfer = {\n id: requestId,\n to,\n amount,\n reason,\n requester,\n created_at: new Date().toISOString(),\n status: 'pending',\n };\n this.pendingTransfers.set(requestId, pending);\n \n await this.auditLog.log({\n action: 'transfer_request',\n request_id: requestId,\n metadata: { pending: true, reason: 'Exceeds single limit' },\n });\n \n return {\n success: false,\n error: `Amount ${amount} exceeds single limit ${this.limits.singleMax}. Pending approval: ${requestId}`,\n };\n }\n\n // 3. 日限额检查\n this.updateDailyTotal();\n if (this.dailyTotal + amount > this.limits.dailyMax) {\n const pending: PendingTransfer = {\n id: requestId,\n to,\n amount,\n reason,\n requester,\n created_at: new Date().toISOString(),\n status: 'pending',\n };\n this.pendingTransfers.set(requestId, pending);\n \n await this.auditLog.log({\n action: 'transfer_request',\n request_id: requestId,\n metadata: { pending: true, reason: 'Exceeds daily limit' },\n });\n \n return {\n success: false,\n error: `Daily limit would be exceeded (${this.dailyTotal} + ${amount} > ${this.limits.dailyMax}). Pending approval: ${requestId}`,\n };\n }\n\n // 4. 执行转账\n const result = await this.wallet.transfer(to, amount);\n\n // 5. 记录结果\n if (result.success) {\n this.dailyTotal += amount;\n await this.auditLog.log({\n action: 'transfer_executed',\n request_id: requestId,\n from: this.wallet.address,\n to,\n amount,\n tx_hash: result.tx_hash,\n reason,\n requester,\n });\n } else {\n await this.auditLog.log({\n action: 'transfer_failed',\n request_id: requestId,\n metadata: { error: result.error },\n });\n }\n\n return result;\n }\n\n /**\n * 审批待处理转账\n */\n async approve(requestId: string, approver: string): Promise<TransferResult> {\n const pending = this.pendingTransfers.get(requestId);\n if (!pending) {\n return { success: false, error: `Pending transfer not found: ${requestId}` };\n }\n\n if (pending.status !== 'pending') {\n return { success: false, error: `Transfer already ${pending.status}` };\n }\n\n await this.auditLog.log({\n action: 'transfer_approved',\n request_id: requestId,\n metadata: { approver },\n });\n\n pending.status = 'approved';\n\n // 执行转账(跳过限额检查)\n const result = await this.wallet.transfer(pending.to, pending.amount);\n\n if (result.success) {\n pending.status = 'executed';\n this.dailyTotal += pending.amount;\n \n await this.auditLog.log({\n action: 'transfer_executed',\n request_id: requestId,\n from: this.wallet.address,\n to: pending.to,\n amount: pending.amount,\n tx_hash: result.tx_hash,\n reason: pending.reason,\n requester: pending.requester,\n metadata: { approved_by: approver },\n });\n } else {\n await this.auditLog.log({\n action: 'transfer_failed',\n request_id: requestId,\n metadata: { error: result.error },\n });\n }\n\n return result;\n }\n\n /**\n * 拒绝待处理转账\n */\n async reject(requestId: string, rejecter: string, reason?: string): Promise<void> {\n const pending = this.pendingTransfers.get(requestId);\n if (!pending) {\n throw new Error(`Pending transfer not found: ${requestId}`);\n }\n\n pending.status = 'rejected';\n\n await this.auditLog.log({\n action: 'transfer_rejected',\n request_id: requestId,\n metadata: { rejected_by: rejecter, reason },\n });\n }\n\n /**\n * 添加白名单地址\n */\n async addToWhitelist(address: string, addedBy: string): Promise<void> {\n const addr = address.toLowerCase();\n this.whitelist.add(addr);\n\n await this.auditLog.log({\n action: 'whitelist_add',\n request_id: `wl_${Date.now()}`,\n to: address,\n metadata: { added_by: addedBy },\n });\n }\n\n /**\n * 移除白名单地址\n */\n async removeFromWhitelist(address: string, removedBy: string): Promise<void> {\n const addr = address.toLowerCase();\n this.whitelist.delete(addr);\n\n await this.auditLog.log({\n action: 'whitelist_remove',\n request_id: `wl_${Date.now()}`,\n to: address,\n metadata: { removed_by: removedBy },\n });\n }\n\n /**\n * 检查地址是否在白名单\n */\n isWhitelisted(address: string): boolean {\n return this.whitelist.has(address.toLowerCase());\n }\n\n /**\n * 获取待处理转账列表\n */\n getPendingTransfers(): PendingTransfer[] {\n return Array.from(this.pendingTransfers.values())\n .filter(p => p.status === 'pending');\n }\n\n /**\n * 获取当前限额配置\n */\n getLimits(): SecurityLimits {\n return { ...this.limits };\n }\n\n /**\n * 获取今日已用额度\n */\n getDailyUsed(): number {\n this.updateDailyTotal();\n return this.dailyTotal;\n }\n\n /**\n * 更新日限额计数器\n */\n private updateDailyTotal(): void {\n const today = new Date().toISOString().slice(0, 10);\n if (this.dailyDate !== today) {\n this.dailyDate = today;\n this.dailyTotal = 0;\n }\n }\n}\n","/**\n * createWallet - Create a new wallet for Agent\n * \n * Features:\n * - Generate new Ethereum wallet\n * - Securely store private key (encrypted or plaintext, depending on config)\n * - Return wallet address (never return private key)\n */\n\nimport { ethers } from 'ethers';\nimport { writeFileSync, readFileSync, existsSync, mkdirSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { createCipheriv, createDecipheriv, randomBytes, scryptSync } from 'crypto';\n\nexport interface CreateWalletOptions {\n /** Storage path, default ~/.moltspay/wallet.json */\n storagePath?: string;\n /** Encryption password (optional, plaintext if not provided) */\n password?: string;\n /** Wallet label/name */\n label?: string;\n /** Overwrite if wallet exists */\n overwrite?: boolean;\n}\n\nexport interface WalletData {\n address: string;\n label?: string;\n createdAt: string;\n encrypted: boolean;\n /** Encrypted or plaintext private key */\n privateKey: string;\n /** Encryption IV */\n iv?: string;\n /** Encryption salt */\n salt?: string;\n}\n\nexport interface CreateWalletResult {\n success: boolean;\n address?: string;\n storagePath?: string;\n error?: string;\n /** Whether newly created (false means loaded existing) */\n isNew?: boolean;\n}\n\nconst DEFAULT_STORAGE_DIR = join(process.env.HOME || '~', '.moltspay');\nconst DEFAULT_STORAGE_FILE = 'wallet.json';\n\n/**\n * Encrypt private key\n */\nfunction encryptPrivateKey(privateKey: string, password: string): { encrypted: string; iv: string; salt: string } {\n const salt = randomBytes(16);\n const key = scryptSync(password, salt, 32);\n const iv = randomBytes(16);\n \n const cipher = createCipheriv('aes-256-cbc', key, iv);\n let encrypted = cipher.update(privateKey, 'utf8', 'hex');\n encrypted += cipher.final('hex');\n \n return {\n encrypted,\n iv: iv.toString('hex'),\n salt: salt.toString('hex'),\n };\n}\n\n/**\n * Decrypt private key\n */\nfunction decryptPrivateKey(encrypted: string, password: string, iv: string, salt: string): string {\n const key = scryptSync(password, Buffer.from(salt, 'hex'), 32);\n const decipher = createDecipheriv('aes-256-cbc', key, Buffer.from(iv, 'hex'));\n \n let decrypted = decipher.update(encrypted, 'hex', 'utf8');\n decrypted += decipher.final('utf8');\n \n return decrypted;\n}\n\n/**\n * Create new wallet\n * \n * @example\n * ```typescript\n * // Create unencrypted wallet\n * const result = await createWallet();\n * console.log('Wallet address:', result.address);\n * \n * // Create encrypted wallet\n * const result = await createWallet({ password: 'mySecurePassword' });\n * \n * // Specify storage path\n * const result = await createWallet({ storagePath: './my-wallet.json' });\n * ```\n */\nexport function createWallet(options: CreateWalletOptions = {}): CreateWalletResult {\n const storagePath = options.storagePath || join(DEFAULT_STORAGE_DIR, DEFAULT_STORAGE_FILE);\n \n // Check if exists\n if (existsSync(storagePath) && !options.overwrite) {\n // Load existing wallet\n try {\n const existing = JSON.parse(readFileSync(storagePath, 'utf8')) as WalletData;\n return {\n success: true,\n address: existing.address,\n storagePath,\n isNew: false,\n };\n } catch (error) {\n return {\n success: false,\n error: `Failed to load existing wallet: ${(error as Error).message}`,\n };\n }\n }\n\n try {\n // Create new wallet\n const wallet = ethers.Wallet.createRandom();\n \n // Prepare storage data\n const walletData: WalletData = {\n address: wallet.address,\n label: options.label,\n createdAt: new Date().toISOString(),\n encrypted: !!options.password,\n privateKey: '',\n };\n\n if (options.password) {\n // Encrypted storage\n const { encrypted, iv, salt } = encryptPrivateKey(wallet.privateKey, options.password);\n walletData.privateKey = encrypted;\n walletData.iv = iv;\n walletData.salt = salt;\n } else {\n // Plaintext storage (not recommended, but convenient for testing/dev)\n walletData.privateKey = wallet.privateKey;\n }\n\n // Ensure directory exists\n const dir = dirname(storagePath);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n\n // Write file\n writeFileSync(storagePath, JSON.stringify(walletData, null, 2), { mode: 0o600 });\n\n return {\n success: true,\n address: wallet.address,\n storagePath,\n isNew: true,\n };\n } catch (error) {\n return {\n success: false,\n error: (error as Error).message,\n };\n }\n}\n\n/**\n * Load existing wallet\n */\nexport function loadWallet(options: { storagePath?: string; password?: string } = {}): {\n success: boolean;\n address?: string;\n privateKey?: string;\n error?: string;\n} {\n const storagePath = options.storagePath || join(DEFAULT_STORAGE_DIR, DEFAULT_STORAGE_FILE);\n\n if (!existsSync(storagePath)) {\n return { success: false, error: 'Wallet not found. Run createWallet() first.' };\n }\n\n try {\n const data = JSON.parse(readFileSync(storagePath, 'utf8')) as WalletData;\n\n if (data.encrypted) {\n if (!options.password) {\n return { success: false, error: 'Wallet is encrypted. Password required.' };\n }\n const privateKey = decryptPrivateKey(data.privateKey, options.password, data.iv!, data.salt!);\n return { success: true, address: data.address, privateKey };\n } else {\n return { success: true, address: data.address, privateKey: data.privateKey };\n }\n } catch (error) {\n return { success: false, error: (error as Error).message };\n }\n}\n\n/**\n * Get wallet address (no password required)\n */\nexport function getWalletAddress(storagePath?: string): string | null {\n const path = storagePath || join(DEFAULT_STORAGE_DIR, DEFAULT_STORAGE_FILE);\n \n if (!existsSync(path)) {\n return null;\n }\n\n try {\n const data = JSON.parse(readFileSync(path, 'utf8')) as WalletData;\n return data.address;\n } catch {\n return null;\n }\n}\n\n/**\n * Check if wallet exists\n */\nexport function walletExists(storagePath?: string): boolean {\n const path = storagePath || join(DEFAULT_STORAGE_DIR, DEFAULT_STORAGE_FILE);\n return existsSync(path);\n}\n","/**\n * PermitWallet - Pay using Boss's Permit authorization\n * \n * Scenario:\n * - Agent doesn't have USDC, but Boss gave a Permit authorization\n * - Agent uses Permit signature + own wallet to execute transferFrom\n * - Agent only needs small amount of ETH for gas, USDC is deducted from Boss's wallet\n */\n\nimport { ethers } from 'ethers';\nimport { getChain, ERC20_ABI } from '../chains/index.js';\nimport { loadWallet } from './createWallet.js';\nimport type {\n ChainName,\n ChainConfig,\n TransferResult,\n PermitSignature,\n} from '../types/index.js';\n\nexport interface PermitData {\n /** Boss's wallet address (USDC holder) */\n owner: string;\n /** Agent's wallet address (authorized spender) */\n spender: string;\n /** Authorized amount (USDC, raw 6 decimal value) */\n value: string;\n /** Expiration timestamp */\n deadline: number;\n /** Signature v */\n v: number;\n /** Signature r */\n r: string;\n /** Signature s */\n s: string;\n}\n\nexport interface PermitWalletConfig {\n chain?: ChainName;\n /** Agent's private key (for executing transactions) */\n privateKey?: string;\n /** Load private key from file */\n walletPath?: string;\n /** Decryption password */\n walletPassword?: string;\n rpcUrl?: string;\n}\n\nexport interface TransferWithPermitParams {\n /** Recipient address */\n to: string;\n /** Amount (USDC) */\n amount: number;\n /** Boss-signed Permit data */\n permit: PermitData;\n}\n\nexport interface TransferWithPermitResult extends TransferResult {\n /** Permit transaction hash */\n permitTxHash?: string;\n /** Transfer transaction hash */\n transferTxHash?: string;\n}\n\n// Extended ABI to support permit and transferFrom\nconst PERMIT_ABI = [\n ...ERC20_ABI,\n 'function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s)',\n 'function transferFrom(address from, address to, uint256 amount) returns (bool)',\n 'function allowance(address owner, address spender) view returns (uint256)',\n];\n\nexport class PermitWallet {\n readonly chain: ChainName;\n readonly chainConfig: ChainConfig;\n readonly address: string;\n \n private wallet: ethers.Wallet;\n private provider: ethers.JsonRpcProvider;\n private usdcContract: ethers.Contract;\n\n constructor(config: PermitWalletConfig = {}) {\n this.chain = config.chain || 'base_sepolia';\n this.chainConfig = getChain(this.chain);\n \n // Get private key\n let privateKey = config.privateKey || process.env.PAYMENT_AGENT_PRIVATE_KEY;\n \n // Or load from file\n if (!privateKey && config.walletPath) {\n const loaded = loadWallet({ \n storagePath: config.walletPath, \n password: config.walletPassword \n });\n if (!loaded.success || !loaded.privateKey) {\n throw new Error(loaded.error || 'Failed to load wallet');\n }\n privateKey = loaded.privateKey;\n }\n \n if (!privateKey) {\n throw new Error('privateKey is required. Set via config, env var, or walletPath.');\n }\n\n const rpcUrl = config.rpcUrl || this.chainConfig.rpc;\n this.provider = new ethers.JsonRpcProvider(rpcUrl);\n this.wallet = new ethers.Wallet(privateKey, this.provider);\n this.address = this.wallet.address;\n \n this.usdcContract = new ethers.Contract(\n this.chainConfig.usdc,\n PERMIT_ABI,\n this.wallet\n );\n }\n\n /**\n * Check if Permit is valid (current allowance)\n */\n async checkPermitAllowance(owner: string): Promise<string> {\n const allowance = await this.usdcContract.allowance(owner, this.address);\n return (Number(allowance) / 1e6).toFixed(2);\n }\n\n /**\n * Pay using Permit authorization\n * \n * Flow:\n * 1. Call permit() to record Boss's authorization in the contract\n * 2. Call transferFrom() to transfer from Boss's wallet to recipient\n * \n * @example\n * ```typescript\n * const wallet = new PermitWallet({ chain: 'base' });\n * \n * // Boss-signed permit data\n * const permit = {\n * owner: '0xBOSS...',\n * spender: wallet.address,\n * value: '10000000', // 10 USDC\n * deadline: 1234567890,\n * v: 27,\n * r: '0x...',\n * s: '0x...'\n * };\n * \n * const result = await wallet.transferWithPermit({\n * to: '0xSELLER...',\n * amount: 3.99,\n * permit\n * });\n * ```\n */\n async transferWithPermit(params: TransferWithPermitParams): Promise<TransferWithPermitResult> {\n const { to, amount, permit } = params;\n\n try {\n // Validate addresses\n const toAddress = ethers.getAddress(to);\n const ownerAddress = ethers.getAddress(permit.owner);\n \n // Verify spender is this wallet\n if (ethers.getAddress(permit.spender).toLowerCase() !== this.address.toLowerCase()) {\n return {\n success: false,\n error: `Permit spender (${permit.spender}) doesn't match wallet address (${this.address})`,\n };\n }\n\n // Check deadline\n const now = Math.floor(Date.now() / 1000);\n if (permit.deadline < now) {\n return {\n success: false,\n error: `Permit expired at ${new Date(permit.deadline * 1000).toISOString()}`,\n };\n }\n\n // Convert amount\n const amountWei = BigInt(Math.floor(amount * 1e6));\n const permitValue = BigInt(permit.value);\n \n // Check if authorized amount is sufficient\n if (amountWei > permitValue) {\n return {\n success: false,\n error: `Permit value (${Number(permitValue) / 1e6} USDC) < transfer amount (${amount} USDC)`,\n };\n }\n\n // Check existing allowance\n const currentAllowance = await this.usdcContract.allowance(ownerAddress, this.address);\n \n let permitTxHash: string | undefined;\n \n // If allowance insufficient, execute permit first\n if (BigInt(currentAllowance) < amountWei) {\n console.log('Executing permit...');\n const permitTx = await this.usdcContract.permit(\n ownerAddress,\n this.address,\n permitValue,\n permit.deadline,\n permit.v,\n permit.r,\n permit.s\n );\n const permitReceipt = await permitTx.wait();\n \n if (permitReceipt.status !== 1) {\n return {\n success: false,\n error: 'Permit transaction failed',\n permitTxHash: permitTx.hash,\n };\n }\n permitTxHash = permitTx.hash;\n console.log('Permit executed:', permitTxHash);\n }\n\n // Execute transferFrom\n console.log('Executing transferFrom...');\n const transferTx = await this.usdcContract.transferFrom(\n ownerAddress,\n toAddress,\n amountWei\n );\n const transferReceipt = await transferTx.wait();\n\n if (transferReceipt.status === 1) {\n return {\n success: true,\n tx_hash: transferTx.hash,\n permitTxHash,\n transferTxHash: transferTx.hash,\n from: ownerAddress,\n to: toAddress,\n amount,\n gas_used: Number(transferReceipt.gasUsed),\n block_number: transferReceipt.blockNumber,\n explorer_url: `${this.chainConfig.explorerTx}${transferTx.hash}`,\n };\n } else {\n return {\n success: false,\n error: 'TransferFrom transaction failed',\n tx_hash: transferTx.hash,\n permitTxHash,\n };\n }\n } catch (error) {\n const message = (error as Error).message;\n \n // Parse common errors\n if (message.includes('ERC20InsufficientAllowance')) {\n return {\n success: false,\n error: 'Insufficient allowance. Permit may have been used or expired.',\n };\n }\n if (message.includes('ERC20InsufficientBalance')) {\n return {\n success: false,\n error: 'Boss wallet has insufficient USDC balance.',\n };\n }\n if (message.includes('InvalidSignature') || message.includes('invalid signature')) {\n return {\n success: false,\n error: 'Invalid permit signature. Ask Boss to re-sign.',\n };\n }\n \n return {\n success: false,\n error: message,\n };\n }\n }\n\n /**\n * Get ETH balance (for gas)\n */\n async getGasBalance(): Promise<string> {\n const balance = await this.provider.getBalance(this.address);\n return ethers.formatEther(balance);\n }\n\n /**\n * Check if there's enough gas\n */\n async hasEnoughGas(minEth: number = 0.001): Promise<boolean> {\n const balance = await this.getGasBalance();\n return parseFloat(balance) >= minEth;\n }\n}\n\n/**\n * Format Permit request message (to send to Boss)\n */\nexport function formatPermitRequest(params: {\n agentAddress: string;\n amount: number;\n deadlineHours?: number;\n chain?: ChainName;\n reason?: string;\n}): string {\n const { agentAddress, amount, deadlineHours = 24, chain = 'base', reason } = params;\n const chainConfig = getChain(chain);\n const deadline = Math.floor(Date.now() / 1000) + deadlineHours * 3600;\n const value = BigInt(Math.floor(amount * 1e6)).toString();\n\n return `🔐 **USDC Spending Allowance Request**\n\n${reason ? `**Purpose:** ${reason}\\n` : ''}\n**Authorization Details:**\n- Authorized address (Agent): \\`${agentAddress}\\`\n- Amount: ${amount} USDC\n- Valid for: ${deadlineHours} hours\n- Chain: ${chainConfig.name}\n\n**Please sign the following EIP-2612 Permit with your wallet:**\n\n\\`\\`\\`json\n{\n \"types\": {\n \"Permit\": [\n { \"name\": \"owner\", \"type\": \"address\" },\n { \"name\": \"spender\", \"type\": \"address\" },\n { \"name\": \"value\", \"type\": \"uint256\" },\n { \"name\": \"nonce\", \"type\": \"uint256\" },\n { \"name\": \"deadline\", \"type\": \"uint256\" }\n ]\n },\n \"primaryType\": \"Permit\",\n \"domain\": {\n \"name\": \"USD Coin\",\n \"version\": \"2\",\n \"chainId\": ${chainConfig.chainId},\n \"verifyingContract\": \"${chainConfig.usdc}\"\n },\n \"message\": {\n \"owner\": \"<YOUR_WALLET_ADDRESS>\",\n \"spender\": \"${agentAddress}\",\n \"value\": \"${value}\",\n \"nonce\": \"<GET_FROM_CONTRACT>\",\n \"deadline\": ${deadline}\n }\n}\n\\`\\`\\`\n\nAfter signing, send { v, r, s, deadline } to the Agent.\n\n⚠️ Note: This authorization only allows the Agent to spend up to ${amount} USDC from your wallet. Your private key is never exposed.`;\n}\n","/**\n * PermitPayment - EIP-2612 无 Gas 预授权\n * \n * 让用户通过签名授权,服务方代付 Gas 执行 transferFrom\n */\n\nimport { ethers } from 'ethers';\nimport { getChain, ERC20_ABI } from '../chains/index.js';\nimport type {\n ChainName,\n ChainConfig,\n PermitRequest,\n PermitSignature,\n PermitExecuteResult,\n EIP712TypedData,\n} from '../types/index.js';\n\nexport interface PermitConfig {\n chain?: ChainName;\n privateKey?: string;\n spenderAddress?: string;\n rpcUrl?: string;\n}\n\nexport class PermitPayment {\n readonly chain: ChainName;\n readonly chainConfig: ChainConfig;\n readonly spenderAddress: string;\n \n private provider: ethers.JsonRpcProvider;\n private wallet?: ethers.Wallet;\n private usdcContract: ethers.Contract;\n\n constructor(config: PermitConfig = {}) {\n this.chain = config.chain || 'base_sepolia';\n this.chainConfig = getChain(this.chain);\n this.spenderAddress = config.spenderAddress || process.env.PAYMENT_AGENT_WALLET || '';\n\n const rpcUrl = config.rpcUrl || this.chainConfig.rpc;\n this.provider = new ethers.JsonRpcProvider(rpcUrl);\n\n const privateKey = config.privateKey || process.env.PAYMENT_AGENT_PRIVATE_KEY;\n if (privateKey) {\n this.wallet = new ethers.Wallet(privateKey, this.provider);\n this.spenderAddress = this.wallet.address;\n }\n\n this.usdcContract = new ethers.Contract(\n this.chainConfig.usdc,\n ERC20_ABI,\n this.wallet || this.provider\n );\n }\n\n /**\n * 获取用户当前 nonce\n */\n async getNonce(owner: string): Promise<number> {\n return Number(await this.usdcContract.nonces(owner));\n }\n\n /**\n * 生成 EIP-712 签名请求(发给前端/用户钱包)\n */\n async createPermitRequest(\n owner: string,\n amount: number,\n orderId: string,\n deadlineMinutes: number = 30\n ): Promise<PermitRequest> {\n const nonce = await this.getNonce(owner);\n const deadline = Math.floor(Date.now() / 1000) + deadlineMinutes * 60;\n const value = BigInt(Math.floor(amount * 1e6)).toString();\n\n // USDC 的 EIP-712 domain(不同链可能不同)\n const domain = {\n name: 'USD Coin',\n version: '2',\n chainId: this.chainConfig.chainId,\n verifyingContract: this.chainConfig.usdc,\n };\n\n const types = {\n EIP712Domain: [\n { name: 'name', type: 'string' },\n { name: 'version', type: 'string' },\n { name: 'chainId', type: 'uint256' },\n { name: 'verifyingContract', type: 'address' },\n ],\n Permit: [\n { name: 'owner', type: 'address' },\n { name: 'spender', type: 'address' },\n { name: 'value', type: 'uint256' },\n { name: 'nonce', type: 'uint256' },\n { name: 'deadline', type: 'uint256' },\n ],\n };\n\n const message = {\n owner,\n spender: this.spenderAddress,\n value,\n nonce,\n deadline,\n };\n\n const typedData: EIP712TypedData = {\n types,\n primaryType: 'Permit',\n domain,\n message,\n };\n\n return {\n type: 'permit_request',\n version: '1.0',\n order_id: orderId,\n typed_data: typedData,\n };\n }\n\n /**\n * 执行 permit + transferFrom\n * \n * @param owner 用户地址\n * @param amount 金额\n * @param signature 用户签名 {v, r, s, deadline}\n */\n async executePermitAndTransfer(\n owner: string,\n amount: number,\n signature: PermitSignature\n ): Promise<PermitExecuteResult> {\n if (!this.wallet) {\n return { success: false, error: 'Wallet not configured. Private key required.' };\n }\n\n try {\n const value = BigInt(Math.floor(amount * 1e6));\n\n // 1. 调用 permit\n const permitTx = await this.usdcContract.permit(\n owner,\n this.spenderAddress,\n value,\n signature.deadline,\n signature.v,\n signature.r,\n signature.s\n );\n await permitTx.wait();\n\n // 2. 调用 transferFrom\n const transferTx = await this.usdcContract.transferFrom(owner, this.spenderAddress, value);\n const receipt = await transferTx.wait();\n\n return {\n success: receipt.status === 1,\n tx_hash: transferTx.hash,\n };\n } catch (error) {\n return {\n success: false,\n error: (error as Error).message,\n };\n }\n }\n\n /**\n * 仅执行 permit(不 transfer)\n */\n async executePermit(\n owner: string,\n amount: number,\n signature: PermitSignature\n ): Promise<PermitExecuteResult> {\n if (!this.wallet) {\n return { success: false, error: 'Wallet not configured. Private key required.' };\n }\n\n try {\n const value = BigInt(Math.floor(amount * 1e6));\n\n const tx = await this.usdcContract.permit(\n owner,\n this.spenderAddress,\n value,\n signature.deadline,\n signature.v,\n signature.r,\n signature.s\n );\n const receipt = await tx.wait();\n\n return {\n success: receipt.status === 1,\n tx_hash: tx.hash,\n };\n } catch (error) {\n return {\n success: false,\n error: (error as Error).message,\n };\n }\n }\n\n /**\n * 格式化 Permit 请求为用户消息\n */\n formatPermitMessage(request: PermitRequest): string {\n const { typed_data } = request;\n const { message } = typed_data;\n\n return `🔐 **签名授权请求**\n\n授权 \\`${(Number(message.value) / 1e6).toFixed(2)} USDC\\` 给服务方\n\n**签名信息:**\n- Owner: \\`${message.owner}\\`\n- Spender: \\`${message.spender}\\`\n- Amount: ${(Number(message.value) / 1e6).toFixed(2)} USDC\n- Deadline: ${new Date(message.deadline * 1000).toISOString()}\n\n请在钱包中签名此请求(不消耗 Gas)。\n\n\\`\\`\\`json\n${JSON.stringify(typed_data, null, 2)}\n\\`\\`\\``;\n }\n}\n","/**\n * 订单管理模块\n */\n\nimport { randomBytes } from 'crypto';\n\nexport interface Order {\n orderId: string;\n prompt: string;\n imageUrl?: string;\n userId: string;\n price: number;\n chain: string;\n status: OrderStatus;\n createdAt: string;\n paidAt?: string;\n txHash?: string;\n payerAddress?: string;\n videoPath?: string;\n error?: string;\n}\n\nexport type OrderStatus = \n | 'pending' // 等待支付\n | 'paid' // 已支付\n | 'generating' // 生成中\n | 'completed' // 已完成\n | 'failed' // 失败\n | 'cancelled'; // 已取消\n\nexport interface CreateOrderParams {\n prompt: string;\n userId: string;\n price?: number;\n chain?: string;\n imageUrl?: string;\n}\n\nexport interface OrderStore {\n get(orderId: string): Promise<Order | null>;\n set(order: Order): Promise<void>;\n findByUser(userId: string, status?: OrderStatus): Promise<Order[]>;\n list(limit?: number): Promise<Order[]>;\n}\n\n/**\n * 内存订单存储(默认实现)\n */\nexport class MemoryOrderStore implements OrderStore {\n private orders: Map<string, Order> = new Map();\n\n async get(orderId: string): Promise<Order | null> {\n return this.orders.get(orderId) || null;\n }\n\n async set(order: Order): Promise<void> {\n this.orders.set(order.orderId, order);\n }\n\n async findByUser(userId: string, status?: OrderStatus): Promise<Order[]> {\n const results: Order[] = [];\n for (const order of this.orders.values()) {\n if (order.userId === userId) {\n if (!status || order.status === status) {\n results.push(order);\n }\n }\n }\n return results.sort((a, b) => \n new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()\n );\n }\n\n async list(limit = 100): Promise<Order[]> {\n return Array.from(this.orders.values())\n .sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime())\n .slice(0, limit);\n }\n}\n\n/**\n * 订单管理器\n */\nexport class OrderManager {\n private store: OrderStore;\n private defaultPrice: number;\n private defaultChain: string;\n\n constructor(options: {\n store?: OrderStore;\n defaultPrice?: number;\n defaultChain?: string;\n } = {}) {\n this.store = options.store || new MemoryOrderStore();\n this.defaultPrice = options.defaultPrice || 2.0;\n this.defaultChain = options.defaultChain || 'base';\n }\n\n /**\n * 生成订单ID\n */\n private generateOrderId(): string {\n return 'vo_' + randomBytes(4).toString('hex');\n }\n\n /**\n * 创建订单\n */\n async createOrder(params: CreateOrderParams): Promise<Order> {\n const order: Order = {\n orderId: this.generateOrderId(),\n prompt: params.prompt,\n imageUrl: params.imageUrl,\n userId: params.userId,\n price: params.price || this.defaultPrice,\n chain: params.chain || this.defaultChain,\n status: 'pending',\n createdAt: new Date().toISOString(),\n };\n\n await this.store.set(order);\n return order;\n }\n\n /**\n * 获取订单\n */\n async getOrder(orderId: string): Promise<Order | null> {\n return this.store.get(orderId);\n }\n\n /**\n * 更新订单\n */\n async updateOrder(orderId: string, updates: Partial<Order>): Promise<Order | null> {\n const order = await this.store.get(orderId);\n if (!order) return null;\n\n const updated = { ...order, ...updates };\n await this.store.set(updated);\n return updated;\n }\n\n /**\n * 查找用户的待支付订单\n */\n async findPendingOrder(userId: string): Promise<Order | null> {\n const orders = await this.store.findByUser(userId, 'pending');\n \n // 返回24小时内的待支付订单\n const now = Date.now();\n for (const order of orders) {\n const age = now - new Date(order.createdAt).getTime();\n if (age < 24 * 60 * 60 * 1000) {\n return order;\n }\n }\n return null;\n }\n\n /**\n * 标记订单为已支付\n */\n async markAsPaid(orderId: string, txHash: string, payerAddress?: string): Promise<Order | null> {\n return this.updateOrder(orderId, {\n status: 'paid',\n paidAt: new Date().toISOString(),\n txHash,\n payerAddress,\n });\n }\n\n /**\n * 标记订单为生成中\n */\n async markAsGenerating(orderId: string): Promise<Order | null> {\n return this.updateOrder(orderId, { status: 'generating' });\n }\n\n /**\n * 标记订单为完成\n */\n async markAsCompleted(orderId: string, videoPath: string): Promise<Order | null> {\n return this.updateOrder(orderId, {\n status: 'completed',\n videoPath,\n });\n }\n\n /**\n * 标记订单为失败\n */\n async markAsFailed(orderId: string, error: string): Promise<Order | null> {\n return this.updateOrder(orderId, {\n status: 'failed',\n error,\n });\n }\n\n /**\n * 取消订单\n */\n async cancelOrder(orderId: string): Promise<Order | null> {\n return this.updateOrder(orderId, { status: 'cancelled' });\n }\n}\n","/**\n * 链上支付验证模块\n */\n\nimport { ethers } from 'ethers';\nimport { getChain, getChainById, type ChainConfig, type ChainName } from '../chains';\n\n// ERC20 Transfer 事件签名\nconst TRANSFER_EVENT_TOPIC = ethers.id('Transfer(address,address,uint256)');\n\nexport interface VerifyPaymentParams {\n txHash: string;\n expectedAmount: number;\n expectedTo?: string;\n chain?: string | number;\n}\n\nexport interface VerifyPaymentResult {\n verified: boolean;\n amount?: number;\n from?: string;\n to?: string;\n txHash?: string;\n blockNumber?: number;\n error?: string;\n}\n\n/**\n * 验证链上支付\n */\nexport async function verifyPayment(params: VerifyPaymentParams): Promise<VerifyPaymentResult> {\n const { txHash, expectedAmount, expectedTo } = params;\n \n // 获取链配置\n let chain: ChainConfig | undefined;\n try {\n if (typeof params.chain === 'number') {\n chain = getChainById(params.chain);\n } else {\n chain = getChain((params.chain || 'base') as ChainName);\n }\n if (!chain) {\n return { verified: false, error: `不支持的链: ${params.chain}` };\n }\n } catch (e) {\n return { verified: false, error: `不支持的链: ${params.chain}` };\n }\n\n try {\n const provider = new ethers.JsonRpcProvider(chain.rpc);\n \n // 获取交易回执\n const receipt = await provider.getTransactionReceipt(txHash);\n \n if (!receipt) {\n return { verified: false, error: '交易未找到或未确认' };\n }\n\n if (receipt.status !== 1) {\n return { verified: false, error: '交易失败' };\n }\n\n // 解析 Transfer 事件\n const usdcAddress = chain.usdc?.toLowerCase();\n if (!usdcAddress) {\n return { verified: false, error: `链 ${chain.name} 未配置USDC地址` };\n }\n\n for (const log of receipt.logs) {\n // 检查是否是 USDC 合约\n if (log.address.toLowerCase() !== usdcAddress) {\n continue;\n }\n\n // 检查是否是 Transfer 事件\n if (log.topics.length < 3 || log.topics[0] !== TRANSFER_EVENT_TOPIC) {\n continue;\n }\n\n // 解析 Transfer 事件参数\n const from = '0x' + log.topics[1].slice(-40);\n const to = '0x' + log.topics[2].slice(-40);\n const amountRaw = BigInt(log.data);\n const amount = Number(amountRaw) / 1e6; // USDC 6位小数\n\n // 验证收款地址\n if (expectedTo && to.toLowerCase() !== expectedTo.toLowerCase()) {\n continue;\n }\n\n // 验证金额\n if (amount < expectedAmount) {\n return {\n verified: false,\n error: `金额不足: 收到 ${amount} USDC, 需要 ${expectedAmount} USDC`,\n amount,\n from,\n to,\n txHash,\n blockNumber: receipt.blockNumber,\n };\n }\n\n // 验证成功\n return {\n verified: true,\n amount,\n from,\n to,\n txHash,\n blockNumber: receipt.blockNumber,\n };\n }\n\n return { verified: false, error: '未找到USDC转账记录' };\n\n } catch (e: any) {\n return { verified: false, error: e.message || String(e) };\n }\n}\n\n/**\n * 获取交易状态\n */\nexport async function getTransactionStatus(\n txHash: string,\n chain: string | number = 'base'\n): Promise<{\n status: 'pending' | 'confirmed' | 'failed' | 'not_found';\n blockNumber?: number;\n confirmations?: number;\n}> {\n let chainConfig: ChainConfig | undefined;\n try {\n chainConfig = typeof chain === 'number' ? getChainById(chain) : getChain(chain as ChainName);\n if (!chainConfig) return { status: 'not_found' };\n } catch {\n return { status: 'not_found' };\n }\n\n try {\n const provider = new ethers.JsonRpcProvider(chainConfig.rpc);\n const receipt = await provider.getTransactionReceipt(txHash);\n\n if (!receipt) {\n // 检查是否在 pending 池中\n const tx = await provider.getTransaction(txHash);\n if (tx) {\n return { status: 'pending' };\n }\n return { status: 'not_found' };\n }\n\n const currentBlock = await provider.getBlockNumber();\n const confirmations = currentBlock - receipt.blockNumber;\n\n if (receipt.status === 1) {\n return {\n status: 'confirmed',\n blockNumber: receipt.blockNumber,\n confirmations,\n };\n } else {\n return {\n status: 'failed',\n blockNumber: receipt.blockNumber,\n };\n }\n } catch {\n return { status: 'not_found' };\n }\n}\n\n/**\n * 等待交易确认\n */\nexport async function waitForTransaction(\n txHash: string,\n chain: string | number = 'base',\n confirmations = 1,\n timeoutMs = 60000\n): Promise<VerifyPaymentResult & { confirmed: boolean }> {\n let chainConfig: ChainConfig | undefined;\n try {\n chainConfig = typeof chain === 'number' ? getChainById(chain) : getChain(chain as ChainName);\n if (!chainConfig) {\n return { verified: false, confirmed: false, error: `不支持的链: ${chain}` };\n }\n } catch (e) {\n return { verified: false, confirmed: false, error: `不支持的链: ${chain}` };\n }\n\n const provider = new ethers.JsonRpcProvider(chainConfig.rpc);\n \n try {\n const receipt = await provider.waitForTransaction(txHash, confirmations, timeoutMs);\n \n if (!receipt) {\n return { verified: false, confirmed: false, error: '等待超时' };\n }\n\n if (receipt.status !== 1) {\n return { verified: false, confirmed: true, error: '交易失败' };\n }\n\n return {\n verified: true,\n confirmed: true,\n txHash,\n blockNumber: receipt.blockNumber,\n };\n } catch (e: any) {\n return { verified: false, confirmed: false, error: e.message || String(e) };\n }\n}\n","/**\n * Payment Guide Generator\n * Generate guides for Agents without payment capability to install and use moltspay\n */\n\nexport interface PaymentGuideParams {\n orderId: string;\n prompt: string;\n price: number;\n recipientAddress: string;\n chain?: 'base' | 'base_sepolia';\n serviceName?: string;\n}\n\n/**\n * Generate complete payment guide message\n */\nexport function generatePaymentGuide(params: PaymentGuideParams): string {\n const {\n orderId,\n prompt,\n price,\n recipientAddress,\n chain = 'base',\n serviceName = 'Video Generation Service'\n } = params;\n\n const chainId = chain === 'base' ? 8453 : 84532;\n const chainName = chain === 'base' ? 'Base Mainnet' : 'Base Sepolia Testnet';\n const explorer = chain === 'base' \n ? 'https://basescan.org/tx/' \n : 'https://sepolia.basescan.org/tx/';\n\n return `🎬 **${serviceName}**\n\n📋 **Order Details:**\n- Order ID: \\`${orderId}\\`\n- Content: ${prompt.length > 50 ? prompt.slice(0, 50) + '...' : prompt}\n- Price: **${price} USDC**\n- Chain: ${chainName}\n\n---\n\n## 💳 How to Pay\n\n### Option 1: Install moltspay SDK (Recommended)\n\n\\`\\`\\`bash\nnpm install moltspay ethers\n\\`\\`\\`\n\n**Create wallet and pay:**\n\n\\`\\`\\`javascript\nconst { SecureWallet, getChain } = require('moltspay');\nconst { Wallet } = require('ethers');\n\n// 1. Create new wallet (first time)\nconst newWallet = Wallet.createRandom();\nconsole.log('Wallet address:', newWallet.address);\nconsole.log('Private key (save securely):', newWallet.privateKey);\n\n// 2. Or use existing wallet\nconst wallet = new SecureWallet({\n chainId: ${chainId},\n privateKey: process.env.WALLET_KEY, // Your private key\n limits: { requireWhitelist: false } // Allow transfers to any address\n});\n\n// 3. Check balance\nconst balance = await wallet.getBalance();\nconsole.log('USDC balance:', balance.usdc);\n\n// 4. Pay\nconst result = await wallet.transfer('${recipientAddress}', '${price}');\nif (result.success) {\n console.log('✅ Payment successful!');\n console.log('Tx hash:', result.hash);\n // Send the tx hash to me\n}\n\\`\\`\\`\n\n### Option 2: Direct Transfer\n\nTransfer USDC from any wallet:\n- **Chain:** ${chainName} (Chain ID: ${chainId})\n- **Token:** USDC\n- **Recipient:** \\`${recipientAddress}\\`\n- **Amount:** ${price} USDC\n\n---\n\n## ✅ After Payment\n\nSend me the **transaction hash**, format:\n\\`\\`\\`\ntx: 0x1234...\n\\`\\`\\`\n\nOr just send the hash directly:\n\\`\\`\\`\n0x1234abcd...\n\\`\\`\\`\n\nI'll verify the on-chain transaction and start processing your request.\n\n---\n\n📦 **moltspay:** https://www.npmjs.com/package/moltspay\n🔗 **Block Explorer:** ${explorer}`;\n}\n\n/**\n * Generate short payment reminder\n */\nexport function generatePaymentReminder(params: {\n orderId: string;\n price: number;\n recipientAddress: string;\n chain?: 'base' | 'base_sepolia';\n}): string {\n const { orderId, price, recipientAddress, chain = 'base' } = params;\n const chainName = chain === 'base' ? 'Base' : 'Base Sepolia';\n\n return `⏳ **Pending Order: ${orderId}**\n\nPlease pay **${price} USDC** to:\n- Chain: ${chainName}\n- Address: \\`${recipientAddress}\\`\n\nSend the tx hash after payment.\n\n---\n💡 No payment capability? Run \\`npm install moltspay\\` to get the payment SDK`;\n}\n\n/**\n * Generate wallet creation guide\n */\nexport function generateWalletGuide(): string {\n return `## 🔐 Create Payment Wallet\n\n**1. Install moltspay:**\n\\`\\`\\`bash\nnpm install moltspay ethers\n\\`\\`\\`\n\n**2. Create new wallet:**\n\\`\\`\\`javascript\nconst { Wallet } = require('ethers');\n\nconst wallet = Wallet.createRandom();\nconsole.log('Address:', wallet.address);\nconsole.log('Private key:', wallet.privateKey);\n// ⚠️ Save the private key securely!\n\\`\\`\\`\n\n**3. Get USDC:**\n- Mainnet: Withdraw from exchange to your wallet\n- Testnet: Use Base Sepolia faucet\n\n**4. Set environment variable:**\n\\`\\`\\`bash\nexport WALLET_KEY=\"your_private_key\"\n\\`\\`\\`\n\nYou're now ready to make on-chain payments with moltspay!`;\n}\n\n/**\n * Extract transaction hash from user message\n */\nexport function extractTransactionHash(message: string): string | null {\n // Match 0x followed by 64 hex chars\n const match = message.match(/0x[a-fA-F0-9]{64}/);\n if (match) return match[0];\n\n // Match tx: followed by content\n const txMatch = message.match(/tx:\\s*([a-fA-F0-9]{64})/i);\n if (txMatch) return '0x' + txMatch[1];\n\n return null;\n}\n\n/**\n * Check if message contains transaction hash\n */\nexport function hasTransactionHash(message: string): boolean {\n return extractTransactionHash(message) !== null;\n}\n","/**\n * Receipt - Transaction receipt generation\n * \n * Generate standardized transaction receipts for reconciliation/reimbursement/audit\n */\n\nimport { getChain } from '../chains/index.js';\nimport type { ChainName, Invoice, VerifyResult } from '../types/index.js';\n\nexport interface ReceiptParams {\n /** Invoice ID (auto-generated or specified) */\n invoiceId?: string;\n /** Order ID */\n orderId: string;\n /** Service name */\n service: string;\n /** Service description */\n description?: string;\n /** Amount */\n amount: number;\n /** Token */\n token?: 'USDC' | 'USDT' | 'ETH';\n /** Chain */\n chain: ChainName;\n /** Transaction hash */\n txHash: string;\n /** Payer address */\n payerAddress: string;\n /** Recipient address */\n recipientAddress: string;\n /** Delivery info */\n delivery?: {\n /** Delivery URL */\n url?: string;\n /** File hash */\n fileHash?: string;\n /** Delivery timestamp */\n deliveredAt?: string;\n };\n /** Additional metadata */\n metadata?: Record<string, unknown>;\n}\n\nexport interface Receipt {\n type: 'receipt';\n version: '1.0';\n /** Invoice ID */\n invoiceId: string;\n /** Order ID */\n orderId: string;\n /** Service */\n service: string;\n description?: string;\n /** Amount */\n amount: string;\n token: string;\n /** Chain info */\n chain: string;\n chainId: number;\n /** Transaction info */\n txHash: string;\n txUrl: string;\n /** Parties */\n payer: string;\n recipient: string;\n /** Timestamps */\n paidAt: string;\n issuedAt: string;\n /** Delivery info */\n delivery?: {\n url?: string;\n fileHash?: string;\n deliveredAt?: string;\n };\n /** Additional metadata */\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Generate invoice ID\n */\nfunction generateInvoiceId(): string {\n const date = new Date().toISOString().slice(0, 10).replace(/-/g, '');\n const random = Math.random().toString(36).slice(2, 8).toUpperCase();\n return `INV-${date}-${random}`;\n}\n\n/**\n * Generate transaction receipt\n */\nexport function generateReceipt(params: ReceiptParams): Receipt {\n const chainConfig = getChain(params.chain);\n \n return {\n type: 'receipt',\n version: '1.0',\n invoiceId: params.invoiceId || generateInvoiceId(),\n orderId: params.orderId,\n service: params.service,\n description: params.description,\n amount: params.amount.toFixed(2),\n token: params.token || 'USDC',\n chain: chainConfig.name,\n chainId: chainConfig.chainId,\n txHash: params.txHash,\n txUrl: `${chainConfig.explorerTx}${params.txHash}`,\n payer: params.payerAddress,\n recipient: params.recipientAddress,\n paidAt: new Date().toISOString(),\n issuedAt: new Date().toISOString(),\n delivery: params.delivery,\n metadata: params.metadata,\n };\n}\n\n/**\n * Generate receipt from Invoice + VerifyResult\n */\nexport function generateReceiptFromInvoice(\n invoice: Invoice,\n verifyResult: VerifyResult,\n delivery?: ReceiptParams['delivery']\n): Receipt {\n if (!verifyResult.verified || !verifyResult.tx_hash) {\n throw new Error('Cannot generate receipt: payment not verified');\n }\n\n return generateReceipt({\n orderId: invoice.order_id,\n service: invoice.service,\n description: invoice.description,\n amount: parseFloat(invoice.amount),\n token: invoice.token as 'USDC' | 'USDT' | 'ETH',\n chain: invoice.chain as ChainName,\n txHash: verifyResult.tx_hash,\n payerAddress: verifyResult.from || 'unknown',\n recipientAddress: invoice.recipient,\n delivery,\n });\n}\n\n/**\n * Format receipt as human-readable message (Markdown)\n */\nexport function formatReceiptMessage(receipt: Receipt): string {\n let msg = `🧾 **Transaction Receipt**\n\n**Invoice:** \\`${receipt.invoiceId}\\`\n**Order:** \\`${receipt.orderId}\\`\n\n---\n\n**Service:** ${receipt.service}\n${receipt.description ? `**Description:** ${receipt.description}\\n` : ''}\n**Amount:** ${receipt.amount} ${receipt.token}\n**Chain:** ${receipt.chain} (Chain ID: ${receipt.chainId})\n\n---\n\n**Payer:** \\`${receipt.payer}\\`\n**Recipient:** \\`${receipt.recipient}\\`\n**Transaction:** [\\`${receipt.txHash.slice(0, 10)}...${receipt.txHash.slice(-8)}\\`](${receipt.txUrl})\n**Paid at:** ${receipt.paidAt}`;\n\n if (receipt.delivery) {\n msg += `\\n\\n---\\n\\n**Delivery Info:**`;\n if (receipt.delivery.url) {\n msg += `\\n- Download: ${receipt.delivery.url}`;\n }\n if (receipt.delivery.fileHash) {\n msg += `\\n- Checksum: \\`${receipt.delivery.fileHash}\\``;\n }\n if (receipt.delivery.deliveredAt) {\n msg += `\\n- Delivered at: ${receipt.delivery.deliveredAt}`;\n }\n }\n\n msg += `\\n\\n---\\n\\n_Receipt issued: ${receipt.issuedAt}_`;\n\n return msg;\n}\n\n/**\n * Format receipt as plain text (for Feishu/WhatsApp)\n */\nexport function formatReceiptText(receipt: Receipt): string {\n let msg = `🧾 Transaction Receipt\n\nInvoice: ${receipt.invoiceId}\nOrder: ${receipt.orderId}\n\nService: ${receipt.service}\nAmount: ${receipt.amount} ${receipt.token}\nChain: ${receipt.chain}\n\nPayer: ${receipt.payer}\nRecipient: ${receipt.recipient}\nTx: ${receipt.txHash}\nExplorer: ${receipt.txUrl}\nPaid at: ${receipt.paidAt}`;\n\n if (receipt.delivery) {\n msg += `\\n\\nDelivery:`;\n if (receipt.delivery.url) {\n msg += `\\nDownload: ${receipt.delivery.url}`;\n }\n if (receipt.delivery.fileHash) {\n msg += `\\nChecksum: ${receipt.delivery.fileHash}`;\n }\n }\n\n return msg;\n}\n\n/**\n * Format receipt as JSON (for Agent parsing)\n */\nexport function formatReceiptJson(receipt: Receipt): string {\n return JSON.stringify(receipt, null, 2);\n}\n","/**\n * Agent Conversation Templates\n * \n * Standardized Agent-to-Agent payment conversation templates\n * Can be embedded in prompts or used for dialogue generation\n */\n\nimport { getChain } from '../chains/index.js';\nimport type { ChainName } from '../types/index.js';\nimport { Receipt } from '../receipt/index.js';\n\n// ============ Seller Templates ============\n\nexport const SellerTemplates = {\n /**\n * 1. Capability Check - Ask if buyer has payment capability\n */\n askPaymentCapability(): string {\n return `Sure. First, let me confirm: do you currently have the ability to pay USDC on-chain (have a wallet and available funds/allowance)?`;\n },\n\n /**\n * 2. Settlement Method - Explain how we settle\n */\n explainSettlement(chain: ChainName = 'base'): string {\n const chainConfig = getChain(chain);\n return `Our settlement method is: USDC (on-chain, ${chainConfig.name}). You just need two things:\n1) A wallet address;\n2) USDC in your wallet, or a spending allowance from your owner (allowance is recommended).\nCan you follow my guidance to set this up?`;\n },\n\n /**\n * 3.1 Installation Guide - First step: install SDK\n */\n guideInstall(): string {\n return `Step 1: Install the payment module in your environment. Run: \\`npm install moltspay ethers\\`.\nAfter installation, create a wallet address and send it to me (address only, never send private key/mnemonic).`;\n },\n\n /**\n * 3.2 Confirm Wallet Address\n */\n confirmWalletAddress(address: string): string {\n return `Got it. Reminder: never send your private key/mnemonic to anyone (including me).\nYour wallet address is \\`${address}\\`.\nStep 2: You need your owner (Boss) to give you payment capability.`;\n },\n\n /**\n * 3.3 Funding Options - Choose method\n */\n guideFunding(): string {\n return `You now have two ways to get payment capability:\nA) Have Boss transfer USDC directly to your wallet (simple, but you'll hold the funds);\nB) Have Boss give you a \"USDC spending allowance\" (recommended: you don't hold funds, can only pay within the allowance).\nWhich works better for you?`;\n },\n\n /**\n * 3.4 Guide Permit Authorization\n */\n guidePermit(agentAddress: string, suggestedAmount: number = 10): string {\n return `OK. Please send this message to your Boss (you can copy it directly):\n\"I need a USDC spending allowance (Permit) for purchasing services. Please authorize ${suggestedAmount} USDC to my wallet ${agentAddress}, valid for 24 hours.\"\nLet me know when you've received the allowance.`;\n },\n\n /**\n * 3.5 Confirm Capability Ready\n */\n confirmCapabilityReady(): string {\n return `Great. You now have the payment capability to complete transactions. Let's confirm your service requirements.`;\n },\n\n /**\n * 4. Ask Service Requirements\n */\n askServiceRequirements(serviceName: string = 'video'): string {\n return `Please tell me your ${serviceName} specifications: theme/style, duration, resolution, subtitles or voiceover needed?`;\n },\n\n /**\n * 5. Quote\n */\n quote(params: {\n service: string;\n price: number;\n recipientAddress: string;\n chain?: ChainName;\n }): string {\n const { service, price, recipientAddress, chain = 'base' } = params;\n const chainConfig = getChain(chain);\n return `Quote:\n- Service: ${service}\n- Price: ${price} USDC\n- Chain: ${chainConfig.name}\n- Recipient: \\`${recipientAddress}\\`\n- After payment, send me the transaction hash (tx hash) for on-chain verification\n\nDo you confirm the purchase and pay now?`;\n },\n\n /**\n * 7. Verifying\n */\n verifying(): string {\n return `I'm verifying the transaction on-chain to confirm receipt and amount.`;\n },\n\n /**\n * 7. Verification Passed\n */\n verificationPassed(amount: string): string {\n return `Verification passed: received ${amount} USDC. Starting to process your request now.\n[status:payment_confirmed]`;\n },\n\n /**\n * 7. Verification Failed\n */\n verificationFailed(error: string): string {\n return `Verification failed: ${error}\nPlease check if the transaction is correct, or resend the correct tx hash.`;\n },\n\n /**\n * 8. Delivery\n */\n deliver(params: {\n downloadUrl: string;\n fileHash?: string;\n }): string {\n const { downloadUrl, fileHash } = params;\n let msg = `Service completed. Delivery details:\n- Download link: ${downloadUrl}`;\n if (fileHash) {\n msg += `\\n- File checksum: SHA256=${fileHash}`;\n }\n msg += `\\n\\nLet me know if you have any download issues, I'll provide a backup link.\n[status:delivered]`;\n return msg;\n },\n\n /**\n * 9. Receipt\n */\n receipt(receipt: Receipt): string {\n return `Here's your transaction receipt (you can forward to Boss for reconciliation):\n- Invoice: ${receipt.invoiceId}\n- Service: ${receipt.service}\n- Amount: ${receipt.amount} ${receipt.token}\n- Tx Hash: ${receipt.txHash}\n- Recipient: ${receipt.recipient}\n${receipt.delivery?.url ? `- Delivery: ${receipt.delivery.url}` : ''}\n[status:receipt_issued invoice=${receipt.invoiceId}]`;\n },\n\n /**\n * 10. End\n */\n end(): string {\n return `Thank you for your purchase. This transaction is complete. Feel free to reach out if you need modifications or new services.`;\n },\n};\n\n// ============ Buyer Templates ============\n\nexport const BuyerTemplates = {\n /**\n * 0. Request Service\n */\n requestService(service: string): string {\n return `I'd like to purchase a ${service} service.`;\n },\n\n /**\n * 1. No Capability\n */\n noCapability(): string {\n return `I'm not sure. I currently don't have any payment tools installed, and no wallet.`;\n },\n\n /**\n * 1. Has Capability\n */\n hasCapability(balance?: string): string {\n return `Yes, I have a wallet and available USDC${balance ? ` (balance: ${balance})` : ''}.`;\n },\n\n /**\n * 2. Agree to Guide\n */\n agreeToGuide(): string {\n return `Sure, please guide me.`;\n },\n\n /**\n * 3.1 Report Wallet Created\n */\n walletCreated(address: string): string {\n return `I've created my wallet address: ${address}.\n[status:wallet_ready]`;\n },\n\n /**\n * 3.3 Choose Permit Method\n */\n choosePermit(): string {\n return `I choose B: have Boss give me an allowance (Permit).`;\n },\n\n /**\n * 3.3 Choose Direct Transfer\n */\n chooseDirectTransfer(): string {\n return `I choose A: have Boss transfer USDC directly to my wallet.`;\n },\n\n /**\n * 3.4 Report Permit Received\n */\n permitReceived(amount: number): string {\n return `Boss has completed the authorization. I now have ${amount} USDC allowance.\n[status:permit_ready USDC=${amount}]`;\n },\n\n /**\n * 4. Submit Requirements\n */\n submitRequirements(requirements: string): string {\n return `Requirements:\n${requirements}`;\n },\n\n /**\n * 5. Confirm Purchase\n */\n confirmPurchase(): string {\n return `Confirmed. I'll pay now.`;\n },\n\n /**\n * 6. Report Payment Sent\n */\n paymentSent(txHash: string, amount: number): string {\n return `Payment complete. Transaction hash: ${txHash}.\n[status:payment_sent tx=${txHash} amount=${amount} USDC]`;\n },\n\n /**\n * 8. Confirm Delivery Received\n */\n deliveryReceived(): string {\n return `Received, I'm downloading and checking now.`;\n },\n\n /**\n * 9. Confirm Receipt\n */\n receiptReceived(): string {\n return `Receipt received, service complete. Thanks!`;\n },\n\n /**\n * Request Permit from Boss\n */\n requestPermitFromBoss(params: {\n amount: number;\n agentAddress: string;\n deadlineHours?: number;\n reason?: string;\n }): string {\n const { amount, agentAddress, deadlineHours = 24, reason } = params;\n return `Boss, I need a USDC spending allowance (Permit) for ${reason || 'purchasing services'}.\nPlease authorize ${amount} USDC to my wallet ${agentAddress}, valid for ${deadlineHours} hours.`;\n },\n};\n\n// ============ Status Markers ============\n\nexport const StatusMarkers = {\n walletReady: '[status:wallet_ready]',\n permitReady: (amount: number) => `[status:permit_ready USDC=${amount}]`,\n paymentSent: (txHash: string, amount: number) => `[status:payment_sent tx=${txHash} amount=${amount} USDC]`,\n paymentConfirmed: (txHash: string) => `[status:payment_confirmed tx=${txHash}]`,\n delivered: (url: string, hash?: string) => `[status:delivered url=${url}${hash ? ` hash=${hash}` : ''}]`,\n receiptIssued: (invoiceId: string, txHash: string) => `[status:receipt_issued invoice=${invoiceId} tx=${txHash}]`,\n};\n\n// ============ Status Parser ============\n\nexport function parseStatusMarker(message: string): {\n type: string;\n data: Record<string, string>;\n} | null {\n const match = message.match(/\\[status:([^\\]]+)\\]/);\n if (!match) return null;\n\n const content = match[1];\n \n // Parse different status types\n if (content === 'wallet_ready') {\n return { type: 'wallet_ready', data: {} };\n }\n \n if (content.startsWith('permit_ready')) {\n const amountMatch = content.match(/USDC=(\\d+(?:\\.\\d+)?)/);\n return { \n type: 'permit_ready', \n data: { amount: amountMatch?.[1] || '0' } \n };\n }\n \n if (content.startsWith('payment_sent')) {\n const txMatch = content.match(/tx=(\\S+)/);\n const amountMatch = content.match(/amount=(\\d+(?:\\.\\d+)?)/);\n return {\n type: 'payment_sent',\n data: {\n txHash: txMatch?.[1] || '',\n amount: amountMatch?.[1] || '0',\n },\n };\n }\n \n if (content.startsWith('payment_confirmed')) {\n const txMatch = content.match(/tx=(\\S+)/);\n return {\n type: 'payment_confirmed',\n data: { txHash: txMatch?.[1] || '' },\n };\n }\n \n if (content.startsWith('delivered')) {\n const urlMatch = content.match(/url=(\\S+)/);\n const hashMatch = content.match(/hash=(\\S+)/);\n return {\n type: 'delivered',\n data: {\n url: urlMatch?.[1] || '',\n hash: hashMatch?.[1] || '',\n },\n };\n }\n \n if (content.startsWith('receipt_issued')) {\n const invoiceMatch = content.match(/invoice=(\\S+)/);\n const txMatch = content.match(/tx=(\\S+)/);\n return {\n type: 'receipt_issued',\n data: {\n invoiceId: invoiceMatch?.[1] || '',\n txHash: txMatch?.[1] || '',\n },\n };\n }\n\n return { type: 'unknown', data: { raw: content } };\n}\n"],"mappings":"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","names":["import_ethers","import_ethers","path","import_ethers","import_ethers","import_crypto","import_ethers"]}