内容
# 收费站 DPYC
[](https://opensource.org/licenses/Apache-2.0)
[](https://pypi.org/project/tollbooth-dpyc/)
[](https://www.python.org/downloads/)
<p align="center">
<img src="https://raw.githubusercontent.com/lonniev/tollbooth-dpyc/main/docs/tollbooth-hero.png" alt="Milo drives the Lightning Turnpike — Don't Pester Your Customer" width="800">
</p>
**不要打扰你的客户** — 面向 MCP 服务器的比特币闪电网络微支付。
**专利待批** — 美国临时申请 64/045,999
> *本项目的隐喻灵感来自诺顿·贾斯特(Norton Juster)的《魔幻收费站》(The Phantom Tollbooth),插图由朱尔斯·费弗(Jules Feiffer)绘制(1961年)。米洛、托克、收费站、词典城和数字城都是贾斯特先生非凡想象力的创造。我们只是构建了支付基础设施。*
---
## 问题
数千名开发者正在构建 [MCP](https://modelcontextprotocol.io/) 服务器——这些服务允许 AI 代理与世界交互。知识图谱、金融数据、社交媒体、医疗记录。每个都是地图上的一座城市。但城市之间的收费公路呢?敞开大开。没有收费员。没有可持续的经济。
每个 MCP 运营商都面临着同样的问题:*我如何维持运营?*
传统的 API 密钥和月度计费?您现在正在经营一个 SaaS 公司。L402 - 面向闪电网络的原生按需付费?每个 API 调用都需要进行支付协商。米洛的玩具车在每个路口都停下来,寻找零钱。
## 解决方案
收费站 DPYC 采用了一种不同的方法——一种尊重每个人时间的的方法:
**米洛开车来到收费站,购买一批代币,支付一次闪电网络发票,然后开车离开。** 没有停车。没有谈判。没有按请求计费的摩擦。代币在后台悄悄减少。当代币数量减少时,他再购买一批。收费公路保持畅通。
基于比特币闪电网络的预付信用额度,在工具层面上进行控制,实时结算,无需订阅管理,也无需第三方支付处理器抽取佣金。
---
## 快速入门:5 分钟内搭建一个运营商
规范的参考运营商是 [tollbooth-sample](https://github.com/lonniev/tollbooth-sample)。每个生产运营商都遵循此模式。
### 1. 安装
```bash
pip install "tollbooth-dpyc[nostr]" fastmcp
```
### 2. 定义您的工具
```python
from fastmcp import FastMCP
from tollbooth.tool_identity import ToolIdentity, STANDARD_IDENTITIES, capability_uuid
from tollbooth.runtime import OperatorRuntime, register_standard_tools
from tollbooth.credential_templates import CredentialTemplate, FieldSpec
mcp = FastMCP("我的服务")
# 领域工具 - 您的服务实际执行的操作
_DOMAIN_TOOLS = [
ToolIdentity(capability="get_weather", category="read", intent="当前天气数据"),
ToolIdentity(capability="get_forecast", category="read", intent="5 天预报"),
]
TOOL_REGISTRY = {t.id: t for t in _DOMAIN_TOOLS}
```
### 3. 创建运行时
```python
runtime = OperatorRuntime(
tool_registry={**STANDARD_IDENTITIES, **TOOL_REGISTRY},
operator_credential_template=CredentialTemplate(
service="我的运营商",
fields={
"btcpay_host": FieldSpec(required=True, sensitive=False, description="BTCPay 服务器 URL"),
"btcpay_api_key": FieldSpec(required=True, sensitive=True, description="BTCPay API 密钥"),
"btcpay_store_id": FieldSpec(required=True, sensitive=True, description="BTCPay 商店 ID"),
},
),
service_name="我的天气服务",
)
```
### 4. 注册标准工具 + 领域工具
```python
# 此单个调用注册了所有 26+ 个标准 DPYC 工具,并返回
# 带有斜杠前缀的 @tool 装饰器,用于运营商自己的付费工具。
tool = register_standard_tools(mcp, "weather", runtime,
service_name="my-weather-service",
service_version="1.0.0",
)
@tool
@runtime.paid_tool(capability_uuid("get_weather"))
async def get_weather(city: str, npub: str = "", proof: str = "") -> dict:
"""获取某城市的当前天气。费用为 1 api_sat。"""
# 您的领域逻辑在此
return {"city": city, "temp": 72, "conditions": "sunny"}
```
### 5. 部署
设置一个环境变量并部署:
```bash
export TOLLBOOTH_NOSTR_OPERATOR_NSEC=nsec1...
fastmcp run server.py
```
就是这样。运行时会从权限方通过加密的 Nostr DM 自举其他所有内容。
---
## 工作原理
### 部署流程
1. **设置 `TOLLBOOTH_NOSTR_OPERATOR_NSEC`** - 运营商的 Nostr 私钥。这是启动时唯一需要的秘密。
2. **运行时从权限方自举** - 通过 Nostr 中继上的加密 DM,发现其 Neon Postgres URL,由上游权限方签名。
3. **Vault 初始化** - Neon Postgres 上的 AES-256-GCM 加密凭证和账本存储,按运营商隔离(`op_{hash}`)。
4. **通过安全快递交付运营商凭证** - BTCPay 连接详细信息通过加密的 Nostr DM 到达(人为干预,从不通过环境变量)。
5. **配置定价** - 通过 Pricing Studio iOS 应用或 `set_pricing_model` 工具设置定价模型。
6. **服务** - 赞助商通过闪电网络购买积分,使用工具,积分自动减少。
### 信用生命周期
1. **赞助商调用 `purchase_credits`** - 运营商获得权限证书(Schnorr 签名的 Nostr 事件)并创建闪电网络发票。
2. **赞助商支付** 闪电网络发票 - 使用任何钱包。
3. **赞助商调用 `check_payment`** - 结算后,积分作为一个批次添加,可选过期时间(`TrancheLifetime`)。
4. **赞助商使用工具** - `debit_or_deny` 控制每个付费工具调用:验证身份、证明、约束、定价和扣除余额。FIFO 批次消费。
5. **余额不足** - 赞助商购买更多积分。无需订阅,无需中断。
### 认证费层级
当赞助商购买积分时,运营商的上游权限方从运营商的预 funded 储备中扣除一小笔认证费(默认 2%,最低 10 sats)。赞助商始终收到他们支付的确切积分 - 费用是运营商的经营成本。
每个权限方都是其上游权限方的运营商 - 相同的费用层级通过链条逐级传递给主要权限方。
### 工具命名:capability vs runtime name
轮子注册的每个工具都有三个标识符,并且只有一个标识符跨服务器边界。
| 标识符 | 示例 | 范围 | 用途 |
|---|---|---|---|
| `capability` | `"check_balance"` | **仅内部** | Python 函数标识符;UUID 的种子。允许一个 slug 重命名,以保留 Neon 定价行。 |
| `mcp_name` / 运行时名称 | `"weather_check_balance"` | **外部** | 线上工具名称,定价模型 `tool_name`,身份证明 `u` 标签,审计日志。唯一的外部标识符。 |
| `tool_id` | capability 的 UUID5 | 内部 | Neon 定价键。跨 slug 重命名保持稳定。 |
在需要跨进程引用标准工具时使用 `rt.runtime_name("check_balance")` 。能力名称永远不会出现在线路上。
---
## 标准工具
`register_standard_tools(mcp, slug, runtime)` 注册这些工具,带有运营商的 slug 前缀(例如 `weather_check_balance`),并返回带有斜杠前缀的 `@tool` 装饰器,用于运营商自己的付费工具:
### 信用和计费(始终注册)
| 工具 | 费用 | 用途 |
|------|------|---------|
| `check_balance` | 免费 | 当前信用余额、批次、用法总结 |
| `purchase_credits` | 免费 | 为信用购买创建闪电网络发票 |
| `check_payment` | 免费 | 轮询发票状态;结算时的信用余额 |
| `check_price` | 免费 | 预览工具调用的有效成本(在约束之后) |
| `restore_credits` | 免费 | 从丢失到缓存问题的付费发票中恢复信用 |
| `account_statement` | 免费 | 30 天的购买和用法历史 |
| `account_statement_infographic` | 1 sat | 账户声明的 SVG 可视化 |
### 身份和生命周期
| 工具 | 费用 | 用途 |
|------|------|---------|
| `service_status` | 免费 | 运营商健康状况、生命周期状态、版本信息 |
| `session_status` | 免费 | 运营商准备就绪状态:ready / warming_up / not_registered / no_identity |
| `get_operator_onboarding_status` | 免费 | 已配置与缺失的运营商凭证 |
| `get_patron_onboarding_status` | 免费 | 已配置与缺失的赞助商凭证 |
### 安全快递(凭证交换)
| 工具 | 费用 | 用途 |
|------|------|---------|
| `request_credential_channel` | 免费 | 向赞助商或运营商发送凭证模板 DM |
| `receive_credentials` | 免费 | 从保险库(即时)或中继(DM)获取凭证 |
| `forget_credentials` | 免费 | 删除服务的保险库凭证 |
### Npub 证明
| 工具 | 费用 | 用途 |
|------|------|---------|
| `request_npub_proof` | 免费 | 向赞助商发送证明挑战 DM |
| `receive_npub_proof` | 免费 | 验证赞助商的 Schnorr 签名证明响应 |
### 权限余额
| 工具 | 费用 | 用途 |
|------|------|---------|
| `check_authority_balance` | 免费 | 上游权限的认证卫星余额 |
### 预言机委托
| 工具 | 费用 | 用途 |
|------|------|---------|
| `<slug>_oracle_*` | 免费 | 对 DPYC 预言机的委托调用(社区信息、税率、成员资格)。从 v0.24.1 开始安装在操作者的 slug 下 - 例如 `schwab_oracle_about`,`brain_oracle_how_to_join`。在给定的操作者上保持每个线暴露的工具在一个单独的 slug 前缀下。 |
### 定价模型
| 工具 | 费用 | 用途 |
|------|------|---------|
| `get_pricing_model` | 免费 | 具有工具注册和约束的当前定价模型 |
| `set_pricing_model` | 免费 | 更新定价模型(运营商限制,需要证明) |
| `list_constraint_types` | 免费 | 可用的约束类型及其参数 |
### OpenTimestamps(当 `ots_enabled=True` 时)
| 工具 | 费用 | 用途 |
|------|------|---------|
| `notarize_ledger` | 免费 | 通过 Merkle 树 + OTS 将账本状态锚定到比特币 |
| `get_notarization_proof` | 免费 | 特定赞助商的 Merkle 包含证明 |
| `list_notarizations` | 免费 | 所有比特币锚定的账本快照 |
### 条件工具
| 工具 | 条件 | 用途 |
|------|-----------|---------|
| `request_patron_credentials` | 设置 `patron_credential_template` | 为赞助商特定凭证打开快递通道 |
| `receive_patron_credentials` | 设置 `patron_credential_template` | 领取赞助商凭证 |
| `begin_oauth` | 设置 `oauth_provider` | 启动 OAuth2 授权流程 |
| `check_oauth_status` | 设置 `oauth_provider` | 在浏览器授权后完成 OAuth2 流程 |
| `update_patron_credential` | 设置 `patron_credential_template` | 添加或更新单个赞助商凭证字段 |
| `delete_patron_credential` | 设置 `patron_credential_template` | 删除单个赞助商凭证字段 |
| `get_patron_credential_fields` | 设置 `patron_credential_template` | 列出存储的赞助商凭证字段名称 |
---
## 权限扩展(`tollbooth.authority`)
权限 MCP - 认证运营商采购订单的机构 - 获得自己的协议表面,镜像 `register_standard_tools` 为运营商。自 v0.22.0 起,完整的权限工具集位于轮子的 `tollbooth.authority` 下,并通过一个调用安装到 FastMCP 应用中:
```python
from fastmcp import FastMCP
from tollbooth.authority import (
AUTHORITY_TOOL_REGISTRY,
OPERATOR_CREDENTIAL_TEMPLATE,
register_authority_tools,
)
from tollbooth.runtime import OperatorRuntime, register_standard_tools
from tollbooth.tool_identity import STANDARD_IDENTITIES
mcp = FastMCP("tollbooth-authority-mine", instructions="…")
runtime = OperatorRuntime(
tool_registry={**STANDARD_IDENTITIES, **AUTHORITY_TOOL_REGISTRY},
vault_source="env", # 权限方自我配置 Neon
purchase_mode="auto", # 从注册链中派生直接/认证
ots_enabled=True,
operator_credential_template=OPERATOR_CREDENTIAL_TEMPLATE,
)
register_standard_tools(mcp, "authority", runtime, ...)
register_authority_tools(mcp, runtime)
```
这就是整个权限 `server.py` 。下面所有内容都由轮子提供。
### `register_authority_tools` 安装的内容
| 工具 | 费用 | 用途 |
|------|------|---------|
| `register_operator` | 免费 | 在权限账本中预配操作员;创建每个操作员的 Neon 模式 + LOGIN 角色 |
| `update_operator` | 免费 | 更新操作员的社区注册条目 |
| `deregister_operator` | 免费 | 从 DPYC 社区注册中删除操作员 |
| `get_operator_config` | 免费(证明门控) | 检索操作员的自举配置(Neon URL,模式) |
| `operator_status` | 免费 | 操作员注册状态 + 权限的 Nostr npub |
| `certify_credits` | 按价值(默认 2%,最低 10 sats) | 为采购订单签署 Schnorr 签名证明(种类 30079) |
| `check_dpyc_membership` | 免费 | 在 dpyc-community 注册表中查找 npub |
| `register_authority_npub` | 免费 | 权限自我声明的步骤 1 - 候选人发送 DM 挑战 |
| `confirm_authority_claim` | 免费 | 步骤 2 - 验证候选人的 DM,将其升级到父权限 |
| `check_authority_approval` | 免费 | 步骤 3 - 确认父权限的批准,激活权限 |
3 步注册流程将逐步升级到候选人的 `dpyc-community` 注册表命名的上游权限 - 主要权限为直接权限,NA 为 NE 等(`tollbooth.registry.resolve_my_parent_npub`,版本 0.20.0 新增)。
### 包导出内容
`tollbooth.authority` 是在 v0.21.0-v0.22.0 中从分叉的权限仓库中提升的六个支持模块上的薄接口:
- `onboarding` - `OnboardingState`,`OnboardingChallenge`,声明/批准凭证模板
- `nostr_signing` - `AuthorityNostrSigner`(Schnorr 证书签名者)
- `replay` - `ReplayTracker`(反重放 JTI 窗口)
- `tenant_provisioner` - Neon 模式 + LOGIN 角色配置
- `role_migration` - 用于将旧模式迁移到每个操作员角色的 CLI
- `settings` - `AuthoritySettings`(pydantic-settings 环境读取器)
每个运行时单例(签名者、重放跟踪器、设置、注册状态)在首次工具调用时延迟初始化;权限 MCP 每个进程一个,因此模块级状态实际上是每个权限的。
### 架构说明 - 权限仓库作为薄消费者
三个参考权限部署(`tollbooth-authority`,`tollbooth-authority-northamerica`,`tollbooth-authority-newengland`)曾经每个都分叉了约 1000 行相同的权限代码。自轮子版本 0.22.0 起,它们的 `server.py` 文件是约 80 行特定于参与者的配置:FastMCP 名称,人类可读的说明,操作员运行时构造和两个 `register_*_tools` 调用。添加新的区域权限现在是一个支架和固定操作,而不是一个分叉。
---
## 操作员运行时
`OperatorRuntime` 是核心协议引擎。所有 DPYC 操作 - 自举、计费、凭证、定价、约束 - 都被委托给它。
### 构造函数参数
```python
OperatorRuntime(
# 必需
tool_registry={**STANDARD_IDENTITIES, **YOUR_TOOLS}, # UUID 键控的 ToolIdentity 映射
# 凭证模板
operator_credential_template=CredentialTemplate(...), # BTCPay + 操作员秘密
patron_credential_template=CredentialTemplate(...), # 每个赞助商的 API 密钥(可选)
operator_credential_greeting="欢迎消息...",
patron_credential_greeting="欢迎消息...",
credential_validator=validate_fn, # 在凭证接收时调用
# 身份和网络
nsec_env_var="TOLLBOOTH_NOSTR_OPERATOR_NSEC", # 环境变量名称(默认)
service_name="我的服务",
relays=["wss://relay.damus.io"], # 覆盖默认中继
# 计费
vault_source="authority", # "authority"(默认)或 "env"(自我配置)
purchase_mode="auto", # "certified", "direct" 或 "auto"(派生自注册表链)
operator_settings={}, # 任意操作员配置字典
# 约束
constraint_gate=None, # 旧版 - 使用定价模型管道代替
# OpenTimestamps
ots_enabled=True,
ots_calendars=["https://a.pool.opentimestamps.org"],
# npub 证明
proven_npub_ttl_seconds=3600, # 默认证明缓存 TTL
npub_proof_field="confirm", # 证明 DM 中的字段名称
npub_proof_greeting="...",
on_npub_proven=async_callback, # 验证证明时调用
# OAuth2
oauth_provider=OAuthProviderConfig(...), # 启用 begin_oauth / check_oauth_status
# 生命周期
on_forget=callback, # 调用凭证被遗忘时
)
```
### 关键方法
| 方法 | 返回值 | 目的 |
|--------|---------|---------|
| `debit_or_deny(tool_id, npub, *, proof, tool_kwargs)` | `int` (成本) 或 `dict` (拒绝) | 通过身份、证明、约束、定价和计费控制工具调用 |
| `paid_tool(tool_id)` | 修饰器 | 修饰器,封装 `debit_or_deny` 在工具函数周围 |
| `require_caller_proof(npub, proof, capability)` | `dict \| None` | 调用者身份验证门控,适用于免费/启动标准工具 — 成功时返回 `None`,否则返回结构化错误字典 |
| `runtime_name(capability)` | `str` | 将能力种子解析为其运行时工具名称 (`<slug>_<capability>`) — 跨服务器边界传递的值 |
| `mcp_name_for(tool_id)` | `str` | 将工具 UUID 解析为其运行时工具名称 |
| `vault()` | `NeonVault` | 初始化并返回 Neon vault (延迟加载) |
| `ledger_cache()` | `LedgerCache` | 返回写后记账缓存 (延迟加载) |
| `courier()` | `SecureCourierService` | 返回安全快递服务 (延迟加载) |
| `operator_npub()` | `str` | 从 nsec 派生操作员的 npub |
| `resolve_npub(npub)` | `str` | 验证 npub (bech32 解码) |
| `resolve_tranche_lifetime()` | `int \| None` | 从定价模型读取 tranche 生命周期 |
| `load_credentials(fields)` | `dict` | 从 vault 加载操作员凭证 |
| `graceful_shutdown()` | — | 清空缓存并关闭连接 |
---
## 定价与约束
### 工具定价
每个工具都有一个 `ToolIdentity`,它声明了其定价:
```python
ToolIdentity(
capability="get_weather",
category="read", # read, write, heavy, free
intent="Current weather",
pricing_hint_type="ad_valorem", # fixed or ad_valorem
pricing_hint_value=1, # base cost in sats
pricing_hint_param="symbols", # parameter for ad valorem scaling
pricing_hint_min=1, # minimum cost
)
```
`ToolPricing` 引擎计算最终成本:`fixed + ceil(percentage * param_value)`,限制在 `[min, max]` 范围内。
### 约束管道
操作员在定价模型的 `pipeline` 数组中配置约束。每个步骤在每次付费工具调用时通过 `debit_or_deny` 运行。有效成本(扣除折扣、免费试用、涨价后)是客户支付的费用。
| 约束 | 目的 |
|-----------|---------|
| `free_trial` | 每个客户的前 N 次调用免费 |
| `happy_hour` | 时间窗口内的免费/折扣,定期重复 |
| `surge_pricing` | 通过全局计数器实现需求弹性定价 |
| `temporal_window` | 按时间/日期划分的访问窗口 |
| `finite_supply` | 总调用配额(每个客户或全局) |
| `periodic_refresh` | 具有 ISO-8601 刷新窗口的速率限制 |
| `coupon` | 基于代码的折扣,带有过期日期 |
| `loyalty_discount` | 基于支出的分级折扣 |
| `bulk_bonus` | 信用购买的批量奖励 |
| `patron_proof` | 高价值工具的每次调用都需要 Schnorr 证明 |
| `json_expression` | 自定义布尔逻辑规则 |
**作用范围:** 每个管道步骤都可以针对特定的工具 (`tool_ids`) 和/或特定的客户 (`patron_npubs`, 最多 10 个)。无作用范围的步骤适用于所有工具和客户。
### TrancheLifetime
信用过期是货币的属性,而不是每个工具的约束。定价模型中的 `TrancheLifetime` 设置了购买信用后保持有效的时长。每次购买都会创建一个 tranche;FIFO 消费。
---
## 凭证交付
所有机密信息 — BTCPay 密钥、API令牌、OAuth 凭证 — 都通过 **安全快递** 交付,而不是环境变量。这是一个人工介入的流程,使用 NIP-44 加密的 Nostr 直接消息:
1. AI 代理调用 `request_credential_channel(sender_npub=..., service=...)`
2. 操作员/客户在他们的 Nostr 客户端收到包含凭证模板的直接消息
3. 他们填写字段并手动回复
4. AI 代理调用 `receive_credentials(sender_npub=..., service=...)`
5. 凭证被验证、加密(AES-256-GCM with AAD),并存储在 Neon vault 中
Vault-first 查找意味着返回的客户立即激活 — 无需中继 I/O。
在第一次中继接收时,服务通过直接消息发送一个 `ncred1...` 凭证卡回来。客户可以扫描或粘贴此卡以重新激活。
---
## x402 上游封装
使用 [Coinbase x402](https://www.x402.org/) 受保护的 API 的操作员可以透明地吸收 402 支付仪式。客户永远不会看到 402 握手 — 操作员支付上游 USDC 费用作为 COGS,就像服务器租赁一样。
```python
from tollbooth.x402_client import X402Client
# 钱包凭证通过安全快递服务("x402-wallet")交付
creds = await runtime.load_credentials(["wallet_private_key", "wallet_address"])
x402 = X402Client(
wallet_private_key=creds["wallet_private_key"],
wallet_address=creds["wallet_address"],
)
@runtime.paid_tool(tool_id)
async def fetch_upstream(query: str, npub: str = "", proof: str = "") -> dict:
resp = await x402.get(f"https://x402-api.example.com/data?q={query}")
return resp.json() # 客户看到数据,永远不会看到 402
```
按工具选择:只有调用 x402 上游的工具处理程序才使用客户端。需要 `pip install tollbooth-dpyc[x402]`。无退款,无返利 — 操作员定价其工具以覆盖上游成本并获得利润。
---
## 身份与证明
每个参与者都由一个 [Nostr](https://nostr.com/) 密钥对标识。`npub` 是 DPYC 社会契约中的您的身份。`nsec` 保留给您 — 永远不会共享,永远不会发送到服务。
每个接受 `npub` 的工具也需要 `proof` — 一个 JSON 序列化的 Schnorr 签名 kind-27235 Nostr 事件,证明所有权。没有证明,就没有服务。
```python
# 证明格式(kind 27235,NIP-98 风格)
{
"pubkey": "<hex_pubkey>",
"kind": 27235,
"content": "",
"created_at": 1713000000,
"tags": [["u", "<tool_name>"]],
"sig": "<schnorr_signature>"
}
```
内联证明必须小于 60 秒。缓存证明(通过 `ProvenNpubCache`)支持客户选择的最长 24 小时的 TTL。消耗的事件 ID 被跟踪以防止重放。
**毒性密钥证明令牌:** 对于非限制工具,证明是一个毒性短语(例如 `bold-hawk-42`),由 `request_npub_proof` / `receive_npub_proof` 返回。调用应用程序记住这个令牌,并在每次后续付费工具调用时将其作为 `proof` 参数传递。MCP 只在 vault 中存储 `sha256(poison):npub` — 永远不会存储原始毒性短语。证明在不限次数的 MCP 重启后仍然有效;时长由客户选择(最长 7 天)。
---
## 架构
```
tollbooth-authority tollbooth-dpyc (此轮子) your-mcp-server
================================ ================================ ================================
Schnorr signing + tax ledger OperatorRuntime OperatorRuntime(tool_registry=...)
certify_purchase -> Nostr cert register_standard_tools(mcp, ...) register_standard_tools(mcp, ...)
Authority BTCPay debit_or_deny (门控 + 计费) @runtime.paid_tool(uuid)
Secure Courier + vault 领域特定工具
定价解析器 + 约束
DPYCRegistry (服务发现)
```
依赖关系单向流动:`your-mcp-server --> tollbooth-dpyc`。 Authority 是一个网络对等方,而不是代码依赖。
### 生态系统仓库
| 仓库 | 角色 |
|------|------|
| [tollbooth-sample](https://github.com/lonniev/tollbooth-sample) | **规范参考操作员** — 从这里开始 |
| [tollbooth-authority](https://github.com/lonniev/tollbooth-authority) | 税收收集、Schnorr 签名、购买订单认证 |
| [dpyc-community](https://github.com/lonniev/dpyc-community) | 成员注册、治理、服务发现 |
| [dpyc-oracle](https://github.com/lonniev/dpyc-oracle) | 社区礼宾 — 入站、税率、成员资格 |
| [thebrain-mcp](https://github.com/lonniev/thebrain-mcp) | 生产操作员 — PersonalBrain 知识图谱 |
| [excalibur-mcp](https://github.com/lonniev/excalibur-mcp) | 生产操作员 — 社交媒体发布 |
| [schwab-mcp](https://github.com/lonniev/schwab-mcp) | 生产操作员 — 带有 OAuth2 的经纪人数据 |
| [cypher-mcp](https://github.com/lonniev/cypher-mcp) | 生产操作员 — 通过命名 Cypher 模板的货币化图答案,适用于 Neo4j/AuraDB |
| [taxsort-mcp](https://github.com/lonniev/taxsort-mcp) | 生产操作员 — 税收分类 + Cloudflare Pages UI 分类 |
| [optionality-mcp](https://github.com/lonniev/optionality-mcp) | 生产操作员 — 期权分析 |
| [tollbooth-shortlinks](https://github.com/lonniev/tollbooth-shortlinks) | 社区实用程序 — URL 缩短器 |
| [tollbooth-oauth2-collector](https://github.com/lonniev/tollbooth-oauth2-collector) | 社区实用程序 — OAuth2 回调邮箱 |
| [tollbooth-pricing-studio](https://github.com/lonniev/tollbooth-pricing-studio) | iOS 定价编辑器 — Nostr 直接消息,原生加密 |
---
## 安装
```bash
# 标准安装 — 包括 Nostr 中继支持(安全快递,审计轨迹)
pip install tollbooth-dpyc[nostr]
# 带有凭证卡的二维码渲染
pip install tollbooth-dpyc[nostr,qr]
```
核心依赖项 (`httpx`, `pynostr`) 处理身份验证、证明和 HTTP。 `[nostr]` 额外功能添加 `websocket-client` 用于 Nostr 中继 I/O — 每个真实操作员都需要,因为安全快递凭证交付、审计发布和启动都使用中继直接消息。 `[qr]` 额外功能添加 `segno` 用于凭证卡的二维码渲染。 `[x402]` 额外功能添加 `x402` + `eth-account` 用于透明的 Coinbase x402 上游封装。
```bash
# 带有 x402 上游封装(适用于消费 x402 保护的 API 的操作员)
pip install tollbooth-dpyc[nostr,x402]
```
---
## 环境变量
| 变量 | 是否必需 | 目的 |
|----------|----------|---------|
| `TOLLBOOTH_NOSTR_OPERATOR_NSEC` | 是 | 单一的启动密钥。身份验证、安全快递、审计签名。 |
| `NEON_DATABASE_URL` | 信任根 | Neon Postgres URL。仅适用于 `vault_source="env"`(自行 provisioned 权限)。 |
| `TOLLBOOTH_NOSTR_RELAYS` | 否 | 以逗号分隔的中继 URL(覆盖默认值)。 |
认证操作员(默认)不设置 `NEON_DATABASE_URL`。他们通过加密的 Nostr 直接消息在启动期间从权限方发现它。
所有其他机密信息(BTCPay、API 密钥、OAuth 令牌)通过安全快递服务 — 而不是环境变量。
---
## Vault & 持久性
### Neon Postgres
`NeonVault` 提供 ACID 账本存储,具有 AES-256-GCM 加密(带 AAD)、乐观并发和通过 `_t()` 的模式限定表名。
`NeonCredentialVault` 以模式隔离的 Postgres 存储加密凭证(每个 `op_{hash}` 模式一个操作员,由 `register_operator` 提供)。
### 模式隔离
权限方使用 `authority` 模式。每个认证操作员都接收一个隔离的模式 (`op_{hash}`),并具有专用的 Postgres LOGIN 角色。 `NeonCredentialVault` 通过 `_t()` 了解模式。
---
## Nostr 集成
### 审计轨迹
`NostrAuditPublisher` 在每次 vault 写入时发布 kind-30078 NIP-78 事件。内容是 NIP-44v2 加密的 — 只有客户的 nsec 可以读取它。将任何 vault 包装到 `AuditedVault` 中即可透明地添加审计轨迹。
### 低余额通知
`NotificationManager` 在客户的余额穿越阈值或 tranche 接近过期时发送主动 NIP-44 直接消息。一次性触发 — 永远不会阻塞工具路径。
### 凭证卡
`ncred1...` bech32 编码的凭证卡将加密凭证打包成可扫描的二维码。基于 kind-21420 Nostr 事件,带有 NIP-44v2 加密。
---
## OpenTimestamps 比特币锚定
将账本状态锚定到比特币区块链,以实现不可篡改的时间戳证明。 `MerkleTree` 在所有 `(npub, ledger_json)` 条目上构建 SHA-256 树。 `OTSCalendarClient` 将根哈希提交到公共 OTS 日历服务器(无需 API 密钥)。
---
## 开发
```bash
git clone https://github.com/lonniev/tollbooth-dpyc.git
cd tollbooth-dpyc
python -m venv venv
source venv/bin/activate
pip install -e ".[dev,nostr,qr]"
pytest tests/ -q
```
## 进一步阅读
[The Phantom Tollbooth on the Lightning Turnpike](https://stablecoin.myshopify.com/blogs/our-value/the-phantom-tollbooth-on-the-lightning-turnpike) — 完整的故事,讲述我们如何使 AI API 的货币化更加高效,然后渐渐消失在背景中。
## 商标
DPYC、Tollbooth DPYC 和 Don't Pester Your Customer 是 Lonnie VanZandt 的商标。有关使用指南,请参阅 [TRADEMARKS.md](https://github.com/lonniev/dpyc-community/blob/main/TRADEMARKS.md) 在 dpyc-community 仓库中。
## 许可证
Apache 2.0 — 请参阅 [LICENSE](LICENSE)。
*因为最终,收费站从来不是目的地。它始终只是旅程的开始。*
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器