# XamiLib PHP — Referencia de clases

Namespace: `Xami\SDK`. El punto de entrada es la clase `XamiSDK`, que da acceso a los
distintos servicios.

---

## `XamiSDK`

Punto de entrada de la librería.

### Constructor

```php
new XamiSDK(array $config)
```

`$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. |
| `results()` | `Results` | Resultados de firma recientes. *(xamiSDK ≥ 0.2.0)* |
| `errors()` | `Errors` | Errores registrados por el servicio local. *(xamiSDK ≥ 0.2.0)* |
| `sync(): array` | resumen | Recarga credenciales y diseños desde Xami sin reiniciar. *(xamiSDK ≥ 0.2.0)* |

---

## `Pades`

Firma de documentos PDF (PAdES).

### Métodos

#### `sign(string $pdfBytes, array $opts): string`
Envía un PDF a firmar. Devuelve el `request_id`. `$opts`: `credential_key` (requerido),
`design_key`, `variables`, `reason`, `location`, `signer_name`.

#### `result(string $requestId): array`
Consulta el estado. Cuando está `DONE`, incluye el PDF firmado.

#### `wait(string $requestId, int $timeoutSeconds = 60, float $pollSeconds = 1.0): string`
Bloquea hasta que la firma esté lista y devuelve el PDF firmado (binario).

#### `signAndWait(string $pdfBytes, array $opts, int $timeoutSeconds = 60): string`
Atajo: `sign()` + `wait()`. Devuelve el PDF firmado.

### Ejemplo

```php
$pdfFirmado = $xami->pades()->signAndWait(
    file_get_contents('documento.pdf'),
    [
        'credential_key' => 'TU_CREDENCIAL',
        'signer_name'    => 'Tu Nombre',
        'reason'         => 'Aprobación',
        'variables'      => ['name' => 'Tu Nombre'],
    ]
);
file_put_contents('documento_firmado.pdf', $pdfFirmado);
```

---

## `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(string $txHash, array $opts): string`
Envía el hash a firmar. Devuelve el `request_id`. `$opts`: `credential_key` (requerido,
credencial EVM), `chain_id`.

#### `result(string $requestId): array`
Consulta el estado.

#### `wait(string $requestId, int $timeoutSeconds = 60, float $pollSeconds = 1.0): array`
Bloquea hasta tener la firma. Devuelve `['r' => ..., 's' => ..., 'v' => ...]`.

#### `signAndWait(string $txHash, array $opts, int $timeoutSeconds = 60): array`
Atajo: `sign()` + `wait()`.

### Ejemplo

```php
$firma = $xami->blockchain()->signAndWait('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(): array` | lista | Todas las credenciales disponibles. |
| `get(string $key): ?array` | credencial o `null` | Una credencial por su `credential_key`. |

---

## `Designs`

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

| Método | Devuelve | Descripción |
|---|---|---|
| `all(): array` | lista | Todos los diseños disponibles. |
| `get(string $key): ?array` | diseño o `null` | Un diseño por su `design_key`. |

---

## `Health`

| Método | Devuelve | Descripción |
|---|---|---|
| `self(): array` | estado | Estado del servicio local (pareado, tenant, versión, etc.). |
| `version(): ?string` | versión | Versión del xamiSDK local. `null` si es anterior a 0.2.0. |
| `apiVersion(): int` | entero | Versión del contrato local. `1` = sin `sync()`, `results()` ni `errors()`. |

---

## `Results`

*Requiere xamiSDK ≥ 0.2.0.*

`Pades::result()` necesita que conserves el `requestId`. Si tu proceso se reinició o el
push no llegó, ese documento quedaba inalcanzable desde la librería. Con `Results` puedes
recuperar lo firmado sin depender de tu propio almacenamiento.

| Método | Devuelve | Descripción |
|---|---|---|
| `recent(int $limit = 50): array` | lista | Últimos resultados (`PENDING` / `DONE` / `ERROR`). |
| `pending(int $limit = 50): array` | lista | Solo los que siguen esperando la firma del chip. |

```php
foreach ($xami->results()->pending() as $r) {
    echo $r['request_id'], ' lleva esperando desde ', $r['created_at'], PHP_EOL;
}
```

---

## `Errors`

*Requiere xamiSDK ≥ 0.2.0.*

Devuelve el mensaje corto y el `error_id` de cada fallo. **Nunca devuelve el traceback**:
el detalle técnico solo sale del equipo del cliente cuando alguien ejecuta
`xamisdk report`. Está pensado para que tu aplicación pueda decirle al usuario qué falló
y con qué identificador pedir soporte.

| Método | Devuelve | Descripción |
|---|---|---|
| `recent(int $limit = 20): array` | lista | Últimos errores registrados. |
| `forRequest(string $requestId): array` | lista | Errores de un request concreto. |

```php
$fallos = $xami->errors()->forRequest($requestId);
if ($fallos) {
    echo 'No se pudo firmar: ', $fallos[0]['short'], PHP_EOL;
    echo 'Menciona ', $fallos[0]['error_id'], ' al pedir soporte.', PHP_EOL;
}
```

---

## Compatibilidad de versiones

Los métodos marcados con *xamiSDK ≥ 0.2.0* devuelven `404` contra un servicio anterior.
Compruébalo antes si no controlas la versión instalada:

```php
if ($xami->health()->apiVersion() >= 2) {
    $xami->sync();
}
```

---

## Manejo de errores

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

```php
use Xami\SDK\XamiException;

try {
    $pdf = $xami->pades()->signAndWait($bytes, ['credential_key' => '...']);
} catch (XamiException $e) {
    error_log('Error al firmar: ' . $e->getMessage());
}
```
