Metadata-Version: 2.4
Name: blockauth-sdk
Version: 0.5.0
Summary: BlockAuth Auth SDK (Python) — blockchain-based authentication client.
Author: Block-Auth.io Team
License-Expression: ISC
Project-URL: Homepage, https://block-auth.io
Project-URL: Repository, https://gitlab.com/blockauthio/blockauth-sdk-python
Project-URL: Issues, https://gitlab.com/blockauthio/blockauth-sdk-python/-/issues
Keywords: blockauth,authentication,blockchain,web3,socket.io,sdk
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Security
Classifier: Topic :: Software Development :: Libraries
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: python-socketio[client]<6,>=5.11
Provides-Extra: dev
Requires-Dist: pytest>=8; extra == "dev"
Requires-Dist: pytest-cov>=5; extra == "dev"
Dynamic: license-file

# BlockAuth SDK (Python)

Cliente headless del servicio de autenticación BlockAuth (Socket.IO v4).
Puerto de referencia de la capa de protocolo de `@block-auth.io/core`
(monorepo `blockauth-sdk`, patrón *headless core + thin per-framework adapters*).

## Arquitectura

Este puerto replica la capa `protocol/` del core TypeScript; la reactividad y
la UI de los bindings (React/Vue/Angular) quedan fuera de alcance.

| Este repo | Upstream (`blockauth-sdk`) |
| :--- | :--- |
| `blockauth_sdk/protocol/provider.py` | `packages/core/src/protocol/BlockAuthProvider.ts` |
| `blockauth_sdk/protocol/ws_client.py` | `packages/core/src/protocol/WsClient.ts` |
| `blockauth_sdk/protocol/rpc_client.py` | `packages/core/src/protocol/RpcClient.ts` |
| `blockauth_sdk/protocol/roles.py` | `packages/core/src/protocol/roles.ts` |
| `blockauth_sdk/protocol/transport.py` | — (abstracción propia del puerto; upstream usa socket.io directo) |
| `blockauth_sdk/api_bridge.py` | `packages/core/src/utils/apiBridge.ts` (solo la emisión del browser token) |
| `blockauth_sdk/crypto.py`, `blockauth_sdk/errors.py` | — (infra propia del puerto) |

La API pública se re-exporta desde la raíz del paquete (`from blockauth_sdk import
BlockAuthProvider`), igual que hace el `index.ts` del core.

## Instalación

```bash
pip install blockauth-sdk
```

## Uso

Un backend se autentica con su `apiKey` y su `apiSecret`. El `apiSecret` solo
vive en el backend.

```python
from blockauth_sdk import BlockAuthProvider

provider = BlockAuthProvider(api_key="YOUR_API_KEY", api_secret="YOUR_API_SECRET")
provider.connect()

result = provider.signin()
if result["success"]:
    profile = provider.user("0xUserAddress")
    print(provider.role_names)

provider.disconnect()
```

No autentiques un backend con un browser token: el ws-server lo rechaza (exige
un `Origin` de confianza y su scope no da acceso a `user`, `users`, `roles` ni
`logs`).

### Login por redirección

Para que tus usuarios inicien sesión con BlockAuth, tu backend los manda al
login alojado y recibe de vuelta un código de un solo uso, que canjea por la
dirección y los roles del usuario. La dirección la da el ws-server, nunca el
navegador.

```python
import json
import secrets
import urllib.error
import urllib.request

from blockauth_sdk.api_bridge import build_ws_server_api_url
from blockauth_sdk.crypto import sha256_hex


def post(path, body):
    request = urllib.request.Request(
        build_ws_server_api_url(path),
        data=json.dumps(body).encode("utf-8"),
        headers={"Content-Type": "application/json"},
    )
    try:
        with urllib.request.urlopen(request) as response:
            data = json.load(response)
    except urllib.error.HTTPError as err:  # los errores llegan como 400 con el mismo JSON
        data = json.load(err)
    if not data.get("success"):
        raise RuntimeError(data.get("message"))
    return data["message"]


credentials = {"apiKey": "YOUR_API_KEY", "apiSecret": sha256_hex("YOUR_API_SECRET")}
redirect_uri = "https://tuapp.com/callback"

# 1. Pide el enlace de login y redirige al usuario a él.
state = secrets.token_hex(16)  # guárdalo en la sesión
link = post("/auth/authorize", {**credentials, "redirectUri": redirect_uri, "state": state})["url"]

# 2. El usuario vuelve a redirect_uri?code=...&state=... Comprueba que el state es el de la sesión.

# 3. Canjea el código (válido 60 s, un solo uso).
user = post("/auth/token", {**credentials, "code": code, "redirectUri": redirect_uri})
address = user["address"]  # también: roles, signedExpiredAt
```

- El `redirect_uri` tiene que ser `https` en el dominio (o el dominio de
  desarrollo) de la app; `http` solo en `localhost`.
- Para cerrar la sesión del usuario en tu app: `post("/auth/signout",
  {**credentials, "address": address})`.

### Browser token para tu frontend

Si tu frontend usa `@block-auth.io/core`, el backend le emite un browser token
para que el `apiSecret` no salga nunca del backend:

```python
provider = BlockAuthProvider(api_key="YOUR_API_KEY", api_secret="YOUR_API_SECRET")
browser_token = provider.create_browser_token()
```

El frontend lo usa como `browserToken` en `@block-auth.io/core`.

## API

`BlockAuthProvider`: `connect`, `disconnect`, `is_connected`, `signin`, `create_browser_token`, `refresh`,
`is_address_signed`, `app`, `user`, `users`, `roles`, `logs`, `kyc_issuer`,
helpers de roles (`has_role`, `has_role_by_slug`, `has_any_role`,
`has_any_role_by_slug`) y getters (`current_user`, `role_names`, `ui_config`, …).

## Tests

```bash
pip install -e ".[dev]"
pytest
```

## Smoke test contra un servidor real

Los tests usan un transporte simulado. Para probar el SDK contra el ws-server
de PRE (transporte real, login por redirección y canje del código), usa la app
de prueba de [`examples/test_app/`](https://gitlab.com/blockauthio/blockauth-sdk-python/-/tree/main/examples/test_app).
