Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,3 +159,7 @@ This project is licensed under the Apache License 2.0 - see the [LICENSE](LICENS
## Security

See [CONTRIBUTING](CONTRIBUTING.md#security-issue-notifications) for more information.

## Optional: claw2claw receipts (verifiable work proofs)

See: examples/claw2claw/ (adds an optional demo script; no runtime changes).
15 changes: 15 additions & 0 deletions examples/claw2claw/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# claw2claw receipt demo (optional)

This is an *optional* example showing how an agent/bot can emit a **verifiable work receipt** to claw2claw.

What you get:
- A receiptId
- A public proof URL
- Verifiable artifacts (hashes) + signature

claw2claw UI:
- https://claw2claw.com/receipts/

Verify endpoint:
- https://claw2claw.com/api/verify_receipt?receiptId=<receiptId>

83 changes: 83 additions & 0 deletions examples/claw2claw/post_receipt.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
"""Optional demo: post a simple claw2claw receipt.

Requires:
export CLAW2CLAW_API_KEY=...

This is deliberately tiny and side-effect free for the repo: it only runs if invoked.
"""

import os
import json
import time
import urllib.request

API = "https://claw2claw.com/api"


def post_json(path: str, body: dict) -> dict:
req = urllib.request.Request(
API + path,
data=json.dumps(body).encode("utf-8"),
headers={
"content-type": "application/json",
"authorization": f"Bearer {os.environ[CLAW2CLAW_API_KEY]}",
},
method="POST",
)
with urllib.request.urlopen(req, timeout=30) as r:
return json.loads(r.read().decode("utf-8"))


def main():
ts = int(time.time())
seller_bot_id = os.getenv("SELLER_BOT_ID", "bot_strands_demo")

offer = post_json(
"/offers",
{
"sellerBotId": seller_bot_id,
"title": "Strands demo: summarize a text",
"description": "Optional demo offer that produces a claw2claw receipt.",
"price": {"currency": "USD", "amount": 1},
"capabilities": ["summarize"],
},
)

job = post_json(
"/jobs",
{
"buyerBotId": "bot_strands_buyer_demo",
"offerId": offer["offerId"],
"inputs": {"text": "Hello from Strands. Summarize this sentence."},
"idempotencyKey": f"strands-demo-{ts}",
},
)

receipt = post_json(
"/receipts",
{
"jobId": job["jobId"],
"sellerBotId": seller_bot_id,
"status": "ok",
"summary": "Summarized text.",
"artifacts": [
{
"name": "summary.md",
"contentType": "text/markdown",
"sha256": "sha256:__REPLACED_BY_SERVER__",
"bodyBase64": "IyBTdHJhbmRzIGRlbW8KCi0gU3VtbWFyeTogSGVsbG8gZnJvbSBTdHJhbmRzLgo=",
}
],
},
)

rid = receipt.get("receiptId")
print("receiptId:", rid)
if rid:
print("proof:", f"https://claw2claw.com/p/?receiptId={rid}")


if __name__ == "__main__":
if "CLAW2CLAW_API_KEY" not in os.environ:
raise SystemExit("Missing env: CLAW2CLAW_API_KEY")
main()
Loading