apacuana-sdk-web
Version:
Apacuana SDK for Web
932 lines (697 loc) • 25.8 kB
Markdown
# Apacuana SDK for Web
## 1. Introducción
El **Apacuana SDK for Web** es una librería de cliente diseñada para integrar las funcionalidades de la plataforma Apacuana en cualquier aplicación web.
Este SDK actúa como una capa de abstracción sobre `apacuana-sdk-core`, facilitando operaciones criptográficas complejas directamente en el navegador del cliente. Utiliza tecnologías web estándar como la **Web Crypto API** para la generación de claves y la firma de documentos, y **IndexedDB** para el almacenamiento seguro y persistente de material criptográfico (certificados y claves privadas) en el dispositivo del usuario.
### Tabla de Contenidos
- [Instalación](#1-instalación)
- [Importación](#2-importación)
- [Configuración y conceptos clave](#3-configuración-y-conceptos-clave)
- [Inicialización del SDK](#4-inicialización-del-sdk)
- [Conceptos Clave](#conceptos-clave)
- [Tipos de Integración](#tipos-de-integración)
- [Acceso a funciones públicas/privadas](#acceso-a-funciones-públicasprivadas)
- [Referencia de la API](#referencia-de-la-api)
- [Métodos públicos](#métodos-públicos)
- [getCertTypes](#getcerttypes)
- [getCertRequerimentsByType](#getcertrequerimentsbytypeparams)
- [createApacuanaUser](#createapacuanauseruserdata)
- [Métodos privados](#métodos-privados)
- [getCustomer](#getcustomer)
- [generateCert](#generatecertparams)
- [getCertStatus](#getcertstatus)
- [addSigner](#addsignerparams)
- [getDocsByCustomer](#getdocsbycustomerparams)
- [signDocument](#signdocumentparams)
- [uploadSignatureVariant](#uploadsignaturevariantparams)
- [getSignatureVariant](#getsignaturevariant)
- [deleteSignatureVariant](#deletesignaturevariant)
- [startLivenessCheck](#startlivenesscheckcontainer)
- [requestRevocation](#requestrevocationparams)
- [getRevocationReasons](#getrevocationreasons)
- [importCertificate](#importcertificateparams)
- [exportCertificateInJSON](#exportcertificateinjsonparams)
- [isCertificateInDevice](#iscertificateindevice)
- [Manejo de Errores](#5-manejo-de-errores)
---
## Guía de Inicio Rápido
Esta sección te muestra cómo comenzar a usar el SDK Web de Apacuana en tu proyecto, desde la instalación hasta la inicialización y primer uso.
### 1. Instalación
Instala el SDK usando npm o yarn:
```bash
npm install apacuana-sdk-web
# o
yarn add apacuana-sdk-web
```
### 2. Importación
Importa la instancia única y preconfigurada del SDK en tu proyecto:
```javascript
import { apacuanaWeb } from "apacuana-sdk-web";
```
### 3. Configuración y conceptos clave
Antes de inicializar el SDK, asegúrate de tener los datos de configuración proporcionados por Apacuana:
- `apiUrl`: URL base de la API de Apacuana.
- `secretKey`: Clave secreta de tu integración.
- `apiKey`: API Key de tu integración.
- `verificationId`: ID de verificación de tu cliente.
- `customerId`: (Opcional) ID único del usuario/cliente. Necesario para funciones privadas.
- `integrationType`: Tipo de integración (`ONBOARDING` recomendado).
> **Nota:** Si inicializas el SDK sin `customerId`, solo tendrás acceso a funciones públicas. Para acceder a funciones privadas (como firma, gestión de certificados, etc.), debes incluir `customerId` en la configuración.
### 4. Inicialización del SDK
Inicializa el SDK una sola vez al cargar tu aplicación. Si la inicialización es exitosa, podrás usar todos los métodos públicos y privados según tu configuración.
```javascript
import { apacuanaWeb } from "apacuana-sdk-web";
const config = {
apiUrl: "https://api.tu-dominio.com",
secretKey: "TU_SECRET_KEY",
apiKey: "TU_API_KEY",
verificationId: "ID_DE_VERIFICACION",
customerId: "ID_DEL_CLIENTE", // Opcional, pero necesario para funciones privadas
integrationType: "ONBOARDING",
};
async function initializeApp() {
try {
const isInitialized = await apacuanaWeb.init(config);
if (isInitialized) {
console.log("El SDK Web de Apacuana se ha inicializado correctamente.");
}
} catch (error) {
if (
error.name === "ApacuanaWebError" ||
error.name === "ApacuanaAPIError"
) {
console.error("Error al inicializar el SDK:", error.message);
} else {
console.error("Error inesperado:", error);
}
}
}
initializeApp();
```
## Conceptos Clave
### Tipos de Integración
El SDK soporta dos tipos de integración (`integrationType`) que determinan cómo se interactúa con la plataforma de Apacuana:
- **`ONBOARDING`**: En este modo, Apacuana gestiona la mayor parte del proceso, como el registro de usuarios y la generación de certificados. Es el modo recomendado y soportado para la mayoría de las integraciones.
- **`ONPREMISE`**: Este modo de integración no está soportado actualmente y se reserva para uso futuro. La mayoría de las operaciones del SDK lanzarán un error `NOT_IMPLEMENTED` si se utiliza este tipo.
La elección del `integrationType` en la `init` es fundamental, ya que afecta a la disponibilidad y el comportamiento de muchos de los métodos del SDK.
### Acceso a funciones públicas/privadas
El SDK puede inicializarse sin el parámetro `customerId`, lo que permite el acceso únicamente a las funciones públicas. Para acceder a las funciones privadas, es necesario inicializar el SDK incluyendo el `customerId` en la configuración.
**Funciones públicas disponibles sin `customerId`:**
- `getCertTypes()`
- `getCertRequerimentsByType(params)`
- `createApacuanaUser(userData)`
**Funciones privadas (requieren `customerId`):**
- `getCustomer()`
- `generateCert(encryptedCSR)`
- `getCertStatus(isCertificateInDevice)`
- `addSigner(signerData)`
- `getDocsByCustomer(params)`
- `signDocument(signData)`
- `uploadSignatureVariant(data)`
- `getSignatureVariant()`
- `deleteSignatureVariant()`
- `startLivenessCheck()`
- `requestRevocation(params)`
- `getRevocationReasons()`
- `importCertificate()`
- `exportCertificateInJSON()`
- `isCertificateInDevice()`
El SDK valida automáticamente si tienes acceso a cada función según la configuración actual, y lanzará un error si intentas acceder a una función privada sin haber inicializado correctamente con el `customerId`.
## Referencia de la API
Todos los métodos deben ser llamados a través de la instancia `apacuanaWeb`.
## Métodos públicos
### `getCertTypes()`
Obtiene los tipos de certificados disponibles.
#### Comportamiento
- Solo disponible para `integrationType: ONBOARDING`. Si se usa con `ONPREMISE`, lanzará un error `NOT_IMPLEMENTED`.
- Devuelve una instancia de `ApacuanaSuccess` con la propiedad `types`, que es un array de tipos de certificado.
#### Respuesta
```js
{
success: true,
data: {
types: [
{ /* tipo de certificado */ },
// ...otros tipos de certificado
]
}
}
```
#### Ejemplo:
```javascript
try {
const response = await apacuanaWeb.getCertTypes();
console.log("Tipos de certificados:", response.data.types);
} catch (error) {
console.error("Error al obtener los tipos de certificado:", error.message);
}
```
### `getCertRequerimentsByType(params)`
Obtiene los requisitos para un tipo de certificado y usuario.
#### Parámetros
- `params`: Objeto con la propiedad obligatoria:
- `type` (Number): El tipo de certificado.
#### Comportamiento
- Solo disponible para `integrationType: ONBOARDING`. Si se usa con `ONPREMISE`, lanzará un error `NOT_IMPLEMENTED`.
- Devuelve una instancia de `ApacuanaSuccess` con los requisitos solicitados.
#### Respuesta
```js
{
success: true,
data: {
...
}
}
```
#### Ejemplo:
```javascript
try {
const response = await apacuanaWeb.getRequerimentsByTypeUser({ type: 1 });
console.log("Requisitos:", response.data.requirements);
} catch (error) {
console.error("Error al obtener los requisitos:", error.message);
}
```
### `createApacuanaUser(userData)`
Crea un nuevo usuario en la plataforma de Apacuana. Este método puede llamarse varias veces para ir completando la información de forma parcial; no es necesario enviar todos los datos en una sola llamada. Sin embargo, en cada actualización es obligatorio enviar el número de documento de identidad (`kinddoc+doc`). El registro inicial debe incluir el documento de identidad.
Los documentos requeridos para el usuario se obtienen previamente usando el método `getRequerimentsByTypeUser` y deben enviarse bajo la estructura `{ file-ID: File }`, donde cada clave corresponde al identificador del documento y el valor es el archivo correspondiente.
> **Nota importante:** El objeto retornado en la respuesta tendrá un atributo `id`, el cual corresponde con el `customerId` de Apacuana. Este valor debe ser asociado y almacenado en tu sistema para cada usuario. Cuando tu usuario esté autenticado en tu aplicación y desee conectarse a Apacuana, deberá usar este `id` como `customerId` en la configuración del SDK. Este valor se obtiene luego de solicitar un certificado por primera vez.
El objeto completo de usuario que puede acompañar la solicitud es:
```js
{
email: "usuario@correo.com",
typeuser: 1,
name: "Nombre",
lastname: "Apellido",
kinddoc: "V",
doc: 12345678,
birthdate: "1990-01-01",
kindrif: "V",
gender: "M",
rif: 12345678,
phone: 4121234567,
kindphone: "0424",
state: "Estado",
municipality: "Municipio",
parish: "Parroquia",
postalcode: "1010",
address: "Dirección",
fiscaladdress: "Dirección fiscal",
fiscalkindphone: "0424",
fiscalphone: 4121234567,
occupation: "Ocupación",
degree: "Título",
university: "Universidad",
graduationyear: "2010",
collegiatenumber: "12345",
collegiateyear: "2011",
companyname: "Empresa",
companykindrif: "J",
companyrif: "J12345678",
companystate: "Estado",
companymunicipality: "Municipio",
companyparish: "Parroquia",
companyaddress: "Dirección empresa",
companykindphone: "0212",
companyphone: "2121234567",
companypostalcode: "1010",
companywebpage: "https://empresa.com",
companycommercialregister: "Registro comercial",
companyregisterdate: "2015-01-01",
companyregisternumber: "123456",
companyconstitutiondate: "2015-01-01",
companypublishdate: "2015-01-01",
companyconstitutiondecree: "Decreto",
companynumberdecree: "123",
positionprivate: "Cargo privado",
departmentprivate: "Departamento privado",
authorizedprivate: "Autorizado privado",
functionsprivate: "Funciones privado",
publishprivate: "2015-01-01",
issuedateprivate: "2015-01-01",
kindphoneprivate: "0424",
phoneprivate: 4121234567,
positionpublic: "Cargo público",
departmentpublic: "Departamento público",
authorizedpublic: "Autorizado público",
functionspublic: "Funciones público",
publishpublic: "2015-01-01",
issuedatepublic: "2015-01-01",
kindphonepublic: "0424",
phonepublic: 4121234567,
companyid: "uuid-empresa"
}
```
**Ejemplo:**
```javascript
try {
const userData = {
usr: "usuario@correo.com",
pwd: "contraseñaSegura123",
kinddoc: "V",
doc: "12345678",
// ...otros campos opcionales
files: {
"file-1": file1, // Instancia de File
"file-2": file2,
// ...otros documentos según los requerimientos
},
};
const response = await apacuanaWeb.createApacuanaUser(userData);
console.log("Usuario creado:", response.data);
} catch (error) {
console.error("Error al crear el usuario:", error.message);
}
```
#### Comportamiento
- Permite crear o actualizar usuarios de forma parcial o total.
- Los documentos requeridos se obtienen previamente usando `getCertRequerimentsByType`.
- Devuelve una instancia de `ApacuanaSuccess` con la información del usuario creado o actualizado.
---
## Métodos privados
### `getCustomer()`
Obtiene los datos del cliente autenticado.
#### Comportamiento
- Solo disponible si el SDK fue inicializado con `customerId`.
- Devuelve una instancia de `ApacuanaSuccess` con los datos del usuario y el token de autenticación.
**Ejemplo de uso:**
```js
const result = await apacuanaWeb.getCustomer();
// result.data contendrá los datos del usuario y el token
```
### `generateCert(params)`
Genera un nuevo certificado digital y lo almacena localmente.
#### Parámetros:
- `params`: (String) Contrase;a unica para generar y posteriormente utilizar el certificado
#### Comportamiento
- Solo disponible si el SDK fue inicializado con `customerId`.
- Genera un par de claves, crea una CSR, la envía al servidor y almacena el certificado y la clave privada cifrada en el dispositivo.
#### Respuesta
```js
{
success: true,
data: {
...
}
}
```
---
### `getCertStatus()`
Verifica el estado del certificado del usuario.
#### Comportamiento
- Solo disponible si el SDK fue inicializado con `customerId`.
- Devuelve el estado actual del certificado, incluyendo texto y descripción.
#### Respuesta
```js
{
success: true,
data: {
status: {
text: "...",
descriptionText: "..."
}
}
}
```
Los posibles valores de `text` incluyen:
- "Por verificar"
- "En revisión"
- "Por generar"
- "Vigente"
- "Por revocar"
- "Revocado"
- "Verificado"
- "Certificado expirado"
#### Ejemplo:
```javascript
try {
const response = await apacuanaWeb.getCertStatus();
console.log("Estado del certificado:", response.data.status.text);
if (response.data.status.descriptionText) {
console.log("Descripción:", response.data.status.descriptionText);
}
} catch (error) {
console.error("Error al obtener el estado del certificado:", error.message);
}
```
---
### `addSigner(params)`
Añade un firmante a un documento. El comportamiento y los campos obligatorios dependen del `integrationType` configurado durante la inicialización.
#### Parámetros:
- **`params`**: Objeto con los datos del firmante y el documento.
- `name` (String, **obligatorio**): Nombre del documento.
- `document` (File, **opcional**): El archivo del documento a firmar (ej. un PDF). No puede coexistir con `reference`.
- `reference` (String, **opcional**): Referencia única para un documento ya existente en la plataforma. No puede coexistir con `document`.
- `typedoc` (String, **obligatorio**): Tipo de documento de identidad del firmante. Valores permitidos: "V", "P", "E".
- `doc` (String, **obligatorio**): Número de documento de identidad del firmante.
- `signature` (Array, **obligatorio**): Un array de objetos que definen la posición de la firma. Debe contener al menos un objeto con:
- `page` (Number, **obligatorio**): Página donde se estampará la firma (entero positivo).
- `x` (Number, **obligatorio**): Coordenada X (de 0 a 1, porcentual respecto al ancho del PDF).
- `y` (Number, **obligatorio**): Coordenada Y (de 0 a 1, porcentual respecto al alto del PDF).
**Notas sobre `document` y `reference`:**
- Solo uno de estos parámetros debe ser enviado. Si el cliente tiene integración con el gestor documental de Apacuana, se debe usar `reference` para referenciar el documento existente en la plataforma.
- Si no existe integración documental, se debe enviar el archivo `document` (File). Este archivo será posteriormente solicitado para la firma del documento luego de ser asignado.
**Notas sobre posicionamiento:**
- Las coordenadas `x` e `y` son porcentuales y van de 0 a 1.
- El origen (0,0) está en la esquina superior izquierda del PDF.
- Ejemplos de posicionamiento:
- Esquina superior izquierda: `{ x: 0, y: 0 }`
- Esquina superior derecha: `{ x: 1, y: 0 }`
- Esquina inferior izquierda: `{ x: 0, y: 1 }`
- Centro de la página: `{ x: 0.5, y: 0.5 }`
#### Ejemplo:
```javascript
try {
const signer = {
name: "Contrato",
document: documentFile, // Instancia de File
typedoc: "V",
doc: "12345678",
signature: [
{ page: 1, x: 0, y: 0 }, // Esquina superior izquierda
{ page: 1, x: 1, y: 0 }, // Esquina superior derecha
{ page: 1, x: 0, y: 1 }, // Esquina inferior izquierda
{ page: 1, x: 0.5, y: 0.5 }, // Centro de la página
],
};
const response = await apacuana.addSigner(signer);
console.log("Firmante añadido:", response.data);
} catch (error) {
console.error("Error al añadir firmante:", error.message);
}
```
### `getDocsByCustomer(params)`
Obtiene la lista de documentos asociados al usuario.
#### Parámetros
- **`params`**: Objeto con parámetros de paginación y filtros.
- `page` (Number, **obligatorio**)
- `size` (Number, **obligatorio**)
- `status` (Number, **opcional**)
- (`status`) 0 pendiente, 1 = completado/firmado, -1 rechazado
#### Comportamiento
- Solo disponible si el SDK fue inicializado con `customerId`.
- Permite filtrar y paginar los documentos asociados al usuario.
#### Respuesta
```js
{
success: true,
data: {
/* lista de documentos */
}
}
```
**Ejemplo:**
```javascript
try {
const params = {
page: 1,
size: 10,
status: 0, // Estado del documento
};
const response = await apacuanaWeb.getDocsByCustomer(params);
console.log("Documentos filtrados:", response.data);
} catch (error) {
console.error("Error al obtener los documentos:", error.message);
}
```
**Notas:**
- Si no se especifican filtros, se devolverán todos los documentos paginados.
---
### `signDocument(params)`
Firma un documento usando el certificado y clave privada local.
#### Parámetros
El parámetro `params` debe incluir:
- `signature` (Object, obligatorio):
- `id` (String): ID de la firma.
- `positions` (Array): Posiciones de la firma en el documento.
- `document` (File, opcional): Archivo del documento a firmar.
**Importante:**
- El objeto `signature` debe ser obtenido directamente del array de documentos devuelto por el método `getDocsByCustomer`, específicamente del atributo `signaturedata` de dicho documento.
- Si en el método `addSigner` se utilizó el parámetro `reference`, no es necesario incluir el archivo `document` al firmar, ya que el documento está referenciado en la plataforma.
- Si en `addSigner` se utilizó el parámetro `document` (archivo), será necesario proporcionar nuevamente el archivo en este método para completar la firma.
#### Comportamiento
- Solo disponible si el SDK fue inicializado con `customerId`.
- Recupera el certificado y clave privada, obtiene el digest, firma localmente y envía la firma al servidor.
#### Respuesta
```js
{
success: true,
data: {
/* información del documento firmado */
}
}
```
#### Ejemplo:
```javascript
// Caso con documento referenciado
const result = await apacuana.signDocument({
signature: { id: "sig-123", positions: [{ page: 1, x: 0.5, y: 0.5 }] },
// No se requiere document
});
// Caso con documento por archivo
const result = await apacuana.signDocument({
signature: { id: "sig-123", positions: [{ page: 1, x: 0.5, y: 0.5 }] },
document: documentFile, // Instancia de File
});
// result.data contendrá la información del documento firmado
```
### `uploadSignatureVariant(params)`
Sube una imagen de variante de firma para el usuario autenticado.
#### Parámetros
El parámetro `params` debe incluir:
- `file` (File, obligatorio): Archivo de imagen en formato PNG (`image/png`).
**Notas importantes:**
- El archivo debe ser una instancia de `File` y tener el tipo MIME `image/png`.
#### Comportamiento
- Solo disponible si el SDK fue inicializado con `customerId`.
- Sube la imagen de la firma y la asocia al usuario.
#### Respuesta
```js
{
success: true,
data: {
/* información de la variante subida */
}
}
```
**Ejemplo:**
```javascript
const imageFile = new File(
[
/* datos */
],
"firma.png",
{ type: "image/png" }
);
try {
const response = await apacuanaWeb.uploadSignatureVariant({
file: imageFile,
});
console.log(response.data);
} catch (error) {
console.error(error.message);
}
```
---
### `getSignatureVariant()`
Obtiene la imagen de la variante de firma registrada.
#### Comportamiento
- Solo disponible si el SDK fue inicializado con `customerId`.
- Devuelve la imagen en Base64 o información asociada.
#### Respuesta
```js
{
success: true,
data: {
/* imagen de la firma en Base64 */
}
}
```
#### Ejemplo
```javascript
try {
const response = await apacuanaWeb.getSignatureVariant();
console.log(response.data);
} catch (error) {
console.error(error.message);
}
```
---
### `deleteSignatureVariant()`
Elimina la variante de firma almacenada.
#### Comportamiento
- Solo disponible si el SDK fue inicializado con `customerId`.
- Elimina la variante de firma si existe.
#### Respuesta
```js
{
success: true,
data: {
/* información del estado tras eliminar la variante */
}
}
```
#### Ejemplo
```javascript
try {
const response = await apacuanaWeb.deleteSignatureVariant();
console.log(response.data);
} catch (error) {
console.error(error.message);
}
---
```
### `startLivenessCheck(container?)`
Inicia una prueba de vida (liveness check) para el usuario.
#### Parámetros
- `container` (opcional): Elemento HTML donde se renderiza la prueba. Si se omite, se muestra en un modal.
#### Comportamiento
- Solo disponible si el SDK fue inicializado con `customerId`.
- Crea una sesión de prueba de vida y muestra la interfaz correspondiente.
#### Respuesta
```js
{
success: true,
data: {
/* resultado de la prueba de vida */
}
}
```
#### Ejemplo:
```javascript
try {
const response = await apacuanaWeb.startLivenesCheck();
console.log("Resultado de fe de vida:", response.data);
} catch (error) {
console.error("Error al procesar la fe de vida:", error.message);
}
```
---
### `requestRevocation(params)`
Solicita la revocación de un certificado.
#### Parámetros
- `params`: Objeto con la propiedad obligatoria:
- `reasonCode` (Number): ID de la razón de revocación.
> **Nota importante:** el atributo reasonCode debe provenir de la lista de razones de revocacion, la cual obtenemos con el metodo: getRevocationReasons()
#### Comportamiento
- Solo disponible si el SDK fue inicializado con `customerId`.
- Permite enviar la solicitud de revocación y documentos asociados.
#### Respuesta
```js
{
success: true,
data: {
/* información de la revocación */
}
}
```
#### Ejemplo:
```javascript
try {
const response = await apacuanaWeb.requestRevocation({ reasonCode: 1 });
console.log("Solicitud de revocación enviada:", response.data);
} catch (error) {
console.error("Error al solicitar la revocación:", error.message);
}
```
---
### `getRevocationReasons()`
Obtiene la lista de razones para la revocación de certificados.
#### Comportamiento
- Solo disponible si el SDK fue inicializado con `customerId`.
- Devuelve un array de razones de revocación proporcionadas por la API.
#### Respuesta
```js
{
success: true,
data: {
reasons: [ /* array de razones de revocación */ ]
}
}
```
#### Ejemplo:
```javascript
try {
const response = await apacuanaWeb.getRevocationReasons();
console.log("Razones de revocación:", response.data.reasons);
} catch (error) {
console.error("Error al obtener las razones de revocación:", error.message);
}
```
---
### `importCertificate(params)`
Importa un certificado previamente exportado.
#### Parámetros
- `params`: Objeto con el archivo y el PIN para importar el certificado.
#### Comportamiento
- Solo disponible si el SDK fue inicializado con `customerId`.
- Permite importar un certificado y clave privada previamente exportados.
#### Respuesta
```js
{
success: true,
data: {
/* información del proceso de importación */
}
}
```
---
### `exportCertificateInJSON(params)`
Exporta el certificado y claves del usuario a un archivo JSON seguro.
#### Parámetros
- `params`: Objeto con el PIN y nombre de archivo para exportar el certificado.
#### Comportamiento
- Solo disponible si el SDK fue inicializado con `customerId`.
- Exporta el certificado y clave privada cifrada a un archivo JSON con sello de integridad.
#### Respuesta
```js
{
success: true,
data: {
isExport: true
}
}
```
---
### `isCertificateInDevice()`
Verifica si existe un certificado almacenado localmente para el usuario.
#### Comportamiento
- Solo disponible si el SDK fue inicializado con `customerId`.
- Realiza una comprobación rápida en el almacenamiento local.
#### Respuesta
```js
{
success: true,
data: {
isExist: true // o false
}
}
```
#### Ejemplo:
```javascript
try {
const response = await apacuanaWeb.isCertificateInDevice();
console.log(
"Certificado existente en el dispositivo:",
response.data.isExist
);
} catch (error) {
console.error(
"Error al verificar si existe el certificado en el dispositivo:",
error.message
);
}
```
---
## 5. Manejo de Errores
El SDK utiliza un sistema de errores personalizado para facilitar la depuración.
- **`ApacuanaWebError`**: Errores generados por el SDK web. Suelen estar relacionados con el estado de la aplicación (ej. SDK no inicializado), validaciones (ej. PIN vacío) o problemas con IndexedDB.
- **`ApacuanaAPIError`**: Errores generados por `apacuana-sdk-core`. Estos errores se relanzan directamente y suelen estar relacionados con problemas de comunicación con la API de Apacuana (ej. `apiKey` inválida, errores del servidor).
Todos los errores lanzados por el SDK pueden ser capturados con un bloque `try...catch`.
### `ApacuanaWebErrorCode`
Los errores de tipo `ApacuanaWebError` incluyen un código para identificar la causa raíz:
- `NOT_INITIALIZED`: Se intentó usar un método antes de llamar a `init()`.
- `VALIDATION_ERROR`: Un parámetro de entrada no pasó la validación (ej. `pin` vacío).
- `NOT_FOUND`: No se encontró un recurso esperado (ej. la clave privada en IndexedDB).
- `UNKNOWN_ERROR`: Un error inesperado ocurrió dentro del SDK.
```
```