Tutti gli articoli

11 min di lettura

Costruisci sulle API di CardanoWall

Come costruire il tuo prodotto su CardanoWall: richiedi un preventivo, carica, pubblica, leggi, verifica e monitora i record Label 309 attraverso le stesse API gateway su cui gira CardanoWall stesso.

Puoi integrare una funzione di Proof of Existence nel tuo prodotto senza far passare gli utenti dal sito di CardanoWall. CardanoWall è un'interfaccia utente costruita sopra un gateway in hosting, e quel gateway espone semplici API HTTP: richiedi un preventivo per una prova, carica il contenuto quando serve storage, pubblica un record Label 309, traccia il suo stato, leggi i record pubblici, controlla i saldi e ricevi webhook. La prova che finisce su Cardano è un normale record di metadati Label 309, non un formato privato esclusivo di CardanoWall — così chiunque, con qualunque strumento, può verificarla in seguito.

È questa la forma che conta. L'esperienza di prodotto può essere interamente tua. La prova resta verificabile in modo indipendente. Sono le stesse API su cui girano la web app e il worker di CardanoWall — non c'è nessuna porta privata né una scorciatoia interna più veloce.

Cosa puoi costruirci sopra?

Ovunque la Proof of Existence trovi posto in un flusso di lavoro, le API si incastrano:

  • un prodotto SaaS che marca temporalmente i documenti dei clienti;
  • una pipeline CI/CD che ancora i manifest di rilascio (vedi prove nella CI/CD);
  • una piattaforma AI che pubblica record di provenienza su larga scala;
  • un archivio di compliance che si impegna su batch giornalieri di prove;
  • uno strumento legale che sigilla le prove per destinatari specifici;
  • un sistema di audit interno che firma gli snapshot dei controlli;
  • un explorer pubblico o una pagina profilo che elenca i record di chi pubblica.

Le API non sono solo un comodo involucro attorno al sito. Sono la superficie di automazione — quello a cui ricorri quando non c'è una persona nel ciclo.

Qual è il flusso di pubblicazione principale?

