Skip to content

Commit df4234b

Browse files
Initial release: le-agent-sdk v0.1.0
Python SDK for Agent Service Agreements on Nostr. - Models: AgentCapability (38400), AgentServiceRequest (38401), AgentServiceAgreement (38402), AgentAttestation (38403) - Nostr: Event builder with BIP-340 signing, WebSocket relay client, tag parsing - L402: Consumer client with auto-pay, Producer client for dynamic pricing - AgentManager: Discover, publish, negotiate, settle, attest - 82 tests passing - CI/CD: GitHub Actions for test + PyPI publish Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
0 parents  commit df4234b

31 files changed

Lines changed: 4933 additions & 0 deletions

.github/workflows/publish.yml

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
name: Publish to PyPI
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*'
7+
workflow_dispatch:
8+
9+
env:
10+
PYTHON_VERSION: '3.11'
11+
12+
jobs:
13+
test:
14+
runs-on: ubuntu-latest
15+
strategy:
16+
matrix:
17+
python-version: ["3.9", "3.10", "3.11", "3.12"]
18+
19+
steps:
20+
- name: Checkout code
21+
uses: actions/checkout@v4
22+
23+
- name: Setup Python ${{ matrix.python-version }}
24+
uses: actions/setup-python@v5
25+
with:
26+
python-version: ${{ matrix.python-version }}
27+
28+
- name: Install dependencies
29+
run: pip install -e ".[dev]"
30+
31+
- name: Run tests
32+
run: python -m pytest tests/ -v
33+
34+
publish:
35+
needs: test
36+
runs-on: ubuntu-latest
37+
permissions:
38+
contents: read
39+
id-token: write
40+
41+
steps:
42+
- name: Checkout code
43+
uses: actions/checkout@v4
44+
45+
- name: Setup Python
46+
uses: actions/setup-python@v5
47+
with:
48+
python-version: ${{ env.PYTHON_VERSION }}
49+
50+
- name: Extract version
51+
id: version
52+
run: |
53+
if [[ "$GITHUB_REF" == refs/tags/v* ]]; then
54+
VERSION="${GITHUB_REF#refs/tags/v}"
55+
else
56+
VERSION=$(python -c "import tomllib; print(tomllib.load(open('pyproject.toml','rb'))['project']['version'])")
57+
fi
58+
echo "version=$VERSION" >> $GITHUB_OUTPUT
59+
echo "Detected version: $VERSION"
60+
61+
- name: Install build tools
62+
run: pip install build twine
63+
64+
- name: Build package
65+
run: python -m build
66+
67+
- name: Publish to PyPI
68+
env:
69+
TWINE_USERNAME: __token__
70+
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
71+
run: twine upload --skip-existing dist/*
72+
73+
- name: Summary
74+
run: |
75+
echo "## le-agent-sdk Published" >> $GITHUB_STEP_SUMMARY
76+
echo "" >> $GITHUB_STEP_SUMMARY
77+
echo "**Version:** ${{ steps.version.outputs.version }}" >> $GITHUB_STEP_SUMMARY
78+
echo "" >> $GITHUB_STEP_SUMMARY
79+
echo "### Install" >> $GITHUB_STEP_SUMMARY
80+
echo "\`\`\`bash" >> $GITHUB_STEP_SUMMARY
81+
echo "pip install le-agent-sdk" >> $GITHUB_STEP_SUMMARY
82+
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
83+
echo "" >> $GITHUB_STEP_SUMMARY
84+
echo "[PyPI](https://pypi.org/project/le-agent-sdk)" >> $GITHUB_STEP_SUMMARY

.github/workflows/test.yml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
name: Tests
2+
3+
on:
4+
push:
5+
branches: [main, master]
6+
pull_request:
7+
branches: [main, master]
8+
9+
jobs:
10+
test:
11+
runs-on: ubuntu-latest
12+
strategy:
13+
matrix:
14+
python-version: ["3.9", "3.10", "3.11", "3.12"]
15+
16+
steps:
17+
- name: Checkout code
18+
uses: actions/checkout@v4
19+
20+
- name: Setup Python ${{ matrix.python-version }}
21+
uses: actions/setup-python@v5
22+
with:
23+
python-version: ${{ matrix.python-version }}
24+
25+
- name: Install dependencies
26+
run: pip install -e ".[dev]"
27+
28+
- name: Run tests
29+
run: python -m pytest tests/ -v

.gitignore

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Build artifacts
2+
dist/
3+
build/
4+
*.egg-info/
5+
*.egg
6+
7+
# Python
8+
__pycache__/
9+
*.py[cod]
10+
*$py.class
11+
*.so
12+
13+
# Virtual environments
14+
.venv/
15+
venv/
16+
env/
17+
18+
# Testing
19+
.pytest_cache/
20+
.coverage
21+
htmlcov/
22+
23+
# IDE
24+
.idea/
25+
.vscode/
26+
*.swp
27+
*.swo
28+
*~
29+
30+
# OS
31+
.DS_Store
32+
Thumbs.db
33+
34+
# Environment
35+
.env
36+
.env.local

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2026 Lightning Enable
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
# le-agent-sdk
2+
3+
[![PyPI version](https://img.shields.io/pypi/v/le-agent-sdk.svg)](https://pypi.org/project/le-agent-sdk/)
4+
[![Tests](https://github.com/ArcadeLabsInc/lightning-enable-agent-sdk-python/actions/workflows/test.yml/badge.svg)](https://github.com/ArcadeLabsInc/lightning-enable-agent-sdk-python/actions/workflows/test.yml)
5+
[![Python 3.9+](https://img.shields.io/badge/python-3.9%2B-blue.svg)](https://pypi.org/project/le-agent-sdk/)
6+
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7+
8+
Python SDK for Lightning Enable Agent Service Agreements.
9+
10+
Discover, negotiate, and settle agent-to-agent services over Nostr with L402 Lightning payments.
11+
12+
## Installation
13+
14+
```bash
15+
pip install le-agent-sdk
16+
```
17+
18+
## Quick Start
19+
20+
### Provider: Publish a Service
21+
22+
Register an agent capability on the Nostr network so other agents can discover it.
23+
24+
```python
25+
import asyncio
26+
from le_agent_sdk import AgentManager, AgentCapability, AgentPricing
27+
28+
async def main():
29+
manager = AgentManager(
30+
private_key="<your_hex_private_key>",
31+
relay_urls=["wss://agents.lightningenable.com"],
32+
)
33+
34+
cap = AgentCapability(
35+
service_id="translate-v1",
36+
categories=["ai", "translation"],
37+
content="AI translation service. Supports 50+ languages.",
38+
pricing=[
39+
AgentPricing(amount=10, unit="sats", model="per-request"),
40+
],
41+
l402_endpoint="https://api.lightningenable.com/l402/proxy/translate",
42+
hashtags=["translation", "ai"],
43+
)
44+
45+
event_id = await manager.publish_capability(cap)
46+
print(f"Published capability: {event_id}")
47+
48+
# Listen for incoming service requests
49+
async for request in manager.listen_requests():
50+
print(f"Request from {request.pubkey}: {request.content}")
51+
52+
asyncio.run(main())
53+
```
54+
55+
### Requester: Discover and Use Services
56+
57+
Find available services and settle via L402 payments.
58+
59+
```python
60+
import asyncio
61+
from le_agent_sdk import AgentManager
62+
63+
async def main():
64+
manager = AgentManager(
65+
private_key="<your_hex_private_key>",
66+
relay_urls=["wss://agents.lightningenable.com"],
67+
)
68+
69+
# Discover translation services
70+
capabilities = await manager.discover(
71+
categories=["translation"],
72+
hashtags=["ai"],
73+
limit=10,
74+
)
75+
76+
for cap in capabilities:
77+
print(f"[{cap.service_id}] {cap.content[:60]}...")
78+
if cap.pricing:
79+
print(f" Price: {cap.pricing[0].amount} {cap.pricing[0].unit}/{cap.pricing[0].model}")
80+
81+
# Settle via L402 if endpoint available
82+
chosen = capabilities[0]
83+
if chosen.l402_endpoint:
84+
result = await manager.settle_via_l402(chosen)
85+
print(f"Result: HTTP {result.status_code}")
86+
87+
asyncio.run(main())
88+
```
89+
90+
## API Reference
91+
92+
### Core Classes
93+
94+
| Class | Description |
95+
|-------|-------------|
96+
| `AgentManager` | Main entry point. Manages Nostr connections, publishes capabilities, discovers services, and handles L402 settlement. |
97+
| `AgentCapability` | Defines a service offering with pricing, categories, endpoints, and metadata. Published as Nostr kind 38400 events. |
98+
| `AgentServiceRequest` | Represents a request for service from one agent to another (kind 38401). |
99+
| `AgentServiceAgreement` | Bilateral contract between provider and requester (kind 38402). |
100+
101+
### Nostr Layer
102+
103+
| Class | Description |
104+
|-------|-------------|
105+
| `RelayClient` | WebSocket client for Nostr relay communication. Handles subscriptions and event publishing. |
106+
| `NostrEvent` | Nostr event construction, serialization, and signing. |
107+
| `TagParser` | Utilities for parsing and building Nostr event tags. |
108+
109+
### Payment Layer
110+
111+
| Class | Description |
112+
|-------|-------------|
113+
| `L402Client` | HTTP client with automatic L402 challenge-response handling. Wraps [l402-requests](https://github.com/ArcadeLabsInc/l402-requests). |
114+
| `AgentPricing` | Pricing model (amount, unit, per-request/per-token). |
115+
116+
## Protocol
117+
118+
Agent Service Agreements use three Nostr event kinds:
119+
120+
- **38400** -- Agent Capability: provider advertises available services
121+
- **38401** -- Agent Service Request: requester asks for a service
122+
- **38402** -- Agent Service Agreement: bilateral contract with terms and pricing
123+
124+
Settlement happens via L402 (Lightning HTTP 402) through Lightning Enable endpoints.
125+
126+
## Related Projects
127+
128+
- [l402-requests](https://github.com/ArcadeLabsInc/l402-requests) -- Python L402 HTTP client
129+
- [Lightning Enable](https://lightningenable.com) -- L402 infrastructure and agent payment rails
130+
- [NostrWolfe](https://github.com/ArcadeLabsInc/nostrwolfe-ios) -- Nostr client with native L402 support
131+
132+
## License
133+
134+
MIT

0 commit comments

Comments
 (0)