# botindex-aar

Python SDK for **Agent Action Receipts (AAR)**.

This package is a Python 3.9+ port of the TypeScript SDK in `ts-reference/`, with:
- Ed25519 signing via `PyNaCl`
- `JCS-SORTED-UTF8-NOWS` canonicalization
- SHA-256 input/output hashing with base64url digests
- receipt creation and verification
- FastAPI and Flask middleware
- Mastercard Verifiable Intent compatibility mapping

## Install

```bash
pip install botindex-aar
```

## Quick Start

```python
from botindex_aar import (
    create_receipt,
    generate_key_pair,
    hash_input,
    hash_output,
    sign_and_finalize,
    verify_receipt,
)

keys = generate_key_pair()

unsigned = create_receipt({
    "agent": {"id": "trading-bot/v2", "name": "TradingBot"},
    "principal": {"id": "user:alice", "type": "user"},
    "action": {
        "type": "trade.execute",
        "target": "binance/BTCUSDT",
        "method": "POST",
        "status": "success",
    },
    "scope": {"permissions": ["trade.spot"]},
    "inputHash": hash_input({"pair": "BTCUSDT", "side": "buy", "qty": 0.5}),
    "outputHash": hash_output('{"orderId":"12345","filled":0.5}'),
    "cost": {"amount": "0.02", "currency": "USDC"},
})

receipt = sign_and_finalize(unsigned, keys.secretKey)
result = verify_receipt(receipt)
assert result.ok
```

## Middleware

### FastAPI

```python
from fastapi import FastAPI
from botindex_aar.middleware.fastapi import AARMiddleware

app = FastAPI()
app.add_middleware(
    AARMiddleware,
    agent_id="my-agent/v1",
    secret_key="<base64url-or-base64-or-pem-secret>",
)
```

### Flask

```python
from flask import Flask
from botindex_aar.middleware.flask import install_aar_middleware

app = Flask(__name__)
install_aar_middleware(
    app,
    agent_id="my-agent/v1",
    secret_key="<base64url-or-base64-or-pem-secret>",
)
```

## API Reference

### Core
- `generate_key_pair()` / `generateKeyPair()`
- `load_secret_key(input)` / `loadSecretKey(input)`
- `public_key_from_secret(secret)` / `publicKeyFromSecret(secret)`
- `create_receipt(opts)` / `createReceipt(opts)`
- `sign_receipt(unsigned, secret)` / `signReceipt(unsigned, secret)`
- `sign_and_finalize(unsigned, secret)` / `signAndFinalize(unsigned, secret)`
- `verify_receipt(receipt, public_key=None)` / `verifyReceipt(...)`
- `hash_input(data)` / `hashInput(data)`
- `hash_output(data)` / `hashOutput(data)`
- `canonicalize(value)`
- `canonicalize_for_signing(receipt)` / `canonicalizeForSigning(receipt)`
- `encode_receipt_header(receipt)` / `encodeReceiptHeader(receipt)`

### Encoding
- `utf8_encode`, `utf8_decode`
- `encode_base64`, `decode_base64`
- `encode_base64url`, `decode_base64url`

### Discovery
- `build_well_known_config(options)` / `buildWellKnownConfig(options)`
- `well_known_handler(options)` / `wellKnownHandler(options)`

### Compatibility
- `aar_to_verifiable_intent(receipt)` / `aarToVerifiableIntent(receipt)`
- `verifiable_intent_to_aar(record)` / `verifiableIntentToAAR(record)`

## Typing

The package ships with `py.typed` (PEP 561).

## License

MIT
