Catallax Skill
Interact with Catallax — a decentralized contract work protocol on Nostr using Lightning/Cashu payments and trusted escrow arbiters.
Protocol Overview
Read references/NIP-3400.md for the full spec. Key concepts:
- - Patron: Creates tasks, funds escrow, assigns workers
- Arbiter: Escrow agent who judges work and handles payment
- Free Agent: Applies for tasks, delivers work, gets paid
- Kinds: 33400 (arbiter service), 33401 (task proposal), 3402 (task conclusion)
- Status flow: proposed → funded → in_progress → submitted → concluded
Querying Tasks
Use nak to query kind 33401 events from relays:
CODEBLOCK0
Parse the content field as JSON to get title, description, requirements. Parse tags for amount, status, categories.
Display Format
When presenting tasks to the user, show:
- - Title (from content.title)
- Bounty (from
amount tag, in sats — show "?" if missing) - Status (from
status tag) - Date (from created_at)
- Categories (from
t tags) - Description (from content.description, truncated)
- Funding type (from
funding_type tag: "patron" or "crowdfunding")
Querying Arbiters
CODEBLOCK1
Parse content for name, about, policy. Parse tags for feetype, feeamount, min/max amounts, categories.
Display Format
When presenting arbiters:
- - Name (from content.name)
- Fee (feetype + feeamount — e.g. "5%" or "1000 sats flat")
- Min/Max (from minamount/maxamount tags)
- Categories (from
t tags) - About (from content.about)
Creating a Task Proposal
To create a task as a Patron, publish a kind 33401 event:
CODEBLOCK2
Generate the d-tag slug from the title (lowercase, hyphenated, with random suffix for uniqueness).
Important: The content field must be valid JSON with title, description, and optionally requirements and deadline.
Updating Task Status
Since kind 33401 is addressable replaceable, publish a new event with the same d-tag to update. Include all original tags plus changes:
CODEBLOCK3
Submitting Work (as Free Agent)
Work delivery is coordinated out-of-band per the protocol. However, agents may use kind 951 (work delivery) as a convention:
CODEBLOCK4
Task Conclusion (Arbiter only)
CODEBLOCK5
Common Queries
| User says | Action |
|---|
| "find bounties" / "show tasks" | Query kind 33401, filter status=proposed or funded |
| "create a task" / "post a bounty" |
Build and publish kind 33401 |
| "find arbiters" | Query kind 33400 |
| "submit work" / "deliver" | Publish kind 951 referencing the task |
| "check my tasks" | Query kind 33401 filtered by user's pubkey in p-tags |
| "what's the status" | Fetch specific task by d-tag, report status |
Reference Client
For visual browsing: https://catallax-reference-client.netlify.app/catallax
Key Relays
Query multiple relays for best coverage:
- - wss://relay.damus.io
- wss://nos.lol
- wss://relay.primal.net
Note: Some relays may not return results for nak req -k 33401 due to kind filtering. If nak returns empty results, fall back to a WebSocket script approach — open a WebSocket connection, send a REQ with {"kinds":[33401],"limit":50}, and collect EVENT responses until EOSE.
Edge Cases
- - Missing amount tag: Some tasks use crowdfunding (funding_type=crowdfunding) with a NIP-75 goal tag instead of a fixed amount. Display bounty as "crowdfunded" in this case.
- Content format: Content should be JSON but some early tasks used plain text. Try JSON.parse first, fall back to treating content as description.
- Stale tasks: Tasks with status=proposed older than 30 days may be abandoned. Note age when displaying.
- Multiple relays: Always publish to 3+ relays for discoverability. Query from multiple relays and deduplicate by event id.
Catallax 技能
与 Catallax 交互——一个基于 Nostr 的去中心化合约工作协议,使用 Lightning/Cashu 支付和可信的托管仲裁者。
协议概述
完整规范请阅读 references/NIP-3400.md。关键概念:
- - 赞助人:创建任务、提供托管资金、指派工作者
- 仲裁者:托管代理人,负责评判工作并处理支付
- 自由代理人:申请任务、交付工作、获得报酬
- 事件类型:33400(仲裁服务)、33401(任务提案)、3402(任务结论)
- 状态流程:已提案 → 已资助 → 进行中 → 已提交 → 已结束
查询任务
使用 nak 从中继查询 33401 类型事件:
bash
列出所有任务提案(限制 50 条)
nak req -k 33401 -l 50 wss://relay.damus.io
按标签过滤(例如标记为development的任务)
nak req -k 33401 -t development -l 50 wss://relay.damus.io
按状态过滤(仅开放任务)
nak req -k 33401 -l 100 wss://relay.damus.io | \
while read -r event; do
status=$(echo $event | jq -r .tags[] | select(.[0]==status) | .[1])
if [ $status = proposed ] || [ $status = funded ]; then
echo $event
fi
done
将内容字段解析为 JSON 以获取标题、描述和要求。解析标签以获取金额、状态和分类。
显示格式
向用户展示任务时,显示:
- - 标题(来自 content.title)
- 赏金(来自 amount 标签,单位为聪——缺失时显示?)
- 状态(来自 status 标签)
- 日期(来自 createdat)
- 分类(来自 t 标签)
- 描述(来自 content.description,截断显示)
- 资助类型(来自 fundingtype 标签:patron 或 crowdfunding)
查询仲裁者
bash
列出仲裁服务
nak req -k 33400 -l 50 wss://relay.damus.io
解析内容以获取名称、简介和政策。解析标签以获取费用类型、费用金额、最小/最大金额和分类。
显示格式
展示仲裁者时:
- - 名称(来自 content.name)
- 费用(feetype + feeamount——例如5%或1000 聪固定费用)
- 最小/最大(来自 minamount/maxamount 标签)
- 分类(来自 t 标签)
- 简介(来自 content.about)
创建任务提案
作为赞助人创建任务,发布一个 33401 类型事件:
bash
构建并发布任务提案
nak event -k 33401 \
--tag d=<唯一标识> \
--tag p=<你的公钥> \
--tag amount=<赏金-聪数> \
--tag t=<分类> \
--tag status=proposed \
--tag funding_type=patron \
-c {title:任务标题,description:详细描述...,requirements:必须交付的内容} \
--sec
\
wss://relay.damus.io wss://nos.lol wss://relay.primal.net
从标题生成 d-tag 标识(小写、连字符连接,添加随机后缀以确保唯一性)。
重要提示:内容字段必须是有效的 JSON,包含标题、描述,以及可选的 requirements 和 deadline。
更新任务状态
由于 33401 类型是可寻址可替换的,发布一个具有相同 d-tag 的新事件即可更新。包含所有原始标签及变更:
bash
更新为已资助(添加 zap 收据引用)
nak event -k 33401 \
--tag d=<相同-d-tag> \
--tag status=funded \
--tag e= \
# ... 所有其他原始标签 ...
--sec \
wss://relay.damus.io
提交工作(作为自由代理人)
根据协议,工作交付在带外协调。然而,代理人可以使用 951 类型(工作交付)作为惯例:
bash
nak event -k 951 \
--tag e=<任务事件-id> \
--tag p=<赞助人公钥> \
-c {delivery:已完成工作的描述,evidence:链接或证明} \
--sec \
wss://relay.damus.io
任务结束(仅限仲裁者)
bash
nak event -k 3402 \
--tag e=<支付-zap-收据-id> \
--tag e=<任务事件-id> \
--tag p=<赞助人公钥> \
--tag p=<仲裁者公钥> \
--tag p=<工作者公钥> \
--tag resolution=successful \
--tag a=33401:<赞助人公钥>:<任务-d-tag> \
-c {resolution_details:工作满足所有要求} \
--sec \
wss://relay.damus.io
常见查询
| 用户说 | 操作 |
|---|
| 查找赏金 / 显示任务 | 查询 33401 类型,过滤 status=proposed 或 funded |
| 创建任务 / 发布赏金 |
构建并发布 33401 类型 |
| 查找仲裁者 | 查询 33400 类型 |
| 提交工作 / 交付 | 发布引用任务的 951 类型 |
| 查看我的任务 | 查询 33401 类型,按 p-tags 中的用户公钥过滤 |
| 状态如何 | 通过 d-tag 获取特定任务,报告状态 |
参考客户端
可视化浏览:https://catallax-reference-client.netlify.app/catallax
关键中继
查询多个中继以获得最佳覆盖:
- - wss://relay.damus.io
- wss://nos.lol
- wss://relay.primal.net
注意:由于事件类型过滤,某些中继可能不会返回 nak req -k 33401 的结果。如果 nak 返回空结果,请回退到 WebSocket 脚本方法——打开 WebSocket 连接,发送带有 {kinds:[33401],limit:50} 的 REQ,并收集 EVENT 响应直到 EOSE。
边界情况
- - 缺少金额标签:某些任务使用众筹(funding_type=crowdfunding),带有 NIP-75 目标标签而非固定金额。此时将赏金显示为众筹。
- 内容格式:内容应为 JSON,但某些早期任务使用纯文本。先尝试 JSON.parse,失败时将内容视为描述。
- 过期任务:状态为 proposed 且超过 30 天的任务可能已被废弃。显示时注明时间。
- 多个中继:始终发布到 3 个以上中继以确保可发现性。从多个中继查询并按事件 ID 去重。