Metadata-Version: 2.4
Name: logicnodes-pol
Version: 1.0.0
Summary: Reference verifier and signer for the POL/1.0 (Proof-of-Logic) verifiable work-receipt standard.
Author-email: LogicNodes <hello@logicnodes.io>
License: MIT
Project-URL: Homepage, https://logicnodes.io
Project-URL: Specification, https://logicnodes.io/agents/pol/spec/1.0
Project-URL: Documentation, https://logicnodes.io/pol-spec.html
Keywords: pol,proof-of-logic,verifiable,receipt,eip-191,m2m,agent,escrow,logicnodes
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Security :: Cryptography
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: eth-account>=0.10.0
Requires-Dist: eth-utils>=2.0.0
Dynamic: license-file

# logicnodes-pol

Reference verifier and signer for **POL/1.0 (Proof-of-Logic)** — an open standard for
verifiable work receipts in a machine-to-machine economy.

- Spec (machine-readable): https://logicnodes.io/agents/pol/spec/1.0
- Spec (human-readable): https://logicnodes.io/pol-spec.html
- License: MIT (this library); the POL/1.0 spec itself is CC-BY-4.0

A POL receipt is a small signed attestation that a defined condition was deterministically
evaluated against a worker's output and produced a verdict. **Verification is a pure function
of the receipt and the issuer's public signer address — no secret, no account, and no network
call required.**

## Install

```bash
pip install logicnodes-pol
```

## Verify a receipt (Python)

```python
from logicnodes_pol import verify_receipt

receipt = {
    "payload": {
        "receipt": "0x77102c0e...",
        "escrow_id": "0xa8bff8e8...",
        "agent": "example-worker",
        "output_hash": "0x839ee4b2...",
        "verified": True,
        "amount_usdc": 0.01,
        "settlement_tx": None,
        "chain": "base",
    },
    "signature": {
        "standard": "EIP-191",
        "signer": "0x0D12B2B82e4aE84A15a032C31C6A8a23520Ecde7",
        "payload_hash": "0xe2dc732e...",
        "signature": "6738841a...",
    },
}

result = verify_receipt(receipt)
print(result.verified)            # True
print(result.recovered_signer)    # 0x0D12B2B82e4aE84A15a032C31C6A8a23520Ecde7
print(result.payload_hash_matches)  # True
```

If any field in the signed body is altered after signing, `payload_hash_matches` becomes
`False` and `verified` becomes `False` — the receipt is rejected even though the signature
itself is still mathematically valid over the original hash.

## Verify from the command line

```bash
# verify a receipt file against the default logicnodes.io issuer
pol verify receipt.json

# verify against a different issuer signer
pol verify receipt.json --signer 0xYourIssuerSigner

# machine-readable output
pol verify receipt.json --json

# read from stdin
cat receipt.json | pol verify -

# print the canonical payload_hash of a receipt body
pol hash receipt.json
```

`pol verify` exits `0` on PASS and `1` on FAIL, so it composes in CI and shell pipelines.

## Sign a receipt (POL/1.0-Producer)

```python
from logicnodes_pol import sign_receipt

signed = sign_receipt(
    {"receipt": "0x...", "verified": True, "agent": "my-worker", "amount_usdc": 0.01, "chain": "base"},
    private_key="0x...",
)
```

## How verification works (POL/1.0 §05)

1. **Canonicalize** the signed body: JSON with `sort_keys=True`, compact separators,
   `_verification` key dropped.
2. **Hash**: `payload_hash = "0x" + sha256(canonical)`.
3. **Recover**: EIP-191 `encode_defunct(hexstr=payload_hash)` → ecrecover the signer.
4. **Decide**: a receipt is verified when the derived hash equals the claimed `payload_hash`
   **and** the recovered signer equals the expected issuer.

This library implements both the **POL/1.0-Verifier** and **POL/1.0-Producer** conformance
profiles.
