Todas las entradas

12 min de lectura

Construye sobre la API de CardanoWall

Cómo construir tu propio producto sobre CardanoWall: solicita un presupuesto, sube contenido, publica, lee, verifica y monitoriza registros Label 309 a través de la misma API de gateway sobre la que funciona la propia CardanoWall.

Puedes integrar una función de prueba de existencia en tu propio producto sin llevar a tus usuarios al sitio web de CardanoWall. CardanoWall es una interfaz de usuario montada sobre un gateway alojado, y ese gateway expone una API HTTP sencilla: solicitar un presupuesto para una prueba, subir contenido cuando hace falta almacenamiento, publicar un registro Label 309, seguir su estado, leer registros públicos, consultar saldos y recibir webhooks. La prueba que aterriza en Cardano son metadatos Label 309 estándar, no un formato privado exclusivo de CardanoWall; así que cualquiera, con cualquier herramienta, puede verificarla más adelante.

Esa es la forma que importa. La experiencia de producto puede ser enteramente tuya. La prueba sigue siendo verificable de forma independiente. Esta es la misma API sobre la que funcionan la app web y el worker de la propia CardanoWall: no hay puerta privada ni un camino interno más rápido.

¿Qué puedes construir con ella?

Allá donde la prueba de existencia tenga sentido dentro de un flujo de trabajo, la API encaja:

  • un producto SaaS que sella en el tiempo los documentos de los clientes;
  • un pipeline de CI/CD que ancla los manifiestos de cada versión (mira pruebas en CI/CD);
  • una plataforma de IA que publica registros de procedencia a escala;
  • un archivo de cumplimiento que fija un compromiso sobre lotes diarios de pruebas;
  • una herramienta legal que sella material probatorio para destinatarios concretos;
  • un sistema de auditoría interna que firma instantáneas de controles;
  • un explorador público o una página de perfil que lista los registros de quien publica.

La API no es solo una envoltura cómoda alrededor del sitio web. Es la superficie de automatización: aquello a lo que recurres cuando no hay una persona en el bucle.

¿Cuál es el flujo principal de publicación?

