> ## Documentation Index
> Fetch the complete documentation index at: https://developers.ebioro.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Inicio de Sesión en el Hub del Wallet

> Lista tu tienda en el wallet de Ebioro y recibe usuarios ya autenticados

## Resumen

El **Hub** de la app del wallet de Ebioro lista tiendas asociadas. Cuando un usuario abre tu tienda desde el Hub, Ebioro puede entregarle un token firmado que identifica al usuario, de modo que llega **ya autenticado** — sin registro ni inicio de sesión aparte. La tienda se abre dentro de la app en un webview.

Es un canal de distribución para comercios: aparece en el Hub, y cada usuario del wallet es un cliente potencial a un toque.

Hay dos formas de listar una tienda:

<CardGroup cols={2}>
  <Card title="Sin autenticación" icon="store" color="#0092DF">
    Registra una sola **URL de webview** y Ebioro la abre directamente desde el Hub. Ideal para un catálogo público sin cuentas de usuario.
  </Card>

  <Card title="Con inicio de sesión" icon="right-to-bracket" color="#04394F">
    Ebioro entrega a tu **endpoint de autenticación** un token firmado, de modo que el usuario llega a una sesión que tú creaste — **ya autenticado**. Ideal cuando los usuarios tienen cuentas en tu tienda.
  </Card>
</CardGroup>

<Info>
  Las tiendas las lista Ebioro, no es autoservicio. Para aparecer en el Hub — y para registrar tu endpoint de autenticación, ícono y los headers personalizados — contáctanos en [support@ebioro.com](mailto:support@ebioro.com).
</Info>

## Cómo funciona el inicio de sesión autenticado

<Steps>
  <Step title="El usuario abre tu tienda" icon="hand-pointer">
    El usuario toca tu tienda en el Hub del wallet.
  </Step>

  <Step title="Ebioro firma un token" icon="signature">
    Un **JWT** de corta duración con el nombre, apellido, correo y teléfono del usuario.
  </Step>

  <Step title="Ebioro llama a tu endpoint" icon="paper-plane">
    Un `POST` a tu **endpoint de autenticación** registrado con `{ "token": "<jwt>" }`.
  </Step>

  <Step title="Verificas el token" icon="shield-check">
    Comprueba la firma y la expiración antes de confiar en cualquier campo.
  </Step>

  <Step title="Inicias una sesión" icon="user-check">
    Busca o crea al usuario (por correo o teléfono) y abre una sesión.
  </Step>

  <Step title="Devuelves un enlace" icon="link">
    Responde con `{ "url": "<enlace autenticado>" }`.
  </Step>

  <Step title="El usuario queda autenticado" icon="mobile-screen">
    Ebioro abre esa URL en el webview dentro de la app — el usuario llega ya autenticado.
  </Step>
</Steps>

## Tu endpoint de autenticación

Registra un endpoint HTTPS que reciba el token y devuelva una URL de sesión.

**Solicitud** — Ebioro llama a tu endpoint:

```http theme={null}
POST /tu/endpoint/auth
Content-Type: application/json

{ "token": "<JWT>" }
```

Los **headers personalizados** que acuerden al momento del listado (por ejemplo un `x-api-key` compartido) se envían con esta solicitud, para que tu endpoint pueda confirmar que la llamada realmente vino de Ebioro.

**Respuesta** — devuelve la URL que abre una sesión autenticada:

```json theme={null}
{ "url": "https://tu-tienda.com/sesion?token=abc123" }
```

Ebioro abre ese `url` en el webview. Devuelve HTTP `200` con un campo `url`; cualquier otra cosa se considera un fallo.

## El token

|           |                 |
| --------- | --------------- |
| Algoritmo | EdDSA (Ed25519) |
| Vigencia  | 2 horas         |

Payload:

```json theme={null}
{
  "name": "Carlos",
  "lastName": "García",
  "email": "carlos@example.com",
  "phone": "+5355555555",
  "iat": 1718131200,
  "exp": 1718138400
}
```

### Obtener la clave pública

