Metadata-Version: 2.4
Name: archerprotocol-sdk
Version: 0.1.0
Summary: Build and monetize an Archer intent from Python: typed envelope builders, embeds, caller context, effect inference, and a one-call FastAPI handler.
License: Apache-2.0
Project-URL: Homepage, https://github.com/Archer-Laboratories/archer-sdk
Project-URL: Repository, https://github.com/Archer-Laboratories/archer-sdk
Project-URL: Issues, https://github.com/Archer-Laboratories/archer-sdk/issues
Keywords: archer,archer-protocol,intent,partner-sdk,fastapi,ed25519
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Requires-Python: >=3.9
Description-Content-Type: text/markdown
Requires-Dist: archer-verify>=0.1.0
Provides-Extra: fastapi
Requires-Dist: fastapi>=0.110; extra == "fastapi"
Requires-Dist: starlette>=0.36; extra == "fastapi"
Provides-Extra: dev
Requires-Dist: pytest>=8; extra == "dev"
Requires-Dist: httpx>=0.27; extra == "dev"
Requires-Dist: fastapi>=0.110; extra == "dev"

# archerprotocol-sdk

Build, monetize, and publish an Archer intent from Python. This package
mirrors the Node `@archerprotocol/sdk` builder surface; both are held to the
same shared test vectors, so an envelope built here is byte-identical to one
built in TypeScript.

```bash
pip install "archerprotocol-sdk[fastapi]"
```

## One-call handler (FastAPI)

```python
from fastapi import FastAPI
from archer_sdk import archer, require_archer_caller, BadInputError
from archer_sdk.fastapi import mount_archer_tools

app = FastAPI()

async def deposit(ctx):
    caller = require_archer_caller(ctx.args)
    amount = ctx.args.get("amount")
    if not amount:
        raise BadInputError('amount is required (e.g. "1.5")')
    return archer.envelope(
        cost=archer.cost(model="embedded", archer_fee_micro=200),
        authorizations=[
            archer.authorization(
                type="tx",
                namespace="evm",
                label=f"Deposit {amount} USDC",
                payload={"chainId": 8453, "to": "0x...", "data": "0x...", "value": "0x0"},
            )
        ],
        record=archer.record(
            record_kind="position",
            basis_micro=1_000_000,
            disclosure={"custody": "SELF", "exitModel": "PERMISSIONLESS"},
        ),
    )

mount_archer_tools(app, {"/deposit": deposit})
```

The handler verifies the signed Archer envelope (via `archer-verify`),
hands you `ctx.args / ctx.caller / ctx.request_id / ctx.intent_definition_id /
ctx.user_id`, and wraps your return in the partner response envelope.
Raise `BadInputError` (400) or `UpstreamError` (503) for clean failures.

## Reads

Return the flat render payload instead of an envelope:

```python
from archer_sdk import archer

async def price_chart(ctx):
    return archer.render(
        text="ETH, last 30 days",
        embed=archer.embed.chart(chart_type="line", data=[{"x": "2026-01", "y": 3000}]),
    )
```

## Effect inference (pre-flight)

`infer_effects` is the same function the platform runs server-side to decode
a `sign` authorization into a verified, bounded confirmation. Run it locally
against your descriptors to see exactly what the user's confirmation screen
will derive; the platform always re-derives its own report.

```python
from archer_sdk import infer_effects

report = await infer_effects(auth, descriptors=my_descriptors, price=my_price_fn)
assert report["verdict"] == "DECODED_BOUNDED"
```

## Publishing

Publishing and lifecycle management use the Node CLI, which works without a
Node project: `npx @archerprotocol/sdk` gives you `archer init / publish /
activate / stats`.