Una publicación tiene tres etapas: presupuesto, subida (solo cuando hay bytes que almacenar) y, después, publicación. En el plano de datos del gateway (/api/v1/*), eso se traduce en:

  • POST /api/v1/poe/quote — fija el precio durante una ventana corta.
  • POST /api/v1/poe/uploads — almacena el contenido y devuelve URIs direccionadas por contenido.
  • POST /api/v1/poe/uploads/sessions y sus rutas de fragmentos — el camino reanudable para archivos grandes.
  • POST /api/v1/poe/publish — envía el registro finalizado.
  • POST /api/v1/poe/publish-batch — envía muchos registros en una sola llamada.
  • GET /api/v1/poe/events/{poe_id} — transmite las actualizaciones de estado por Server-Sent Events.

Los cuerpos exactos de petición y respuesta viven en el documento OpenAPI del gateway, servido por cada despliegue; enlaza con eso, no con un fragmento de un blog. Lo que se mantiene estable es el modelo mental: fija primero el precio, almacena cualquier contenido y luego envía los bytes del registro canónico-CBOR ya finalizado junto con el id del presupuesto.

¿Por qué va primero el presupuesto?

Porque publicar es una operación de pago, y el precio no se puede conocer de antemano.

Un gateway paga costes reales en tu nombre: las comisiones de las transacciones de Cardano, el almacenamiento en Arweave cuando se adjunta contenido, la exposición cambiaria entre el USD y esas redes, y el margen del operador. Un presupuesto deja ese coste explícito antes de que la llamada de publicación gaste nada. (Para entender por qué la publicación tiene un precio, mira por qué publicar cuesta dinero.)

La respuesta de un presupuesto lleva un quote_id, un desglose con precios (los componentes de red, almacenamiento y servicio), el margen aplicado, la frescura de la instantánea del tipo de cambio y una marca de caducidad. El precio queda fijado solo durante una ventana limitada —unos quince minutos—, tras la cual solicitas un presupuesto nuevo.

Eso permite que tu aplicación decida:

  • si la cuenta puede permitirse la publicación;
  • si la instantánea del tipo de cambio es lo bastante fresca para tu política;
  • si la operación necesita confirmación del usuario;
  • si conviene dividir un lote grande;
  • si reintentar con un presupuesto nuevo cuando el anterior caduca.

No muestres una etiqueta de «gratis» hasta que el gateway confirme que la operación no cuesta nada. Un registro de solo hash, sin almacenamiento, puede salir barato, pero la autoridad sobre el precio es el gateway, no tu interfaz.

¿Qué hace el paso de subida?

La subida gestiona los bytes que necesitan un lugar donde vivir.

Una prueba de solo hash no sube nada: ya tienes el digest. Un registro con contenido adjunto, un texto cifrado sellado o material de recuperación necesita almacenamiento direccionado por contenido, y los endpoints de subida almacenan esos bytes y devuelven una URI como ar://.... La API admite subidas multiparte, resultados por archivo, deduplicación por hash del contenido dentro de una cuenta y sesiones reanudables para archivos demasiado grandes para enviarlos en una sola petición. CardanoWall no impone un tamaño máximo de subida fijo: el contenido se factura por byte, y se esperan subidas de varios gigabytes.

Trata la subida como su propio pequeño ciclo de vida:

  1. Sube los bytes.
  2. Recibe la URI direccionada por contenido.
  3. Construye o finaliza el registro Label 309 usando esa URI.
  4. Publica el registro.

Si una subida devuelve el id de un intento en curso, consulta el endpoint de estado de ese intento en lugar de volver a subir a ciegas: reenviar un archivo de varios gigabytes porque te perdiste una respuesta es justo el tipo de error que el id del intento existe para evitar.

¿Qué hace la publicación y por qué es asíncrona?

La publicación envía el registro y pone en marcha el pipeline de la cadena.

La llamada de publicación acepta los bytes del registro canónico-CBOR ya finalizado más el quote_id. El gateway ancla el registro en Cardano bajo la etiqueta de metadatos 309, debita el importe presupuestado y devuelve un id de registro del gateway (un valor poe_...) mientras la transacción aún avanza por el envío y la confirmación.

Esa asincronía importa para tu diseño. Cuando la llamada retorna, puede que el hash de la transacción on-chain todavía no exista. Muestra un estado pendiente y mantente a la escucha de actualizaciones. El estado que reporta la API recorre estos valores:

  • submitting — la transacción se está construyendo y difundiendo;
  • confirming — está en la cadena pero por debajo del umbral de confirmación;
  • confirmed — ha superado ese umbral y está confirmada;
  • failed — la publicación ha fallado de forma definitiva y no aterrizará.

El flujo de estado en GET /api/v1/poe/events/{poe_id} existe precisamente para esto. Ante un fallo definitivo, el gateway revierte el débito por sí mismo, de modo que tu producto puede decirles a los usuarios con honestidad «solo se te cobra por lo que aterriza en la cadena» sin tener que llevar tu propia conciliación. No construyas una vía de reembolso del lado del proveedor para los fallos de publicación; reembolsaría dos veces.

¿Qué debería guardar tu cliente de la API?

Guarda lo justo para reconectar el flujo de trabajo, y nada más. Como mínimo:

  • tu propio id de usuario o de cuenta;
  • el poe_id del gateway;
  • el id del presupuesto usado en la publicación;
  • el digest del registro, o un hash de los bytes del registro;
  • el hash final de la transacción de Cardano, una vez que exista;
  • estado y sellos de tiempo;
  • cualquier id de intento de subida;
  • cualquier URI direccionada por contenido;
  • cualquier material local que vayas a necesitar para verificar más adelante.

No trates tu base de datos como la prueba. Trátala como un modelo de lectura del producto. La prueba es el registro Label 309 on-chain más el contenido o las claves necesarios para verificarlo, y esa combinación se sostiene por sí sola, independiente de tus servidores.

¿Cómo se leen y verifican los registros?

La superficie de registros está pensada para lecturas públicas y anónimas:

  • GET /api/v1/records — el feed de registros on-chain, con filtros y paginación.
  • GET /api/v1/records/count — un recuento para ese feed.
  • GET /api/v1/records/{tx_hash} — un único registro por hash de transacción.
  • POST /api/v1/records/{tx_hash}/verify — un informe de verificación del lado del servidor.

Las rutas de listado y consulta atienden a quien llama de forma anónima: las páginas de verificación públicas y los exploradores no necesitan credencial. Un token de portador puede añadir contexto de cuenta donde sea relevante, pero la verificación pública de registros nunca debería depender de una sesión privada de CardanoWall.

Usa estos endpoints por comodidad del producto. Para comprobaciones de alta garantía, ejecuta además un verificador autónomo que obtenga los datos de la cadena a través de la infraestructura de Cardano que él elija y produzca un informe independiente. Ese es el reparto saludable: la API facilita construir aplicaciones, pero la prueba debe seguir sosteniéndose fuera de la API. Los SDK y la CLI de código abierto incluyen exactamente ese verificador; mira cómo verificar un registro Label 309 para ver cómo funciona de principio a fin.

¿Cómo debería funcionar la autenticación?

Mantén las credenciales acotadas, y mantén las credenciales de operador en tu backend.

El gateway separa dos planos. Tus usuarios actúan sobre el plano de datos (/api/v1/*) con un token de cuenta o clave de API de corta duración que tu backend acuña por sesión. Solo tu backend posee la credencial de operador del plano de control (/control/v1/*): aprovisionar cuentas, aplicar créditos cuando tu facturación cobra dinero, fijar márgenes y acuñar esos tokens de cuenta.

El acceso al plano de datos está acotado por alcances. Los alcances que vas a usar:

  • poe:create — presupuesto, subida, publicación y publicación por lotes;
  • poe:read — lecturas de registros, la ruta de verificación y el flujo de estado cuando se llama con un token de portador;
  • account:read — lecturas de saldo y de libro mayor;
  • webhooks:read y webhooks:write — gestión de webhooks acotada a la cuenta;
  • billing:read — reservado para las superficies de facturación del proveedor.

Una página de publicación necesita poe:create; un widget de saldo necesita account:read; ninguno necesita más. Las credenciales de operador no deben llegar jamás a un paquete de navegador, una app móvil, el script de un socio ni un trabajo de CI que solo necesita publicar pruebas: esos acuñan su propio token de cuenta acotado. Un token de cuenta filtrado debería ser un problema de una hora, no un incidente.

¿Cómo deberían funcionar los reintentos y la idempotencia?

Diseña los reintentos antes de producción, porque los sistemas de publicación fallan de formas anodinas: cortes de red, presupuestos caducados, saldo insuficiente, límites de tasa, una subida todavía en curso o un flujo de estado caído.

Una integración sólida debería:

  • usar idempotencia donde la API lo admita, con clave en un id de origen estable;
  • tratar la caducidad del presupuesto como algo normal: pide un presupuesto nuevo y continúa;
  • consultar el endpoint autoritativo del intento o del registro tras un fallo incierto, en lugar de reenviar a ciegas;
  • evitar subir dos veces archivos grandes;
  • evitar acreditar saldos por duplicado (pon clave a cada crédito con el propio id del pago);
  • registrar los ids de petición y los ids del gateway para el soporte;
  • distinguir en tus informes una publicación fallida de un registro no verificable.

La publicación deduplica por los bytes del registro, y los lotes de subida admiten reproducción idempotente. Apóyate en esa semántica en lugar de en un bucle de «reintenta y reza».

¿Qué deberían hacer los webhooks?

Los webhooks son la forma de construir modelos de lectura: no consultando cada segundo, y desde luego no leyendo las tablas de la base de datos del gateway, que son internas del motor y cambian sin previo aviso.

Registra una suscripción a un webhook y el gateway empuja eventos de ciclo de vida: poe_status_changed, balance_changed, intenciones de reembolso, fallos de subida. Los operadores pueden suscribirse al firehose completo de toda la instancia; en el plano de datos también existen rutas de webhook acotadas a la cuenta. Una vista de «elementos enviados» —donde cada usuario ve los registros que publicó, con estado en vivo— es el caso de uso canónico: consume poe_status_changed, proyéctalo en tu propia tabla y renderiza desde ahí.

Tu receptor debería verificar la firma de cada entrega, aceptar entregas al menos una vez, poner clave a las proyecciones con el id del evento o de la entrega y tratar una reentrega como una operación sin efecto. El modelo de lectura pertenece a tu app. El estado canónico de gasto y publicación pertenece al gateway: guárdalo en caché para renderizar si hace falta, pero lee del gateway cualquier decisión que condicione un gasto.

¿Qué no debería salir nunca del cliente?

El material de identidad privada. Tu aplicación llama a la API para publicar registros; nunca debería entregarle al gateway la semilla de identidad del usuario, su clave privada de firma ni la clave privada de un destinatario.

  • Para los registros firmados, firma localmente o usa firma fuera del host: los SDK exponen un flujo en el que la clave privada vive en un KMS, un HSM o una máquina aislada, y solo la clave pública y la firma cruzan el cable.
  • Para los registros sellados, cifra localmente antes de subir cuando el caso de uso requiera confidencialidad de extremo a extremo.
  • Para la verificación de destinatario, descifra localmente.

La API sirve para publicar y para operaciones de ciclo de vida. No es la raíz de confianza, y está diseñada para que nunca necesite serlo. Para el principio más amplio, mira por qué las claves nunca salen del dispositivo.

Por dónde empezar

El camino más rápido son los SDK y la CLI de código abierto en github.com/cardanowall: un SDK de TypeScript (@cardanowall/sdk-ts), un SDK de Python (cardanowall-sdk), un SDK de Rust (cardanowall) y la CLI cardanowall. Todos son agnósticos respecto al gateway —tú aportas la URL base y una clave de API opaca— y todos incluyen el mismo verificador autónomo. Si prefieres manejar primero la API a mano, publica tu primera prueba recorre un registro de principio a fin, y usar la CLI en la automatización cubre el camino con scripts. Y si quieres ejecutar tú mismo el backend en lugar de usar el alojado, el gateway también es de código abierto: mira cómo ejecutar tu propio gateway.

Para seguir leyendo

apidevelopersgateway