Ebioro firma con su clave de firma Stellar. La clave pública correspondiente se publica en el campo `SIGNING_KEY` del Stellar TOML:

| Entorno           | URL del TOML                                                 |
| ----------------- | ------------------------------------------------------------ |
| Pruebas (sandbox) | `https://test-walletapi.ebioro.com/.well-known/stellar.toml` |
| Producción        | `https://api.ebioro.com/.well-known/stellar.toml`            |

La clave está en formato Stellar `G...`. Para verificar un JWT Ed25519 estándar, conviértela a un objeto de clave pública como se muestra abajo.

### Verificar el token (Node.js)

```javascript theme={null}
import { StrKey, StellarToml } from '@stellar/stellar-sdk';
import { jwtVerify } from 'jose';
import { createPublicKey } from 'crypto';

// Sandbox: test-walletapi.ebioro.com — Producción: api.ebioro.com
const EBIORO_DOMAIN = process.env.EBIORO_DOMAIN || 'test-walletapi.ebioro.com';

// El host del webview de tu tienda registrado en Ebioro — el claim `aud` del token.
const STORE_HOST = 'www.example.store';

let cachedKey; // La clave de firma rara vez cambia — obtén el TOML una vez y reutilízalo.

async function getSigningKey() {
  if (cachedKey) return cachedKey;
  const toml = await StellarToml.Resolver.resolve(EBIORO_DOMAIN);
  cachedKey = toml.SIGNING_KEY; // clave pública Stellar G...
  return cachedKey;
}

export async function verifyEbioroToken(token: string) {
  const stellarPublicKey = await getSigningKey();

  // Convierte la clave Stellar G... en una clave pública Ed25519 SPKI
  const rawPublicKey = StrKey.decodeEd25519PublicKey(stellarPublicKey);
  const spkiPrefix = Buffer.from('302a300506032b6570032100', 'hex');
  const spkiKey = Buffer.concat([spkiPrefix, rawPublicKey]);
  const publicKey = createPublicKey({ key: spkiKey, format: 'der', type: 'spki' });

  // Lanza un error si la firma es inválida o el token expiró
  // Lanza un error si la firma es inválida, el token expiró, o la audiencia no
  // coincide. STORE_HOST es el host del webview de tu tienda registrado en Ebioro
  // (p. ej. 'www.example.store').
  const { payload } = await jwtVerify(token, publicKey, { audience: STORE_HOST });
  return payload; // { name, lastName, email, phone, aud, iat, exp }
}
```

La llamada a `jwtVerify` comprueba la firma, la expiración (`exp`) y la audiencia (`aud`). Con el payload verificado, busca al usuario por correo o teléfono, créalo si no existe, inicia una sesión y devuelve su URL.

### Verifica la audiencia

Cada token que Ebioro firma está acotado a una sola tienda: su claim `aud` se fija en **el host del webview de tu tienda** (el hostname de la URL de webview que registraste, p. ej. `www.example.store`). Pasa ese valor como la opción `audience` a `jwtVerify`, como se muestra arriba.

Verificar `aud` garantiza que un token emitido para otra tienda no pueda reutilizarse contra tu endpoint. Es opcional pero muy recomendable — sin ello, se aceptaría cualquier token válido de Ebioro. Si no estás seguro del host exacto registrado para tu tienda, pregúntanos al momento de la incorporación.

<Warning>
  El ejemplo usa por defecto la clave de **sandbox**. Antes de pasar a producción, define `EBIORO_DOMAIN` como `api.ebioro.com` — verificar tokens de producción con la clave de sandbox hará fallar todos los inicios de sesión.
</Warning>

<Warning>
  Verifica siempre la firma antes de confiar en cualquier campo del token, y confirma los headers personalizados acordados con Ebioro. Nunca autentiques a un usuario con un token sin verificar.
</Warning>

## Tiendas sin autenticación

Si tu tienda no tiene cuentas de usuario, puedes omitir todo lo anterior: registra una sola **URL de webview** y Ebioro la abre directamente desde el Hub. Sin token, sin endpoint. Contáctanos para configurarlo.
