内容
# 支出树
支出树是一款本地的、非托管的预算树和飞行记录器,适用于进行真实x402支付的代理。
它不是一个模拟账本或测试网络演示。支付路径创建真实的EIP-3009 USDC授权,适用于Base主网,并将其发送给真实的x402商家。钱包属于用户,资金直接结算给商家,支出树从不持有任一方的资金。
> 状态:预alpha版。在安全表面被加强之前,请仅使用专用的、低余额钱包。
## 当前功能
- x402 v2 `exact`支付
- Base主网(`eip155:8453`)
- 原生USDC(仅限规范)
- 一个一次性签名者,接受预留的EIP-3009类型数据
- 精确的HTTPS源、路径、HTTP方法和接收地址策略
- 分层、过期的代理配额
- 原子祖先预留,防止并发超支
- 根作用域的幂等性和保守的模糊结算处理
- 数据库到钱包的绑定,防止在错误签名者下记账
- SQLite审计跟踪,包含报价、签名有效载荷、随机数、交易哈希、响应哈希和代理祖先
- Base收款验证,同时检查精确的规范USDC `Transfer`和签名EIP-3009 `AuthorizationUsed`随机数
- 本地Unix套接字守护进程、强制绑定MCP适配器和CLI烟雾路径
不在v0中:任意代币转账、兑换、`upto`、批量结算、订阅、法定货币/卡支付、充值、退款、托管或商家交付保证。
## 架构
```text
代理
│ 标准输入输出MCP(作用域能力;无钱包密钥)
▼
支出树MCP适配器
│ 身份验证JSON,基于Unix套接字0600
▼
支出树守护进程
├─ 策略 + 分层预算引擎
├─ SQLite预留/尝试账本
├─ 受限的一次性EIP-3009签名者
└─ 受保护的x402 HTTP握手
│
▼
商家促进者 ──▶ Base USDC结算
```
守护进程将预留转换为已提交的支出,并在传输`PAYMENT-SIGNATURE`之前持久化签名有效载荷。在此之后,超时、丢失的收款或商家错误永远不会释放预算:商家仍可以在授权过期之前结算。
## 从GitHub安装
要求:Node.js 24或更新版本。
```sh
npm install --global github:bilalxashraf/spendtree
spendtree --help
```
GitHub安装会在本地构建CLI和MCP适配器。要从克隆版本开发,请运行`npm ci`、`npm run check`和`npm run build`。所有安全敏感的依赖版本都在`package.json`和`package-lock.json`中固定。
## 十分钟真实支付金丝雀
此路径调用Exa的实时x402网络搜索API,位于Base主网。2026年7月18日,其未签名的报价为0.007 USDC至`0x6d6E695b09861467c7d462f5AAF31cF3540B9192`。检查的策略最多允许每次调用0.01 USDC,如果接收者或价格发生变化,则失败关闭。
下载狭窄的示例策略并创建一份在一小时内过期的授权:
```sh
curl --fail --output exa-policy.json \
https://raw.githubusercontent.com/bilalxashraf/spendtree/main/config/policy.exa.example.json
spendtree init exa-policy.json --ttl-minutes 60
```
保存`init`打印的能力。创建或导出一个**专用**EOA,然后打印其地址并用Base上的少量USDC资助它。不要使用主钱包。
```sh
SPENDTREE_PRIVATE_KEY=0x... spendtree address
SPENDTREE_PRIVATE_KEY=0x... spendtree daemon
```
保持守护进程运行。在另一个终端中,使用能力但不向客户端进程公开钱包密钥,进行有用的付费搜索:
```sh
SPENDTREE_CAPABILITY=st_cap_... \
spendtree pay \
'https://api.exa.ai/search' \
'exa-canary-001' \
'Find current primary sources about agent payment controls' \
--json '{"query":"agent payment controls x402","numResults":3}'
```
再次运行相同的命令。支出树返回存储的响应,带有`"replayed": true`,并且不会两次签名或支付。检查已验证的Base交易和剩余的额度:
```sh
SPENDTREE_CAPABILITY=st_cap_... spendtree summary
```
这是用户资助的真实主网调用。项目维护者不补贴购买、不持有资金,也不接收商家付款。
## 从源克隆配置另一个商家
复制`config/policy.example.json`,然后将源地址和`payTo`地址替换为真实的x402商家。金额是原子的USDC单位:`1000000`是1 USDC。
```sh
cp config/policy.example.json config/policy.json
# 编辑config/policy.json后再继续。
spendtree init config/policy.json --ttl-minutes 60
```
`init`打印一个根能力一次。支出树只存储其SHA-256哈希;将原始能力保存在密码管理器或其他秘密存储中。
## 启动支付守护进程
用Base上的USDC资助一个专用的EOA。标准的EIP-3009支付不需要买方钱包持有ETH;商家的促进者提交交易。
在与代理不同的终端或服务环境中启动守护进程。不要将钱包密钥放在MCP进程中:
```sh
SPENDTREE_PRIVATE_KEY=0x... spendtree daemon
```
环境变量是初始的开发人员密钥提供者。保持守护进程和MCP环境分开;为每个环境提供示例文件。在稳定版本之前,计划使用加密的密钥库/原生密钥链提供程序。
## 从CLI进行真实支付
守护进程运行时,使用根或子能力:
```sh
SPENDTREE_CAPABILITY=st_cap_... \
spendtree pay \
'https://merchant.example/paid/resource' \
'smoke-001' \
'Buy the merchant resource for the initial smoke test'
```
对于POST资源,请追加`--json '{"key":"value"'`。也支持`--text`和显式`--method GET|POST`。
这是主网操作。如果报价满足授权,真实的USDC可以从配置的钱包转移。
检查配额和飞行记录:
```sh
SPENDTREE_CAPABILITY=st_cap_... spendtree summary
```
## 连接MCP代理
为每个代理/授权运行一个适配器。适配器内部附加其能力;代理无法在工具参数中选择不同的授权。
```json
{
"mcpServers": {
"spendtree": {
"command": "spendtree-mcp",
"args": [],
"env": {
"SPENDTREE_SOCKET": "/absolute/path/to/home/.spendtree/spendtree.sock",
"SPENDTREE_CAPABILITY": "st_cap_..."
}
}
}
}
```
将套接字路径替换为守护进程的路径;默认路径为`~/.spendtree/spendtree.sock`。对于仅源安装,请将`command`设置为`node`,将`args`设置为`dist/mcp.js`的绝对路径。
MCP表面暴露`paid_fetch`、`get_spend_tree`、`delegate_budget`和`revoke_child`。它不暴露通用签名或代币转移操作。
## 重要限制
- EIP-3009在密码学上绑定了付款人、收款人、金额、有效性窗口、随机数、代币和链。它**不**绑定HTTP方法、URL、正文或商家交付。支出树在本地强制执行和记录该关系。
- `PAYMENT-RESPONSE`是促进者/商家报告,而不是签名的收款。支出树通过RPC验证Base交易收款、精确的USDC `Transfer`和匹配的EIP-3009 `AuthorizationUsed`随机数。当RPC暂时不可用时,已交付的结果作为`reported_settled`保留,`onchainVerified: false`而不是被错误标记为已确认。
- 具有无限制shell/文件系统访问权限的同一OS用户代理可以绕过Unix套接字能力边界。对于该威胁模型,请使用单独的OS用户/容器。专用的低余额钱包是硬v0损失上限。
- 子限制是分层配额,而不是划分的国库分配。每次支付都会消耗其叶配额和所有祖先配额。
在钱包中放置资金之前,请查看[SECURITY.md](SECURITY.md)。
## 开发
```sh
npm run typecheck
npm test
npm run build
```
测试使用真实的EIP-3009签名实现对抗模拟的HTTP传输。它们不广播交易或使用假余额。
## 许可证
MIT