Una pubblicazione ha tre fasi: preventivo, caricamento (solo quando i byte hanno bisogno di storage), poi pubblicazione. Sul data plane del gateway (/api/v1/*), questo si traduce in:

  • POST /api/v1/poe/quote — blocca il prezzo per una breve finestra.
  • POST /api/v1/poe/uploads — conserva il contenuto, restituendo URI indirizzati per contenuto.
  • POST /api/v1/poe/uploads/sessions e le sue route a chunk — il percorso ripristinabile per i file di grandi dimensioni.
  • POST /api/v1/poe/publish — invia il record finalizzato.
  • POST /api/v1/poe/publish-batch — invia molti record in un'unica chiamata.
  • GET /api/v1/poe/events/{poe_id} — trasmette in streaming gli aggiornamenti di stato via Server-Sent Events.

I corpi esatti di richiesta e risposta vivono nel documento OpenAPI del gateway, servito da ogni deployment — vincolati a quello, non a uno snippet di un blog. A restare stabile è il modello mentale: blocca prima il prezzo, conserva eventuali contenuti, poi invia i byte del record finalizzato in canonical-CBOR insieme all'id del preventivo.

Perché il preventivo viene prima?

Perché pubblicare è un'operazione a pagamento, e il prezzo non è conoscibile in anticipo.

Un gateway sostiene costi reali per tuo conto: le fee delle transazioni Cardano, lo storage Arweave quando c'è contenuto allegato, l'esposizione al cambio tra USD e quelle reti e il margine dell'operatore. Un preventivo rende quel costo esplicito prima che la chiamata di pubblicazione spenda alcunché. (Per il ragionamento dietro la pubblicazione a pagamento, vedi perché pubblicare ha un prezzo.)

La risposta a un preventivo porta con sé un quote_id, un dettaglio dei prezzi (componenti di rete, storage e servizio), il margine applicato, la freschezza dello snapshot del tasso di cambio e un timestamp di scadenza. Il prezzo è bloccato solo per una finestra limitata — circa quindici minuti — dopodiché richiedi un nuovo preventivo.

Questo permette alla tua applicazione di decidere:

  • se l'account può permettersi la pubblicazione;
  • se lo snapshot del tasso di cambio è abbastanza fresco per la tua policy;
  • se l'operazione richiede la conferma dell'utente;
  • se suddividere un batch di grandi dimensioni;
  • se riprovare con un nuovo preventivo quando il vecchio scade.

Non mostrare un'etichetta «gratis» finché il gateway non conferma che l'operazione non costa nulla. Un record solo-hash senza storage può essere economico, ma l'autorità sul prezzo è il gateway, non la tua UI.

Cosa fa il passo di caricamento?

Il caricamento gestisce i byte che hanno bisogno di un posto dove stare.

Una prova solo-hash non carica nulla — il digest è già in mano tua. Un record con contenuto allegato, un testo cifrato sigillato o materiale di recupero ha bisogno di storage indirizzato per contenuto, e gli endpoint di caricamento conservano quei byte e restituiscono un URI come ar://.... Le API supportano caricamenti multipart, esiti per singolo file, deduplica per hash del contenuto all'interno di un account e sessioni ripristinabili per i file troppo grandi da inviare in una singola richiesta. CardanoWall non impone alcun limite massimo di caricamento fisso — il contenuto è fatturato al byte, e ci si aspettano caricamenti di diversi gigabyte.

Tratta il caricamento come un suo piccolo ciclo di vita:

  1. Carica i byte.
  2. Ricevi l'URI indirizzato per contenuto.
  3. Costruisci o finalizza il record Label 309 usando quell'URI.
  4. Pubblica il record.

Se un caricamento restituisce l'id di un tentativo ancora in corso, interroga l'endpoint di stato di quel tentativo invece di ricaricare alla cieca — rispedire un file da diversi gigabyte perché ti sei perso una risposta è esattamente il tipo di errore che l'id del tentativo esiste per evitare.

Cosa fa la pubblicazione, e perché è asincrona?

La pubblicazione invia il record e avvia la pipeline on-chain.

La chiamata di pubblicazione accetta i byte del record finalizzato in canonical-CBOR più il quote_id. Il gateway ancora il record su Cardano sotto la label dei metadati 309, addebita l'importo preventivato e restituisce un id di record del gateway (un valore poe_...) mentre la transazione si sta ancora muovendo tra invio e conferma.

Quell'asincronia conta per il tuo design. Quando la chiamata ritorna, l'hash della transazione on-chain potrebbe non esistere ancora. Mostra uno stato in attesa e resta in ascolto degli aggiornamenti. Lo stato riportato dalle API si muove attraverso questi valori:

  • submitting — la transazione viene costruita e diffusa;
  • confirming — è on-chain ma sotto la soglia di conferma;
  • confirmed — ha superato quella soglia ed è ormai consolidata;
  • failed — la pubblicazione è fallita in modo definitivo e non andrà a buon fine.

Lo stream di stato su GET /api/v1/poe/events/{poe_id} esiste esattamente per questo. In caso di fallimento definitivo, il gateway annulla l'addebito da sé — così il tuo prodotto può dire onestamente agli utenti «paghi solo per ciò che finisce on-chain» senza dover gestire una tua riconciliazione. Non costruire un percorso di rimborso lato fornitore per i fallimenti di pubblicazione: produrrebbe un doppio rimborso.

Cosa dovrebbe conservare il tuo client API?

Conserva quanto basta per riagganciare il flusso di lavoro — e niente di più. Come minimo:

  • il tuo id utente o di account;
  • il poe_id del gateway;
  • l'id del preventivo usato per la pubblicazione;
  • il digest del record, o un hash dei byte del record;
  • l'hash finale della transazione Cardano, una volta che esiste;
  • stato e timestamp;
  • eventuali id dei tentativi di caricamento;
  • eventuali URI indirizzati per contenuto;
  • qualunque materiale locale ti serva per verificare in seguito.

Non trattare il tuo database come la prova. Trattalo come un read model di prodotto. La prova è il record Label 309 on-chain più il contenuto o le chiavi necessari a verificarlo — e quella combinazione regge da sé, indipendentemente dai tuoi server.

Come leggi e verifichi i record?

La superficie dei record è pensata per letture pubbliche e anonime:

  • GET /api/v1/records — il feed dei record on-chain, con filtri e paginazione.
  • GET /api/v1/records/count — un conteggio per quel feed.
  • GET /api/v1/records/{tx_hash} — un singolo record per hash della transazione.
  • POST /api/v1/records/{tx_hash}/verify — un report di verifica lato server.

Le route di lista e di lettura servono chiamanti anonimi — pagine di verifica pubbliche ed explorer non hanno bisogno di credenziali. Un bearer token può aggiungere il contesto di account dove rilevante, ma la verifica pubblica di un record non dovrebbe mai dipendere da una sessione CardanoWall privata.

Usa questi endpoint per la comodità del prodotto. Per controlli ad alta garanzia, esegui anche un verificatore standalone che recupera i dati di catena attraverso l'infrastruttura Cardano che sceglie lui e produce un report indipendente. È questa la divisione sana: le API rendono più facile costruire app, ma la prova deve comunque reggere al di fuori delle API. Gli SDK e la CLI open source includono esattamente quel verificatore — vedi verificare un record Label 309 per capire come funziona dall'inizio alla fine.

Come dovrebbe funzionare l'autenticazione?

Mantieni le credenziali ristrette, e tieni le credenziali da operatore sul tuo backend.

Il gateway separa due piani. I tuoi utenti agiscono sul data plane (/api/v1/*) con un account token a vita breve o una chiave API che il tuo backend conia a ogni sessione. Solo il tuo backend custodisce la credenziale da operatore per il control plane (/control/v1/*) — per creare account, applicare crediti quando la tua fatturazione incassa, impostare i margini e coniare quegli account token.

L'accesso al data plane ha scope definiti. Gli scope che userai:

  • poe:create — preventivo, caricamento, pubblicazione e pubblicazione a batch;
  • poe:read — letture dei record, la route di verifica e lo stream di stato quando chiamato con un bearer;
  • account:read — letture di saldo e ledger;
  • webhooks:read e webhooks:write — gestione dei webhook a livello di account;
  • billing:read — riservato alle superfici di fatturazione lato fornitore.

Una pagina di pubblicazione ha bisogno di poe:create; un widget del saldo ha bisogno di account:read; nessuno dei due ha bisogno di più. Le credenziali da operatore non devono mai raggiungere un bundle del browser, un'app mobile, lo script di un partner o un job CI che deve soltanto pubblicare prove — questi coniano invece il proprio account token con scope ristretti. Un account token trapelato dovrebbe essere un problema di un'ora, non un incidente.

Come dovrebbero funzionare i retry e l'idempotenza?

Progetta i retry prima della produzione, perché i sistemi di pubblicazione falliscono in modi banali: intoppi di rete, preventivi scaduti, saldo insufficiente, rate limit, un caricamento ancora in corso o uno stream di stato interrotto.

Un'integrazione solida dovrebbe:

  • usare l'idempotenza dove le API la supportano, con chiave su un id di origine stabile;
  • trattare la scadenza del preventivo come normale — recuperare un nuovo preventivo e proseguire;
  • interrogare l'endpoint autorevole del tentativo o del record dopo un fallimento incerto, invece di reinviare alla cieca;
  • evitare di caricare due volte i file di grandi dimensioni;
  • evitare di accreditare due volte i saldi (mettendo una chiave su ogni credito, basata sull'id del pagamento stesso);
  • registrare gli id di richiesta e gli id del gateway a fini di supporto;
  • distinguere una pubblicazione fallita da un record non verificabile nei tuoi report.

La pubblicazione deduplica sui byte del record, e i batch di caricamento supportano il replay idempotente. Appoggiati a queste semantiche invece che a un loop del tipo «riprova e spera».

Cosa dovrebbero fare i webhook?

I webhook sono il modo in cui costruisci i read model — non interrogando ogni secondo, e di certo non leggendo le tabelle del database del gateway, che sono interne al motore e cambiano senza preavviso.

Registra una sottoscrizione webhook e il gateway invia gli eventi del ciclo di vita: poe_status_changed, balance_changed, intenti di rimborso, fallimenti di caricamento. Gli operatori possono sottoscrivere l'intero firehose esteso a tutta l'istanza; sul data plane esistono anche route webhook a livello di account. Una vista «elementi inviati» — in cui ogni utente vede i record che ha pubblicato, con lo stato in tempo reale — è l'uso canonico: consuma poe_status_changed, proiettalo nella tua tabella e renderizza da lì.

Il tuo ricevitore dovrebbe verificare la firma di ogni consegna, accettare la consegna at-least-once, mettere una chiave sulle proiezioni basata sull'id dell'evento o della consegna e trattare una riconsegna come un no-op. Il read model appartiene alla tua app. Lo stato canonico di spesa e di pubblicazione appartiene al gateway — mettilo pure in cache per il rendering se proprio devi, ma leggi dal gateway per qualunque decisione che condizioni una spesa.

Cosa non dovrebbe mai lasciare il client?

Il materiale di identità privato. La tua applicazione chiama le API per pubblicare record; non dovrebbe mai consegnare al gateway l'Identity Seed dell'utente, la chiave privata di firma o la chiave privata del destinatario.

  • Per i record firmati, firma localmente o usa la firma fuori host — gli SDK espongono un flusso in cui la chiave privata vive in un KMS, in un HSM o in una macchina air-gapped, e solo la chiave pubblica e la firma attraversano la rete.
  • Per i record sigillati, cifra localmente prima del caricamento quando il caso d'uso richiede confidenzialità end-to-end.
  • Per la verifica destinatario, decifra localmente.

Le API servono alla pubblicazione e alle operazioni del ciclo di vita. Non sono la radice di fiducia, e sono progettate in modo da non doverlo mai essere. Per il principio più ampio, vedi perché le chiavi non lasciano mai il dispositivo.

Da dove iniziare

Il percorso più rapido sono gli SDK e la CLI open source su github.com/cardanowall: un SDK TypeScript (@cardanowall/sdk-ts), un SDK Python (cardanowall-sdk), un SDK Rust (cardanowall) e la CLI cardanowall. Sono tutti indipendenti dal gateway — fornisci tu l'URL di base e una chiave API opaca — e includono tutti lo stesso verificatore standalone. Se preferisci prima pilotare le API a mano, pubblica la tua prima prova ti accompagna attraverso un record dall'inizio alla fine, e usare la CLI nell'automazione copre il percorso a script. Se vuoi far girare il backend da te invece di usare quello in hosting, anche il gateway è open source — vedi far girare il tuo gateway.

Approfondimenti

apidevelopersgateway