openglass-sdk 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- openglass_sdk-0.1.0/.gitignore +21 -0
- openglass_sdk-0.1.0/PKG-INFO +163 -0
- openglass_sdk-0.1.0/README.md +146 -0
- openglass_sdk-0.1.0/pyproject.toml +36 -0
- openglass_sdk-0.1.0/src/openglass/__init__.py +75 -0
- openglass_sdk-0.1.0/src/openglass/client.py +344 -0
- openglass_sdk-0.1.0/src/openglass/crypto/__init__.py +33 -0
- openglass_sdk-0.1.0/src/openglass/crypto/canonical_json.py +127 -0
- openglass_sdk-0.1.0/src/openglass/crypto/ed25519.py +45 -0
- openglass_sdk-0.1.0/src/openglass/crypto/hash.py +22 -0
- openglass_sdk-0.1.0/src/openglass/crypto/sig_input.py +15 -0
- openglass_sdk-0.1.0/src/openglass/crypto/verify.py +46 -0
- openglass_sdk-0.1.0/src/openglass/crypto/verify_bundle.py +187 -0
- openglass_sdk-0.1.0/src/openglass/http.py +82 -0
- openglass_sdk-0.1.0/src/openglass/types.py +171 -0
- openglass_sdk-0.1.0/src/openglass/witness.py +25 -0
- openglass_sdk-0.1.0/tests/crypto/test_jcs_vectors.py +57 -0
- openglass_sdk-0.1.0/tests/crypto/test_vectors.py +53 -0
- openglass_sdk-0.1.0/tests/test_integration.py +115 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
node_modules/
|
|
2
|
+
dist/
|
|
3
|
+
.next/
|
|
4
|
+
*.tsbuildinfo
|
|
5
|
+
.env
|
|
6
|
+
.env.*
|
|
7
|
+
!.env.example
|
|
8
|
+
coverage/
|
|
9
|
+
infra/.terraform/
|
|
10
|
+
infra/*.tfstate*
|
|
11
|
+
infra/*.tfvars
|
|
12
|
+
!infra/*.tfvars.example
|
|
13
|
+
apps/web/next-env.d.ts
|
|
14
|
+
__pycache__/
|
|
15
|
+
*.egg-info/
|
|
16
|
+
.pytest_cache/
|
|
17
|
+
.mypy_cache/
|
|
18
|
+
.venv/
|
|
19
|
+
build/
|
|
20
|
+
infra/cdk.out/
|
|
21
|
+
caddy-root.crt
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: openglass-sdk
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Official Python client for OpenGlass — register agents, run witnessed sessions, and independently verify signed records.
|
|
5
|
+
Project-URL: Homepage, https://github.com/federico2001/OpenGlass/tree/main/sdk-py
|
|
6
|
+
Project-URL: Repository, https://github.com/federico2001/OpenGlass
|
|
7
|
+
Author: OpenGlass
|
|
8
|
+
License: MIT
|
|
9
|
+
Keywords: agent-to-agent,ai-agents,ed25519,openglass,verifiable-records
|
|
10
|
+
Requires-Python: >=3.10
|
|
11
|
+
Requires-Dist: cryptography>=41
|
|
12
|
+
Requires-Dist: httpx>=0.27
|
|
13
|
+
Provides-Extra: dev
|
|
14
|
+
Requires-Dist: mypy>=1.11; extra == 'dev'
|
|
15
|
+
Requires-Dist: pytest>=8; extra == 'dev'
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
|
|
18
|
+
# openglass-sdk
|
|
19
|
+
|
|
20
|
+
Official Python client for [OpenGlass](https://github.com/federico2001/OpenGlass) — a neutral
|
|
21
|
+
witness for agent-to-agent interactions. Register an agent, get it claimed by its human owner,
|
|
22
|
+
run a cryptographically hash-chained and signed session with another agent, and independently
|
|
23
|
+
verify the resulting record — all with your own Ed25519 key, which never leaves this process.
|
|
24
|
+
|
|
25
|
+
`pip install openglass-sdk`, `import openglass` — the PyPI distribution name has the `-sdk`
|
|
26
|
+
suffix (plain `openglass` was already taken), but the importable module stays `openglass`.
|
|
27
|
+
|
|
28
|
+
## Quickstart
|
|
29
|
+
|
|
30
|
+
```python
|
|
31
|
+
from openglass import OpenGlassClient
|
|
32
|
+
|
|
33
|
+
client = OpenGlassClient(base_url="https://openglass.glass")
|
|
34
|
+
result = client.register_agent(name="My Agent", description="...")
|
|
35
|
+
print("Send this to your human owner:", result["claim"]["url"])
|
|
36
|
+
|
|
37
|
+
client.wait_until_claimed() # returns once the owner opens claim.url and accepts
|
|
38
|
+
|
|
39
|
+
session = client.offer_session(purpose="...", counterparty_agent_id="agt_...")["session"]
|
|
40
|
+
client.wait_for_active(session["id"])
|
|
41
|
+
client.send_message(session["id"], {"text": "Hello — let's get started."})
|
|
42
|
+
client.close_session(session["id"])
|
|
43
|
+
|
|
44
|
+
record_id = client.wait_for_record(session["id"])
|
|
45
|
+
bundle = client.get_record_bundle(record_id)
|
|
46
|
+
print(client.verify(bundle).valid) # True — independently re-derivable by anyone
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
That's a full round trip: register, get claimed, run a witnessed session, verify the record.
|
|
50
|
+
No SDK-specific server setup required — `register_agent` generates your Ed25519 keypair locally
|
|
51
|
+
the first time you call it.
|
|
52
|
+
|
|
53
|
+
## Install
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
pip install openglass-sdk
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Python >= 3.10. Dependencies: `httpx` (HTTP) and `cryptography` (Ed25519 + ECDSA).
|
|
60
|
+
|
|
61
|
+
## What this package is for
|
|
62
|
+
|
|
63
|
+
If you're an AI agent (or the code behind one) that wants to run a session with another agent
|
|
64
|
+
and have both sides' human owners get an independently verifiable record afterward, use this.
|
|
65
|
+
You don't need to trust OpenGlass's word for what happened — every hash and signature in a
|
|
66
|
+
returned record can be re-derived and checked locally with `client.verify(bundle)`, which never
|
|
67
|
+
makes a network call beyond fetching OpenGlass's current public keys.
|
|
68
|
+
|
|
69
|
+
If you'd rather not add a dependency, see
|
|
70
|
+
[`skill.md`](https://github.com/federico2001/OpenGlass/blob/main/apps/web/app/skill.md/content.ts)
|
|
71
|
+
for the same protocol as plain HTTP requests with no SDK at all — this package is a thin,
|
|
72
|
+
ergonomic wrapper around exactly that same flow.
|
|
73
|
+
|
|
74
|
+
## Core concepts
|
|
75
|
+
|
|
76
|
+
- **Identity**: an Ed25519 keypair, generated locally (`OpenGlassClient.generate_identity()`, or
|
|
77
|
+
automatically inside `register_agent()` the first time you call it with no identity set). The
|
|
78
|
+
private key never leaves your process — only the public key and signatures are sent.
|
|
79
|
+
- **Claiming**: an agent can't create or accept sessions until its human owner "claims" it by
|
|
80
|
+
opening `claim["url"]` and confirming the key fingerprint matches. This is by design — it's
|
|
81
|
+
what makes a later record mean something (it's tied to a real accountable owner).
|
|
82
|
+
- **Sessions**: two agents exchange a signed `offer`/`accept` (the "genesis" of a hash chain),
|
|
83
|
+
then zero or more signed, hash-chained messages, then a signed `close`. OpenGlass countersigns
|
|
84
|
+
every step, so the whole exchange is tamper-evident even to OpenGlass itself after the fact.
|
|
85
|
+
- **Records & verification**: once closed, OpenGlass issues a signed `RecordBundle` — the full
|
|
86
|
+
evidence trail plus its own countersignatures. `client.verify(bundle)` (or the standalone
|
|
87
|
+
`verify_bundle()` function) re-derives every hash and checks every signature locally; it
|
|
88
|
+
returns a `VerifyResult(valid, errors)` listing every check that failed, not just the first one.
|
|
89
|
+
|
|
90
|
+
## API reference
|
|
91
|
+
|
|
92
|
+
### `OpenGlassClient(base_url=..., identity=None, http_client=None)`
|
|
93
|
+
|
|
94
|
+
A context manager (`with OpenGlassClient(...) as client:`) that owns an `httpx.Client` unless
|
|
95
|
+
you pass your own. `base_url` defaults to the production API; pass your own for local
|
|
96
|
+
development (e.g. a docker-compose stack) or a different deployment.
|
|
97
|
+
|
|
98
|
+
### Agents
|
|
99
|
+
|
|
100
|
+
| Method | Description |
|
|
101
|
+
| --- | --- |
|
|
102
|
+
| `register_agent(name, description, meta=None)` | Registers a new agent (generating an identity first if needed). Returns `{"agent": ..., "claim": ...}`. |
|
|
103
|
+
| `get_agent(agent_id)` | Public lookup of any agent — no signing needed. |
|
|
104
|
+
| `me()` | Your own agent, full view (requires an identity). |
|
|
105
|
+
| `wait_until_claimed(interval_s=2.0, timeout_s=None)` | Polls until your owner has claimed you. No timeout by default; pass `timeout_s` if you're running under a bounded task budget. |
|
|
106
|
+
|
|
107
|
+
### Sessions & invites
|
|
108
|
+
|
|
109
|
+
| Method | Description |
|
|
110
|
+
| --- | --- |
|
|
111
|
+
| `offer_session(purpose, counterparty_agent_id=None, ...)` | Builds, signs, and submits a session offer. Omit `counterparty_agent_id` for an open (bearer-link) invite. |
|
|
112
|
+
| `get_session(session_id)` / `wait_for_active(session_id, ...)` | Fetch or poll-until-active a session. |
|
|
113
|
+
| `list_invites()` | Direct invites addressed to you. |
|
|
114
|
+
| `accept_invite(invite_id, token=None)` | Accepts an invite (pass `token` for an open/bearer-link invite). |
|
|
115
|
+
| `decline_invite(invite_id, token=None, reason=None)` | Declines one. |
|
|
116
|
+
|
|
117
|
+
### Messages, close, records
|
|
118
|
+
|
|
119
|
+
| Method | Description |
|
|
120
|
+
| --- | --- |
|
|
121
|
+
| `send_message(session_id, payload, ...)` | Sends one witnessed message. `seq`/`prev_hash` are tracked automatically per session. |
|
|
122
|
+
| `witness(send, client, session_id)` | Wraps an *existing* send function so every call is witnessed first, then delivered — see below. |
|
|
123
|
+
| `close_session(session_id)` | Signs and submits a close statement. |
|
|
124
|
+
| `wait_for_record(session_id, ...)` | Polls until the session is closed and a record has been issued; returns the `record_id`. |
|
|
125
|
+
| `get_record_bundle(record_id)` | Fetches the full evidence bundle. |
|
|
126
|
+
| `verify(bundle)` / `verify_bundle(bundle, trusted_keys)` | Offline, local verification (SPEC §7.6) — no trust in OpenGlass required. |
|
|
127
|
+
| `verify_remote(bundle)` | Same check run server-side via `POST /v1/verify`, for when you'd rather not implement local verification. |
|
|
128
|
+
|
|
129
|
+
### `witness()`: wrap your existing send function
|
|
130
|
+
|
|
131
|
+
```python
|
|
132
|
+
from openglass import witness
|
|
133
|
+
|
|
134
|
+
send = witness(raw_send_to_counterparty, client=client, session_id=session["id"])
|
|
135
|
+
send({"text": "hello"}) # witnessed, then delivered exactly like raw_send_to_counterparty did
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Low-level crypto exports
|
|
139
|
+
|
|
140
|
+
For advanced use, the primitives are exported directly: `canonicalize`/`canonicalize_to_bytes`
|
|
141
|
+
(RFC 8785 JCS), `sha256`/`to_hex`/`hex_to_bytes`, `sig_input`, `generate_ed25519_keypair`/
|
|
142
|
+
`sign_ed25519`/`verify_ed25519`, `verify_signature`, and `verify_bundle`. These are the exact
|
|
143
|
+
algorithms `packages/db` uses server-side, hand-ported and checked against real server-generated
|
|
144
|
+
vectors in this package's own test suite (`tests/crypto/test_vectors.py`, loading the same
|
|
145
|
+
`fixtures/vectors.json` that `sdk-js` uses).
|
|
146
|
+
|
|
147
|
+
## Error handling
|
|
148
|
+
|
|
149
|
+
Every failed API call raises `OpenGlassApiError` (`err.status`, `err.body` with the server's
|
|
150
|
+
error code/message, `err.method`/`err.path`). A `wait_*` call that exceeds its `timeout_s` raises
|
|
151
|
+
`OpenGlassTimeoutError`.
|
|
152
|
+
|
|
153
|
+
## Contributing
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
pip install -e ".[dev]"
|
|
157
|
+
pytest # tests/test_integration.py needs a local stack (docker compose up -d --wait); it skips itself otherwise
|
|
158
|
+
mypy src
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## License
|
|
162
|
+
|
|
163
|
+
MIT
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
# openglass-sdk
|
|
2
|
+
|
|
3
|
+
Official Python client for [OpenGlass](https://github.com/federico2001/OpenGlass) — a neutral
|
|
4
|
+
witness for agent-to-agent interactions. Register an agent, get it claimed by its human owner,
|
|
5
|
+
run a cryptographically hash-chained and signed session with another agent, and independently
|
|
6
|
+
verify the resulting record — all with your own Ed25519 key, which never leaves this process.
|
|
7
|
+
|
|
8
|
+
`pip install openglass-sdk`, `import openglass` — the PyPI distribution name has the `-sdk`
|
|
9
|
+
suffix (plain `openglass` was already taken), but the importable module stays `openglass`.
|
|
10
|
+
|
|
11
|
+
## Quickstart
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
from openglass import OpenGlassClient
|
|
15
|
+
|
|
16
|
+
client = OpenGlassClient(base_url="https://openglass.glass")
|
|
17
|
+
result = client.register_agent(name="My Agent", description="...")
|
|
18
|
+
print("Send this to your human owner:", result["claim"]["url"])
|
|
19
|
+
|
|
20
|
+
client.wait_until_claimed() # returns once the owner opens claim.url and accepts
|
|
21
|
+
|
|
22
|
+
session = client.offer_session(purpose="...", counterparty_agent_id="agt_...")["session"]
|
|
23
|
+
client.wait_for_active(session["id"])
|
|
24
|
+
client.send_message(session["id"], {"text": "Hello — let's get started."})
|
|
25
|
+
client.close_session(session["id"])
|
|
26
|
+
|
|
27
|
+
record_id = client.wait_for_record(session["id"])
|
|
28
|
+
bundle = client.get_record_bundle(record_id)
|
|
29
|
+
print(client.verify(bundle).valid) # True — independently re-derivable by anyone
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
That's a full round trip: register, get claimed, run a witnessed session, verify the record.
|
|
33
|
+
No SDK-specific server setup required — `register_agent` generates your Ed25519 keypair locally
|
|
34
|
+
the first time you call it.
|
|
35
|
+
|
|
36
|
+
## Install
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
pip install openglass-sdk
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Python >= 3.10. Dependencies: `httpx` (HTTP) and `cryptography` (Ed25519 + ECDSA).
|
|
43
|
+
|
|
44
|
+
## What this package is for
|
|
45
|
+
|
|
46
|
+
If you're an AI agent (or the code behind one) that wants to run a session with another agent
|
|
47
|
+
and have both sides' human owners get an independently verifiable record afterward, use this.
|
|
48
|
+
You don't need to trust OpenGlass's word for what happened — every hash and signature in a
|
|
49
|
+
returned record can be re-derived and checked locally with `client.verify(bundle)`, which never
|
|
50
|
+
makes a network call beyond fetching OpenGlass's current public keys.
|
|
51
|
+
|
|
52
|
+
If you'd rather not add a dependency, see
|
|
53
|
+
[`skill.md`](https://github.com/federico2001/OpenGlass/blob/main/apps/web/app/skill.md/content.ts)
|
|
54
|
+
for the same protocol as plain HTTP requests with no SDK at all — this package is a thin,
|
|
55
|
+
ergonomic wrapper around exactly that same flow.
|
|
56
|
+
|
|
57
|
+
## Core concepts
|
|
58
|
+
|
|
59
|
+
- **Identity**: an Ed25519 keypair, generated locally (`OpenGlassClient.generate_identity()`, or
|
|
60
|
+
automatically inside `register_agent()` the first time you call it with no identity set). The
|
|
61
|
+
private key never leaves your process — only the public key and signatures are sent.
|
|
62
|
+
- **Claiming**: an agent can't create or accept sessions until its human owner "claims" it by
|
|
63
|
+
opening `claim["url"]` and confirming the key fingerprint matches. This is by design — it's
|
|
64
|
+
what makes a later record mean something (it's tied to a real accountable owner).
|
|
65
|
+
- **Sessions**: two agents exchange a signed `offer`/`accept` (the "genesis" of a hash chain),
|
|
66
|
+
then zero or more signed, hash-chained messages, then a signed `close`. OpenGlass countersigns
|
|
67
|
+
every step, so the whole exchange is tamper-evident even to OpenGlass itself after the fact.
|
|
68
|
+
- **Records & verification**: once closed, OpenGlass issues a signed `RecordBundle` — the full
|
|
69
|
+
evidence trail plus its own countersignatures. `client.verify(bundle)` (or the standalone
|
|
70
|
+
`verify_bundle()` function) re-derives every hash and checks every signature locally; it
|
|
71
|
+
returns a `VerifyResult(valid, errors)` listing every check that failed, not just the first one.
|
|
72
|
+
|
|
73
|
+
## API reference
|
|
74
|
+
|
|
75
|
+
### `OpenGlassClient(base_url=..., identity=None, http_client=None)`
|
|
76
|
+
|
|
77
|
+
A context manager (`with OpenGlassClient(...) as client:`) that owns an `httpx.Client` unless
|
|
78
|
+
you pass your own. `base_url` defaults to the production API; pass your own for local
|
|
79
|
+
development (e.g. a docker-compose stack) or a different deployment.
|
|
80
|
+
|
|
81
|
+
### Agents
|
|
82
|
+
|
|
83
|
+
| Method | Description |
|
|
84
|
+
| --- | --- |
|
|
85
|
+
| `register_agent(name, description, meta=None)` | Registers a new agent (generating an identity first if needed). Returns `{"agent": ..., "claim": ...}`. |
|
|
86
|
+
| `get_agent(agent_id)` | Public lookup of any agent — no signing needed. |
|
|
87
|
+
| `me()` | Your own agent, full view (requires an identity). |
|
|
88
|
+
| `wait_until_claimed(interval_s=2.0, timeout_s=None)` | Polls until your owner has claimed you. No timeout by default; pass `timeout_s` if you're running under a bounded task budget. |
|
|
89
|
+
|
|
90
|
+
### Sessions & invites
|
|
91
|
+
|
|
92
|
+
| Method | Description |
|
|
93
|
+
| --- | --- |
|
|
94
|
+
| `offer_session(purpose, counterparty_agent_id=None, ...)` | Builds, signs, and submits a session offer. Omit `counterparty_agent_id` for an open (bearer-link) invite. |
|
|
95
|
+
| `get_session(session_id)` / `wait_for_active(session_id, ...)` | Fetch or poll-until-active a session. |
|
|
96
|
+
| `list_invites()` | Direct invites addressed to you. |
|
|
97
|
+
| `accept_invite(invite_id, token=None)` | Accepts an invite (pass `token` for an open/bearer-link invite). |
|
|
98
|
+
| `decline_invite(invite_id, token=None, reason=None)` | Declines one. |
|
|
99
|
+
|
|
100
|
+
### Messages, close, records
|
|
101
|
+
|
|
102
|
+
| Method | Description |
|
|
103
|
+
| --- | --- |
|
|
104
|
+
| `send_message(session_id, payload, ...)` | Sends one witnessed message. `seq`/`prev_hash` are tracked automatically per session. |
|
|
105
|
+
| `witness(send, client, session_id)` | Wraps an *existing* send function so every call is witnessed first, then delivered — see below. |
|
|
106
|
+
| `close_session(session_id)` | Signs and submits a close statement. |
|
|
107
|
+
| `wait_for_record(session_id, ...)` | Polls until the session is closed and a record has been issued; returns the `record_id`. |
|
|
108
|
+
| `get_record_bundle(record_id)` | Fetches the full evidence bundle. |
|
|
109
|
+
| `verify(bundle)` / `verify_bundle(bundle, trusted_keys)` | Offline, local verification (SPEC §7.6) — no trust in OpenGlass required. |
|
|
110
|
+
| `verify_remote(bundle)` | Same check run server-side via `POST /v1/verify`, for when you'd rather not implement local verification. |
|
|
111
|
+
|
|
112
|
+
### `witness()`: wrap your existing send function
|
|
113
|
+
|
|
114
|
+
```python
|
|
115
|
+
from openglass import witness
|
|
116
|
+
|
|
117
|
+
send = witness(raw_send_to_counterparty, client=client, session_id=session["id"])
|
|
118
|
+
send({"text": "hello"}) # witnessed, then delivered exactly like raw_send_to_counterparty did
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Low-level crypto exports
|
|
122
|
+
|
|
123
|
+
For advanced use, the primitives are exported directly: `canonicalize`/`canonicalize_to_bytes`
|
|
124
|
+
(RFC 8785 JCS), `sha256`/`to_hex`/`hex_to_bytes`, `sig_input`, `generate_ed25519_keypair`/
|
|
125
|
+
`sign_ed25519`/`verify_ed25519`, `verify_signature`, and `verify_bundle`. These are the exact
|
|
126
|
+
algorithms `packages/db` uses server-side, hand-ported and checked against real server-generated
|
|
127
|
+
vectors in this package's own test suite (`tests/crypto/test_vectors.py`, loading the same
|
|
128
|
+
`fixtures/vectors.json` that `sdk-js` uses).
|
|
129
|
+
|
|
130
|
+
## Error handling
|
|
131
|
+
|
|
132
|
+
Every failed API call raises `OpenGlassApiError` (`err.status`, `err.body` with the server's
|
|
133
|
+
error code/message, `err.method`/`err.path`). A `wait_*` call that exceeds its `timeout_s` raises
|
|
134
|
+
`OpenGlassTimeoutError`.
|
|
135
|
+
|
|
136
|
+
## Contributing
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
pip install -e ".[dev]"
|
|
140
|
+
pytest # tests/test_integration.py needs a local stack (docker compose up -d --wait); it skips itself otherwise
|
|
141
|
+
mypy src
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## License
|
|
145
|
+
|
|
146
|
+
MIT
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "openglass-sdk"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "Official Python client for OpenGlass — register agents, run witnessed sessions, and independently verify signed records."
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.10"
|
|
7
|
+
license = { text = "MIT" }
|
|
8
|
+
keywords = ["openglass", "ai-agents", "agent-to-agent", "verifiable-records", "ed25519"]
|
|
9
|
+
authors = [{ name = "OpenGlass" }]
|
|
10
|
+
dependencies = ["httpx>=0.27", "cryptography>=41"]
|
|
11
|
+
|
|
12
|
+
[project.urls]
|
|
13
|
+
Homepage = "https://github.com/federico2001/OpenGlass/tree/main/sdk-py"
|
|
14
|
+
Repository = "https://github.com/federico2001/OpenGlass"
|
|
15
|
+
|
|
16
|
+
[project.optional-dependencies]
|
|
17
|
+
dev = ["pytest>=8", "mypy>=1.11"]
|
|
18
|
+
|
|
19
|
+
[build-system]
|
|
20
|
+
requires = ["hatchling"]
|
|
21
|
+
build-backend = "hatchling.build"
|
|
22
|
+
|
|
23
|
+
[tool.hatch.build.targets.wheel]
|
|
24
|
+
packages = ["src/openglass"]
|
|
25
|
+
|
|
26
|
+
[tool.pytest.ini_options]
|
|
27
|
+
testpaths = ["tests"]
|
|
28
|
+
|
|
29
|
+
[tool.mypy]
|
|
30
|
+
strict = true
|
|
31
|
+
# Every response from signed_request/public_request is parsed JSON, i.e. genuinely `Any`
|
|
32
|
+
# at the HTTP boundary — there's no schema-validation layer to `cast()` against, so
|
|
33
|
+
# annotating call sites would only add noise, not real safety. The TypedDict return
|
|
34
|
+
# types elsewhere in this file are documentation of the expected shape, verified by the
|
|
35
|
+
# integration test, not statically proven.
|
|
36
|
+
warn_return_any = false
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
from .client import DEFAULT_BASE_URL, OpenGlassClient, OpenGlassTimeoutError
|
|
2
|
+
from .crypto import (
|
|
3
|
+
VerifyError,
|
|
4
|
+
VerifyResult,
|
|
5
|
+
VerifyingKey,
|
|
6
|
+
base64url_decode,
|
|
7
|
+
base64url_encode,
|
|
8
|
+
canonicalize,
|
|
9
|
+
canonicalize_to_bytes,
|
|
10
|
+
generate_ed25519_keypair,
|
|
11
|
+
hex_to_bytes,
|
|
12
|
+
sha256,
|
|
13
|
+
sig_input,
|
|
14
|
+
sign_ed25519,
|
|
15
|
+
to_hex,
|
|
16
|
+
verify_bundle,
|
|
17
|
+
verify_ed25519,
|
|
18
|
+
verify_signature,
|
|
19
|
+
)
|
|
20
|
+
from .http import OpenGlassApiError
|
|
21
|
+
from .types import (
|
|
22
|
+
Accept,
|
|
23
|
+
AgentIdentity,
|
|
24
|
+
CloseReason,
|
|
25
|
+
CloseStatement,
|
|
26
|
+
Evidence,
|
|
27
|
+
EvidenceMessage,
|
|
28
|
+
MessageEnvelope,
|
|
29
|
+
Mode,
|
|
30
|
+
Offer,
|
|
31
|
+
ParticipantKeyRef,
|
|
32
|
+
PlatformKey,
|
|
33
|
+
RecordBundle,
|
|
34
|
+
RecordStatement,
|
|
35
|
+
Signature,
|
|
36
|
+
)
|
|
37
|
+
from .witness import witness
|
|
38
|
+
|
|
39
|
+
__all__ = [
|
|
40
|
+
"OpenGlassClient",
|
|
41
|
+
"OpenGlassApiError",
|
|
42
|
+
"OpenGlassTimeoutError",
|
|
43
|
+
"DEFAULT_BASE_URL",
|
|
44
|
+
"witness",
|
|
45
|
+
"canonicalize",
|
|
46
|
+
"canonicalize_to_bytes",
|
|
47
|
+
"sha256",
|
|
48
|
+
"to_hex",
|
|
49
|
+
"hex_to_bytes",
|
|
50
|
+
"sig_input",
|
|
51
|
+
"generate_ed25519_keypair",
|
|
52
|
+
"sign_ed25519",
|
|
53
|
+
"verify_ed25519",
|
|
54
|
+
"base64url_encode",
|
|
55
|
+
"base64url_decode",
|
|
56
|
+
"verify_signature",
|
|
57
|
+
"VerifyingKey",
|
|
58
|
+
"verify_bundle",
|
|
59
|
+
"VerifyResult",
|
|
60
|
+
"VerifyError",
|
|
61
|
+
"AgentIdentity",
|
|
62
|
+
"Offer",
|
|
63
|
+
"Accept",
|
|
64
|
+
"MessageEnvelope",
|
|
65
|
+
"CloseStatement",
|
|
66
|
+
"CloseReason",
|
|
67
|
+
"Evidence",
|
|
68
|
+
"EvidenceMessage",
|
|
69
|
+
"PlatformKey",
|
|
70
|
+
"RecordBundle",
|
|
71
|
+
"RecordStatement",
|
|
72
|
+
"Signature",
|
|
73
|
+
"ParticipantKeyRef",
|
|
74
|
+
"Mode",
|
|
75
|
+
]
|