Guías

Guías · Parte 2 de 6

Publique su primera PoE

Publicar es la mitad de Label 309 que sí necesita una pasarela. Verificar no requiere confianza ni cuenta; publicar coloca una transacción en la cadena, y eso tiene un coste, así que el envío se hace a través de una pasarela de Label 309 que construye la transacción, paga la comisión y la carga en su propio modelo de saldo. El SDK y la CLI son independientes de la pasarela: apúntelos a la pasarela para la que disponga de una clave de API.

Toda publicación tiene la misma forma en dos pasos: fijar un precio y luego enviar. La pasarela calcula el precio del registro a partir de una instantánea de FX en tiempo real y devuelve un quote_id válido durante 15 minutos; la llamada de publicación lo consume de forma atómica junto con la inserción en cadena. Los asistentes de alto nivel calculan el hash de su contenido y construyen el registro en CBOR canónico por usted.

Con la CLI

Instale el binario cardanowall y apunte submit a un archivo. Calcula el hash del contenido, ancla el resumen y muestra el resultado:

cardanowall submit \
  --file ./contract.pdf \
  --base-url https://your-gateway.example \
  --api-key "$CW_API_KEY"

--base-url y --api-key también se leen de CARDANOWALL_BASE_URL y CARDANOWALL_API_KEY, o de un perfil de pasarela guardado, de modo que desaparecen del comando en CI. Si ya dispone del resumen, áncrelo directamente con --hash en lugar de --file; añada --alg blake2b-256 para cambiar del valor predeterminado sha2-256, y --json para un resumen legible por máquina:

cardanowall submit --hash 3b9f…c1a2 --json

Para firmar el registro con su clave de identidad, pase la semilla maestra de 32 bytes mediante --seed-file o --seed-stdin (nunca como un --seed directo en argv, porque acaba en el historial del shell). Omítalo para publicar sin firma.

Con el SDK de TypeScript

Cree un cliente apuntando a su pasarela y, a continuación, cotice y publique en una sola llamada al asistente. publishContent calcula el hash de los bytes, construye el registro y lo envía:

import { Label309Client } from '@cardanowall/sdk-ts';

const client = new Label309Client({
  baseUrl: 'https://your-gateway.example',
  apiKey: process.env.CW_API_KEY,
});

const quote = await client.poe.quote({
  recordBytes: 256,
  recipientCount: 0,
  fileBytesTotal: 0,
});

const result = await client.poe.publishContent({
  content: fileBytes, // Uint8Array or a UTF-8 string
  quoteId: quote.quote_id,
  // idempotencyKey: crypto.randomUUID(), // safe to retry the same submit
  // signer is optional — omit to publish unsigned (profile=core)
});

console.log(result.id, result.tx_hash, result.status);
console.log(result.balance_after_usd_micros); // decimal string of USD micro-cents

result.status comienza en submitting; tx_hash es null hasta que la pasarela construye la transacción. Pase un idempotencyKey para que los reintentos sean seguros: un envío idéntico repetido devuelve el registro original (dedup_hit: true) sin volver a cargar el saldo. Para un resumen precalculado use publishPrehashed; para un sobre sellado dirigido a un destinatario use publishSealed.

Con el SDK de Python

cardanowall-sdk replica los asistentes de TypeScript método a método. El cliente es un gestor de contexto asíncrono; las respuestas se devuelven como diccionarios simples:

import asyncio
from cardanowall.client import Label309Client


async def main() -> None:
    async with Label309Client(
        base_url="https://your-gateway.example",
        api_key="<opaque-bearer>",
    ) as client:
        quote = await client.poe.quote(
            record_bytes=256, recipient_count=0, file_bytes_total=0
        )
        out = await client.poe.publish_content(
            content="hello world",  # str (UTF-8) or bytes
            quote_id=quote["quote_id"],
        )
        print(out["id"], out["tx_hash"], out["status"])


asyncio.run(main())

Con el SDK de Rust

El crate cardanowall expone el mismo cliente independiente de la pasarela. Las llamadas son bloqueantes, así que no hace falta un entorno de ejecución asíncrono; los asistentes devuelven resultados tipados:

use cardanowall::client::{
    Label309Client, Label309ClientConfig, PublishContentInput, QuoteInput,
};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = Label309Client::new(Label309ClientConfig {
        base_url: Some("https://your-gateway.example".into()),
        api_key: std::env::var("CW_API_KEY").ok(),
    })?;

    let quote = client.poe().quote(&QuoteInput {
        record_bytes: 256,
        recipient_count: 0,
        file_bytes_total: 0,
    })?;

    let result = client.poe().publish_content(&PublishContentInput {
        content: file_bytes, // Vec<u8>
        quote_id: quote.quote_id,
        hash_alg: None, // defaults to sha2-256
        signer: None,   // omit to publish unsigned (profile = core)
        idempotency_key: None,
    })?;

    println!("{} {:?} {:?}", result.id, result.tx_hash, result.status);
    Ok(())
}

Para un resumen precalculado use publish_prehashed; para un sobre sellado dirigido a un destinatario use publish_sealed.

La comisión es de la pasarela, la prueba es suya

La pasarela a través de la cual publica paga la comisión de Cardano y la carga en su modelo de saldo, pero el registro que ancla son simples metadatos de Label 309 bajo la etiqueta 309. Cualquiera puede verificarlo a partir de la cadena pública, sin cuenta y sin confiar en la pasarela. Para dirigir un registro a un destinatario, consulte construir una PoE sellada; para conocer la forma exacta en cadena, lea el registro.