Tous les articles

12 min de lecture

Bâtir sur l'API CardanoWall

Comment bâtir votre propre produit sur CardanoWall : demander un devis, téléverser, publier, lire, vérifier et surveiller des records Label 309 via la même API gateway que CardanoWall utilise lui-même.

Vous pouvez intégrer une fonctionnalité de preuve d'existence dans votre propre produit sans renvoyer vos utilisateurs vers le site CardanoWall. CardanoWall est une interface utilisateur posée sur un gateway hébergé, et ce gateway expose une API HTTP toute simple : demander un devis pour une preuve, téléverser du contenu lorsque le stockage est nécessaire, publier un record Label 309, suivre son statut, lire des records publics, consulter des soldes et recevoir des webhooks. La preuve qui se pose sur Cardano est constituée de métadonnées Label 309 standard, et non d'un format privé propre à CardanoWall — de sorte que n'importe qui, avec n'importe quel outil, pourra la vérifier ensuite.

C'est là le point essentiel. L'expérience produit peut être entièrement la vôtre. La preuve, elle, reste vérifiable de façon indépendante. C'est exactement l'API sur laquelle reposent l'application web et le worker de CardanoWall lui-même — il n'y a aucune porte dérobée ni aucun chemin interne plus rapide.

Que pouvez-vous bâtir avec elle ?

Partout où une preuve d'existence a sa place dans un flux de travail, l'API s'intègre :

  • un produit SaaS qui horodate les documents de ses clients ;
  • un pipeline CI/CD qui ancre des manifestes de version (voir les preuves en CI/CD) ;
  • une plateforme d'IA qui publie des records de provenance à grande échelle ;
  • une archive de conformité qui engage chaque jour des lots de pièces ;
  • un outil juridique qui scelle des pièces à l'intention de destinataires précis ;
  • un système d'audit interne qui signe des instantanés de contrôles ;
  • un explorateur public ou une page de profil qui liste les records d'un éditeur.

L'API n'est pas qu'une simple surcouche pratique autour du site. C'est la surface d'automatisation — ce vers quoi vous vous tournez quand aucun humain n'est dans la boucle.

Quel est le flux de publication principal ?

