Guide · Parte 2 di 6
Pubblica la tua prima PoE
La pubblicazione è la metà di Label 309 in cui un gateway serve davvero. La verifica è trustless e non richiede account; la pubblicazione invece mette una transazione sulla chain, e questo ha un costo, perciò la invii tramite un gateway Label 309 che costruisce la transazione, paga la fee e la addebita sul proprio modello di balance. L'SDK e la CLI sono indipendenti dal gateway: puntali a quello per cui possiedi una API key.
Ogni pubblicazione ha la stessa struttura in due passaggi: blocca un prezzo, poi invia.
Il gateway calcola il prezzo del record da uno snapshot FX in tempo reale e restituisce un
quote_id valido per 15 minuti; la chiamata di pubblicazione lo consuma in modo atomico
insieme all'inserimento on-chain. Gli helper di alto livello calcolano l'hash del tuo
contenuto e costruiscono al posto tuo il record in canonical-CBOR.
Con la CLI
Installa il binario cardanowall, poi punta submit a un file. Ne calcola l'hash, ancora
il digest e stampa il risultato:
cardanowall submit \
--file ./contract.pdf \
--base-url https://your-gateway.example \
--api-key "$CW_API_KEY"--base-url e --api-key vengono letti anche dalle variabili CARDANOWALL_BASE_URL e
CARDANOWALL_API_KEY, oppure da un profilo gateway salvato, così spariscono dal comando in
CI. Se hai già il digest, ancoralo direttamente con --hash invece di --file; aggiungi
--alg blake2b-256 per passare dal valore predefinito sha2-256, e --json per un
riepilogo leggibile da una macchina:
cardanowall submit --hash 3b9f…c1a2 --jsonPer firmare il record con la tua chiave di identità, passa il seed master a 32 byte tramite
--seed-file o --seed-stdin (mai --seed nudo su argv: finirebbe nella cronologia della
shell). Omettilo per pubblicare senza firma.
Con l'SDK TypeScript
Crea un client verso il tuo gateway, poi richiedi il preventivo e pubblica in un'unica
chiamata helper. publishContent calcola l'hash dei byte, costruisce il record e lo invia:
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-centsresult.status parte da submitting; tx_hash resta null finché il gateway non
costruisce la transazione. Passa un idempotencyKey per rendere sicuri i tentativi
ripetuti: un invio identico ripetuto restituisce il record originale (dedup_hit: true)
senza addebitare una seconda volta. Per un digest precalcolato usa publishPrehashed; per
una busta sigillata indirizzata a un destinatario usa publishSealed.
Con l'SDK Python
cardanowall-sdk rispecchia gli helper TypeScript metodo per metodo. Il client è un async
context manager; le risposte tornano come semplici dizionari:
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 l'SDK Rust
Il crate cardanowall espone lo stesso client indipendente dal gateway. Le chiamate sono
bloccanti, quindi non serve alcun runtime async; gli helper restituiscono risultati tipizzati:
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(())
}Per un digest precalcolato usa publish_prehashed; per una busta sigillata indirizzata a un
destinatario usa publish_sealed.
La fee è del gateway, la prova è tua
Il gateway tramite cui pubblichi paga la fee Cardano e l'addebita sul proprio modello di balance, ma il record che ancora è semplice metadati Label 309 con label 309. Chiunque può verificarlo a partire dalla sola chain pubblica, senza account e senza riporre alcuna fiducia nel gateway. Per indirizzare invece un record a un destinatario, vedi costruire una PoE sigillata; per la struttura esatta on-chain, leggi il record.