# XamiLib Python — Referencia de clases

Paquete: `xamisdk_client`. El punto de entrada es la clase `XamiSDK`. Los métodos siguen
la convención Python (snake_case). La interfaz es equivalente a la de PHP.

---

## `XamiSDK`

Punto de entrada de la librería.

### Constructor

```python
XamiSDK(config: dict)
```

`config` acepta:

| Clave | Descripción |
|---|---|
| `endpoint` | URL del servicio local (por defecto `http://127.0.0.1:8300`). |
| `wrapper_key` | Credencial de aplicación (`wrp_...`). |
| `wrapper_secret` | Secret de la credencial (`wsec_...`). |
| `timeout` | Timeout HTTP en segundos (opcional). |

### Métodos

| Método | Devuelve | Descripción |
|---|---|---|
| `pades()` | `Pades` | Servicio de firma de documentos PDF. |
| `blockchain()` | `Blockchain` | Servicio de firma de transacciones EVM. |
| `credentials()` | `Credentials` | Consulta de credenciales. |
| `designs()` | `Designs` | Consulta de diseños de sello. |
| `health()` | `Health` | Estado del servicio local. |

---

## `Pades`

Firma de documentos PDF (PAdES).

### Métodos

#### `sign(pdf_bytes: bytes, opts: dict) -> str`
Envía un PDF a firmar. Devuelve el `request_id`. `opts`: `credential_key` (requerido),
`design_key`, `variables`, `reason`, `location`, `signer_name`.

#### `result(request_id: str) -> dict`
Consulta el estado. Cuando está `DONE`, incluye el PDF firmado en la clave `pdf`.

#### `wait(request_id: str, timeout_seconds: int = 60, poll_seconds: float = 1.0) -> bytes`
Bloquea hasta que la firma esté lista y devuelve el PDF firmado (bytes).

#### `sign_and_wait(pdf_bytes: bytes, opts: dict, timeout_seconds: int = 60) -> bytes`
Atajo: `sign()` + `wait()`. Devuelve el PDF firmado.

### Ejemplo

```python
pdf_firmado = xami.pades().sign_and_wait(
    open("documento.pdf", "rb").read(),
    {
        "credential_key": "TU_CREDENCIAL",
        "signer_name": "Tu Nombre",
        "reason": "Aprobación",
        "variables": {"name": "Tu Nombre"},
    },
)
open("documento_firmado.pdf", "wb").write(pdf_firmado)
```

---

## `Blockchain`

Firma de transacciones / mensajes EVM. El chip actúa como wallet y devuelve `r`/`s`/`v`;
tú ensamblas la transacción con tu web3.

### Métodos

#### `sign(tx_hash: str, opts: dict) -> str`
Envía el hash a firmar. Devuelve el `request_id`. `opts`: `credential_key` (requerido,
credencial EVM), `chain_id`.

#### `result(request_id: str) -> dict`
Consulta el estado.

#### `wait(request_id: str, timeout_seconds: int = 60, poll_seconds: float = 1.0) -> dict`
Bloquea hasta tener la firma. Devuelve `{"r": ..., "s": ..., "v": ..., "signature": ...}`.

#### `sign_and_wait(tx_hash: str, opts: dict, timeout_seconds: int = 60) -> dict`
Atajo: `sign()` + `wait()`.

### Ejemplo

```python
firma = xami.blockchain().sign_and_wait("0xHASH_DE_LA_TX", {
    "credential_key": "TU_CREDENCIAL_EVM",
    "chain_id": 648541,
})
# firma["r"], firma["s"], firma["v"]
```

---

## `Credentials`

Consulta de credenciales en la caché local.

| Método | Devuelve | Descripción |
|---|---|---|
| `all() -> list` | lista | Todas las credenciales disponibles. |
| `get(key: str)` | credencial o `None` | Una credencial por su `credential_key`. |

---

## `Designs`

Consulta de diseños de sello en la caché local.

| Método | Devuelve | Descripción |
|---|---|---|
| `all() -> list` | lista | Todos los diseños disponibles. |
| `get(key: str)` | diseño o `None` | Un diseño por su `design_key`. |

---

## `Health`

| Método | Devuelve | Descripción |
|---|---|---|
| `self() -> dict` | estado | Estado del servicio local (pareado, tenant, etc.). |

---

## Manejo de errores

Todos los métodos lanzan `xamisdk_client.XamiException` ante un fallo (credencial
inválida, servicio caído, timeout). Envuélvelos en `try/except`.

```python
from xamisdk_client import XamiException

try:
    pdf = xami.pades().sign_and_wait(pdf_bytes, {"credential_key": "..."})
except XamiException as e:
    print("Error al firmar:", e)
```