Une publication comporte trois étapes : devis, téléversement (uniquement quand des octets doivent être stockés), puis publication. Sur le plan de données du gateway (/api/v1/*), cela correspond à :

  • POST /api/v1/poe/quote — verrouiller le prix pour une courte fenêtre.
  • POST /api/v1/poe/uploads — stocker le contenu et renvoyer des URI adressés par le contenu.
  • POST /api/v1/poe/uploads/sessions et ses routes de fragments — le chemin reprenable pour les fichiers volumineux.
  • POST /api/v1/poe/publish — soumettre le record finalisé.
  • POST /api/v1/poe/publish-batch — soumettre plusieurs records en un seul appel.
  • GET /api/v1/poe/events/{poe_id} — diffuser les mises à jour de statut via Server-Sent Events.

Les corps exacts de requête et de réponse figurent dans le document OpenAPI du gateway, servi par chaque déploiement — alignez-vous dessus, et non sur un extrait de blog. Ce qui reste stable, c'est le modèle mental : verrouillez d'abord le prix, stockez le contenu éventuel, puis soumettez les octets finalisés du record en CBOR canonique accompagnés de l'identifiant du devis.

Pourquoi le devis vient-il en premier ?

Parce que publier est une opération payante, et que le prix n'est pas connu à l'avance.

Un gateway assume des coûts réels pour votre compte : les frais de transaction Cardano, le stockage Arweave lorsqu'un contenu est joint, l'exposition de change entre le dollar et ces réseaux, ainsi que la marge de l'opérateur. Un devis rend ce coût explicite avant que l'appel de publication ne dépense quoi que ce soit. (Pour le raisonnement qui sous-tend la publication payante, voir pourquoi la publication a un prix.)

Une réponse de devis porte un quote_id, une ventilation tarifaire (composantes réseau, stockage et service), la marge appliquée, la fraîcheur de l'instantané du taux de change et un horodatage d'expiration. Le prix n'est verrouillé que pour une fenêtre limitée — une quinzaine de minutes environ — après quoi vous demandez un nouveau devis.

Cela laisse votre application décider :

  • si le compte a les moyens de couvrir la publication ;
  • si l'instantané du taux de change est assez frais pour votre politique ;
  • si l'opération exige une confirmation de l'utilisateur ;
  • s'il faut scinder un gros lot ;
  • s'il faut réessayer avec un nouveau devis lorsque l'ancien expire.

N'affichez pas la mention « gratuit » tant que le gateway n'a pas confirmé que l'opération ne coûte rien. Un record réduit à une empreinte, sans stockage, peut être bon marché, mais c'est le gateway qui fait autorité sur le prix, pas votre interface.

À quoi sert l'étape de téléversement ?

Le téléversement prend en charge les octets qui doivent être hébergés quelque part.

Une preuve réduite à une empreinte ne téléverse rien — vous détenez déjà le condensé. Un record assorti d'un contenu joint, d'un texte chiffré scellé ou de matériel de récupération a besoin d'un stockage adressé par le contenu, et les points de terminaison de téléversement stockent ces octets et renvoient un URI tel que ar://.... L'API prend en charge les téléversements multiparties, des résultats par fichier, la déduplication par empreinte du contenu au sein d'un compte et des sessions reprenables pour les fichiers trop volumineux pour être envoyés en une seule requête. CardanoWall n'impose aucune taille maximale de téléversement — le contenu est facturé à l'octet, et l'on s'attend à des téléversements de plusieurs gigaoctets.

Traitez le téléversement comme son propre petit cycle de vie :

  1. Téléversez les octets.
  2. Recevez l'URI adressé par le contenu.
  3. Construisez ou finalisez le record Label 309 à partir de cet URI.
  4. Publiez le record.

Si un téléversement renvoie l'identifiant d'une tentative encore en cours, interrogez le point de terminaison de statut de cette tentative plutôt que de re-téléverser à l'aveugle — renvoyer un fichier de plusieurs gigaoctets parce que vous avez manqué une réponse est précisément le genre d'erreur que l'identifiant de tentative est là pour éviter.

Que fait la publication, et pourquoi est-elle asynchrone ?

La publication soumet le record et lance le pipeline de la chaîne.

L'appel de publication accepte les octets finalisés du record en CBOR canonique, plus le quote_id. Le gateway ancre le record sur Cardano sous le label de métadonnées 309, débite le montant indiqué dans le devis et renvoie un identifiant de record du gateway (une valeur poe_...) alors que la transaction chemine encore vers la soumission et la confirmation.

Cette asynchronie compte dans votre conception. Au retour de l'appel, l'empreinte de transaction sur la chaîne peut ne pas encore exister. Affichez un état en attente et écoutez les mises à jour. Le statut rapporté par l'API passe par ces valeurs :

  • submitting — la transaction est en cours de construction et de diffusion ;
  • confirming — elle est sur la chaîne mais en dessous du seuil de confirmation ;
  • confirmed — elle a franchi ce seuil et est réglée ;
  • failed — la publication a échoué de façon définitive et ne se posera pas.

Le flux de statut situé à GET /api/v1/poe/events/{poe_id} existe précisément pour cela. En cas d'échec définitif, le gateway annule lui-même le débit — de sorte que votre produit peut dire honnêtement à ses utilisateurs « vous n'êtes facturé que pour ce qui se pose sur la chaîne », sans avoir à mener votre propre réconciliation. Ne construisez pas, côté fournisseur, de chemin de remboursement pour les échecs de publication ; cela aboutirait à un double remboursement.

Que doit stocker votre client d'API ?

Stockez juste assez pour reconnecter le flux de travail — et rien de plus. Au minimum :

  • votre propre identifiant d'utilisateur ou de compte ;
  • le poe_id du gateway ;
  • l'identifiant du devis utilisé pour la publication ;
  • le condensé du record, ou une empreinte des octets du record ;
  • l'empreinte de transaction Cardano finale, une fois qu'elle existe ;
  • le statut et les horodatages ;
  • les éventuels identifiants de tentative de téléversement ;
  • les éventuels URI adressés par le contenu ;
  • tout matériel local dont vous aurez besoin pour vérifier ultérieurement.

Ne traitez pas votre base de données comme la preuve. Traitez-la comme un modèle de lecture produit. La preuve, c'est le record Label 309 sur la chaîne, plus le contenu ou les clés nécessaires pour le vérifier — et cette combinaison se suffit à elle-même, indépendamment de vos serveurs.

Comment lire et vérifier les records ?

La surface des records est conçue pour des lectures publiques et anonymes :

  • GET /api/v1/records — le flux des records sur la chaîne, avec filtres et pagination.
  • GET /api/v1/records/count — un décompte pour ce flux.
  • GET /api/v1/records/{tx_hash} — un record unique par empreinte de transaction.
  • POST /api/v1/records/{tx_hash}/verify — un rapport de vérification côté serveur.

Les routes de liste et de récupération servent des appelants anonymes — les pages de vérification publiques et les explorateurs n'ont besoin d'aucun identifiant. Un jeton porteur peut ajouter un contexte de compte là où c'est pertinent, mais la vérification publique d'un record ne doit jamais dépendre d'une session CardanoWall privée.

Utilisez ces points de terminaison pour le confort produit. Pour les contrôles à forte assurance, exécutez aussi un vérificateur autonome qui récupère les données de la chaîne via l'infrastructure Cardano qu'il choisit et produit un rapport indépendant. C'est là le partage sain : l'API facilite la création d'applications, mais la preuve doit pouvoir tenir en dehors de l'API. Les SDK et la CLI open source embarquent exactement ce vérificateur — voir vérifier un record Label 309 pour comprendre son fonctionnement de bout en bout.

Comment l'authentification doit-elle fonctionner ?

Gardez des identifiants étroits, et gardez les identifiants d'opérateur sur votre backend.

Le gateway sépare deux plans. Vos utilisateurs agissent via le plan de données (/api/v1/*) avec un jeton de compte à courte durée de vie ou une clé d'API que votre backend émet par session. Votre backend détient seul l'identifiant d'opérateur du plan de contrôle (/control/v1/*) — provisionnement des comptes, application de crédits lorsque votre facturation encaisse, définition des marges et émission de ces jetons de compte.

L'accès au plan de données est restreint par portée. Les portées que vous utiliserez :

  • poe:create — devis, téléversement, publication et publication par lot ;
  • poe:read — lecture de records, route de vérification et flux de statut lorsque l'appel porte un jeton porteur ;
  • account:read — lecture du solde et du registre ;
  • webhooks:read et webhooks:write — gestion des webhooks limitée au compte ;
  • billing:read — réservée aux surfaces de facturation du fournisseur.

Une page de publication a besoin de poe:create ; un widget de solde a besoin de account:read ; ni l'une ni l'autre n'a besoin de plus. Les identifiants d'opérateur ne doivent jamais atteindre un bundle de navigateur, une application mobile, le script d'un partenaire ou un job CI qui n'a qu'à publier des preuves — ceux-ci émettent plutôt leur propre jeton de compte à portée restreinte. Une fuite de jeton de compte doit rester un problème d'une heure, pas un incident.

Comment gérer les nouvelles tentatives et l'idempotence ?

Concevez les nouvelles tentatives avant la production, car les systèmes de publication échouent de façon banale : coupures réseau, devis expirés, solde insuffisant, limites de débit, un téléversement encore en cours ou un flux de statut interrompu.

Une intégration solide devrait :

  • recourir à l'idempotence là où l'API la prend en charge, indexée sur un identifiant d'origine stable ;
  • traiter l'expiration d'un devis comme normale — récupérez un nouveau devis et continuez ;
  • interroger le point de terminaison faisant autorité (tentative ou record) après un échec incertain, plutôt que de resoumettre à l'aveugle ;
  • éviter de téléverser deux fois les fichiers volumineux ;
  • éviter de créditer deux fois les soldes (indexez chaque crédit sur l'identifiant propre du paiement) ;
  • journaliser les identifiants de requête et de gateway pour le support ;
  • distinguer dans vos rapports une publication en échec d'un record invérifiable.

La publication déduplique sur les octets du record, et les lots de téléversement prennent en charge la relecture idempotente. Appuyez-vous sur cette sémantique plutôt que sur une boucle « on réessaie en espérant ».

Que doivent faire les webhooks ?

Les webhooks sont la voie par laquelle vous construisez vos modèles de lecture — non pas en interrogeant chaque seconde, et surtout pas en lisant les tables de base de données du gateway, qui sont internes au moteur et changent sans préavis.

Enregistrez un abonnement webhook et le gateway vous pousse les événements de cycle de vie : poe_status_changed, balance_changed, intentions de remboursement, échecs de téléversement. Les opérateurs peuvent s'abonner au firehose complet à l'échelle de l'instance ; des routes webhook limitées au compte existent aussi sur le plan de données. Une vue « Messages envoyés » — chaque utilisateur voyant les records qu'il a publiés, avec leur statut en direct — en est l'usage canonique : consommez poe_status_changed, projetez-le dans votre propre table et faites le rendu à partir de là.

Votre récepteur devrait vérifier la signature de chaque livraison, accepter une livraison au moins une fois, indexer les projections sur l'identifiant d'événement ou de livraison, et traiter une nouvelle livraison comme sans effet. Le modèle de lecture appartient à votre application. L'état canonique des dépenses et des publications appartient au gateway — mettez-le en cache pour le rendu s'il le faut, mais lisez le gateway pour toute décision qui conditionne une dépense.

Que ne doit jamais quitter le client ?

Le matériel d'identité privé. Votre application appelle l'API pour publier des records ; elle ne doit jamais confier au gateway la graine d'identité de l'utilisateur, sa clé privée de signature ou la clé privée d'un destinataire.

  • Pour les records signés, signez localement ou recourez à une signature hors hôte — les SDK exposent un flux où la clé privée réside dans un KMS, un HSM ou une machine isolée, et où seuls la clé publique et la signature passent sur le réseau.
  • Pour les records scellés, chiffrez localement avant le téléversement lorsque le cas d'usage exige une confidentialité de bout en bout.
  • Pour la vérification par le destinataire, déchiffrez localement.

L'API sert à publier et à gérer le cycle de vie. Elle n'est pas la racine de confiance, et elle est conçue pour ne jamais avoir à l'être. Pour le principe plus général, voir pourquoi les clés ne quittent jamais l'appareil.

Par où commencer

Le chemin le plus rapide passe par les SDK et la CLI open source sur github.com/cardanowall : un SDK TypeScript (@cardanowall/sdk-ts), un SDK Python (cardanowall-sdk), un SDK Rust (cardanowall) et la CLI cardanowall. Tous sont indépendants du gateway — vous fournissez l'URL de base et une clé d'API opaque — et tous embarquent le même vérificateur autonome. Si vous préférez d'abord piloter l'API à la main, publiez votre première preuve vous guide à travers un record de bout en bout, et utiliser la CLI en automatisation couvre le chemin scripté. Et si vous voulez exécuter le backend vous-même plutôt que d'utiliser celui qui est hébergé, le gateway est lui aussi open source — voir exécuter votre propre gateway.

Pour aller plus loin

apidevelopersgateway