**Motivations:** - Fix insufficient UTXO amount error in anchor API - Ensure continuous availability of usable UTXOs for anchor transactions - Improve anchor transaction reliability and efficiency **Root causes:** - UTXO selection logic was too restrictive, rejecting UTXOs larger than needed - No automatic provisioning of new usable UTXOs when existing ones were not suitable - Algorithm prevented efficient use of available UTXOs **Correctifs:** - Refactored createAnchorTransaction() to provision 7 UTXOs of 2500 sats on each anchor - Use single large UTXO to create 1 anchor output + 7 provisioning outputs + change - Simplified UTXO selection: single large UTXO per transaction instead of multiple small ones - Added UTXO provisioning logic in signet-dashboard - Enhanced Bitcoin RPC methods in both api-anchorage and signet-dashboard - Added documentation in fixKnowledge/api-anchorage-utxo-provisioning.md **Evolutions:** - Enhanced signet-dashboard with new pages (hash-list, utxo-list, join-signet, api-docs) - Improved Bitcoin RPC client with better error handling and UTXO management - Added cache files for hash and UTXO lists - Updated api-faucet with improved server configuration - Enhanced anchor count tracking **Pages affectées:** - api-anchorage/src/bitcoin-rpc.js: Complete refactor of createAnchorTransaction() - api-anchorage/src/routes/anchor.js: Enhanced anchor route - api-anchorage/src/server.js: Server configuration updates - signet-dashboard/src/bitcoin-rpc.js: Added comprehensive Bitcoin RPC client - signet-dashboard/src/server.js: Enhanced server with new routes - signet-dashboard/public/: Added new HTML pages and updated app.js - api-faucet/src/server.js: Server improvements - api-faucet/README.md: Documentation updates - fixKnowledge/api-anchorage-utxo-provisioning.md: New documentation - anchor_count.txt, hash_list.txt, utxo_list.txt: Tracking files
702 lines
27 KiB
HTML
702 lines
27 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="fr">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>Documentation API d'Ancrage - Bitcoin Ancrage</title>
|
||
<link rel="stylesheet" href="styles.css">
|
||
<style>
|
||
.api-docs-section {
|
||
margin-bottom: 40px;
|
||
}
|
||
|
||
.endpoint-card {
|
||
background: var(--card-background);
|
||
padding: 30px;
|
||
border-radius: 10px;
|
||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||
margin-bottom: 30px;
|
||
}
|
||
|
||
.endpoint-header {
|
||
display: flex;
|
||
align-items: center;
|
||
margin-bottom: 20px;
|
||
padding-bottom: 15px;
|
||
border-bottom: 2px solid var(--border-color);
|
||
}
|
||
|
||
.method-badge {
|
||
display: inline-block;
|
||
padding: 5px 15px;
|
||
border-radius: 5px;
|
||
font-weight: bold;
|
||
font-size: 0.9em;
|
||
margin-right: 15px;
|
||
min-width: 70px;
|
||
text-align: center;
|
||
}
|
||
|
||
.method-get {
|
||
background: #28a745;
|
||
color: white;
|
||
}
|
||
|
||
.method-post {
|
||
background: #007bff;
|
||
color: white;
|
||
}
|
||
|
||
.endpoint-path {
|
||
font-family: 'Courier New', monospace;
|
||
font-size: 1.2em;
|
||
color: var(--primary-color);
|
||
font-weight: bold;
|
||
}
|
||
|
||
.endpoint-description {
|
||
margin: 20px 0;
|
||
color: var(--text-color);
|
||
line-height: 1.6;
|
||
}
|
||
|
||
.endpoint-params {
|
||
margin: 20px 0;
|
||
}
|
||
|
||
.endpoint-params h4 {
|
||
color: var(--primary-color);
|
||
margin-bottom: 10px;
|
||
}
|
||
|
||
.param-table {
|
||
width: 100%;
|
||
border-collapse: collapse;
|
||
margin: 15px 0;
|
||
}
|
||
|
||
.param-table th,
|
||
.param-table td {
|
||
padding: 12px;
|
||
text-align: left;
|
||
border-bottom: 1px solid var(--border-color);
|
||
}
|
||
|
||
.param-table th {
|
||
background: #f5f5f5;
|
||
font-weight: bold;
|
||
}
|
||
|
||
.param-name {
|
||
font-family: 'Courier New', monospace;
|
||
color: var(--primary-color);
|
||
font-weight: bold;
|
||
}
|
||
|
||
.param-required {
|
||
color: var(--error-color);
|
||
font-weight: bold;
|
||
}
|
||
|
||
.param-optional {
|
||
color: #666;
|
||
}
|
||
|
||
.code-block {
|
||
background: #1e1e1e;
|
||
color: #d4d4d4;
|
||
padding: 20px;
|
||
border-radius: 5px;
|
||
font-family: 'Courier New', monospace;
|
||
font-size: 0.9em;
|
||
line-height: 1.6;
|
||
overflow-x: auto;
|
||
margin: 20px 0;
|
||
}
|
||
|
||
.code-block pre {
|
||
margin: 0;
|
||
white-space: pre-wrap;
|
||
word-wrap: break-word;
|
||
}
|
||
|
||
.response-example {
|
||
margin: 20px 0;
|
||
}
|
||
|
||
.response-example h4 {
|
||
color: var(--primary-color);
|
||
margin-bottom: 10px;
|
||
}
|
||
|
||
.info-box {
|
||
background: #e7f3ff;
|
||
border-left: 4px solid #2196F3;
|
||
padding: 15px;
|
||
margin: 20px 0;
|
||
border-radius: 5px;
|
||
}
|
||
|
||
.warning-box {
|
||
background: #fff3cd;
|
||
border-left: 4px solid #ffc107;
|
||
padding: 15px;
|
||
margin: 20px 0;
|
||
border-radius: 5px;
|
||
}
|
||
|
||
.error-box {
|
||
background: #f8d7da;
|
||
border-left: 4px solid #dc3545;
|
||
padding: 15px;
|
||
margin: 20px 0;
|
||
border-radius: 5px;
|
||
}
|
||
|
||
.auth-section {
|
||
background: var(--card-background);
|
||
padding: 30px;
|
||
border-radius: 10px;
|
||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||
margin-bottom: 30px;
|
||
}
|
||
|
||
.copy-button {
|
||
background: var(--primary-color);
|
||
color: white;
|
||
border: none;
|
||
padding: 8px 15px;
|
||
border-radius: 5px;
|
||
cursor: pointer;
|
||
font-size: 0.9em;
|
||
margin-top: 10px;
|
||
transition: background 0.3s;
|
||
}
|
||
|
||
.copy-button:hover {
|
||
background: #e0820d;
|
||
}
|
||
|
||
.status-code {
|
||
display: inline-block;
|
||
padding: 3px 8px;
|
||
border-radius: 3px;
|
||
font-size: 0.85em;
|
||
font-weight: bold;
|
||
margin-right: 10px;
|
||
}
|
||
|
||
.status-200 {
|
||
background: #28a745;
|
||
color: white;
|
||
}
|
||
|
||
.status-400 {
|
||
background: #ffc107;
|
||
color: #000;
|
||
}
|
||
|
||
.status-401 {
|
||
background: #dc3545;
|
||
color: white;
|
||
}
|
||
|
||
.status-402 {
|
||
background: #ff9800;
|
||
color: white;
|
||
}
|
||
|
||
.status-500 {
|
||
background: #dc3545;
|
||
color: white;
|
||
}
|
||
|
||
.status-503 {
|
||
background: #ff9800;
|
||
color: white;
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div class="container">
|
||
<a href="/" class="back-link">← Retour au Dashboard</a>
|
||
|
||
<header>
|
||
<h1>Documentation API d'Ancrage</h1>
|
||
<p class="subtitle">API REST pour ancrer et vérifier des documents sur Bitcoin Signet, et utiliser le faucet</p>
|
||
</header>
|
||
|
||
<main>
|
||
<!-- Section Authentification -->
|
||
<section class="api-docs-section">
|
||
<div class="auth-section">
|
||
<h2>🔐 Authentification</h2>
|
||
<p>Toutes les requêtes vers l'API d'ancrage (sauf les endpoints publics) nécessitent une clé API dans le header <code>X-API-Key</code>.</p>
|
||
|
||
<div class="code-block">
|
||
<pre>X-API-Key: votre-clé-api-ici</pre>
|
||
</div>
|
||
|
||
<div class="info-box">
|
||
<p><strong>Endpoints publics (sans authentification) :</strong></p>
|
||
<ul style="margin-left: 20px; margin-top: 10px;">
|
||
<li><code>GET /health</code> - Vérification de santé (API d'ancrage)</li>
|
||
<li><code>GET /api/anchor/locked-utxos</code> - Liste des UTXO verrouillés</li>
|
||
<li><code>GET /health</code> - Vérification de santé (API faucet)</li>
|
||
</ul>
|
||
<p style="margin-top: 10px;"><strong>Endpoints nécessitant une clé API :</strong></p>
|
||
<ul style="margin-left: 20px; margin-top: 10px;">
|
||
<li><code>POST /api/anchor/document</code> - Ancrer un document</li>
|
||
<li><code>POST /api/anchor/verify</code> - Vérifier un hash</li>
|
||
<li><code>POST /api/faucet/request</code> - Demander des sats</li>
|
||
</ul>
|
||
</div>
|
||
|
||
<div class="warning-box">
|
||
<p><strong>⚠️ Important :</strong> Conservez votre clé API secrète et ne la partagez jamais publiquement.</p>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Endpoint: Health -->
|
||
<section class="api-docs-section">
|
||
<div class="endpoint-card">
|
||
<div class="endpoint-header">
|
||
<span class="method-badge method-get">GET</span>
|
||
<span class="endpoint-path">/health</span>
|
||
</div>
|
||
|
||
<div class="endpoint-description">
|
||
<p>Vérifie l'état de santé de l'API. Cet endpoint est public et ne nécessite pas d'authentification.</p>
|
||
</div>
|
||
|
||
<div class="response-example">
|
||
<h4>Réponse (200 OK)</h4>
|
||
<div class="code-block">
|
||
<pre>{
|
||
"ok": true,
|
||
"service": "anchor-api",
|
||
"bitcoin": {
|
||
"connected": true,
|
||
"blocks": 12345
|
||
},
|
||
"timestamp": "2026-01-25T12:00:00.000Z"
|
||
}</pre>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="response-example">
|
||
<h4>Réponse (503 Service Unavailable) - Bitcoin non connecté</h4>
|
||
<div class="code-block">
|
||
<pre>{
|
||
"ok": false,
|
||
"service": "anchor-api",
|
||
"error": "Bitcoin RPC connection failed",
|
||
"timestamp": "2026-01-25T12:00:00.000Z"
|
||
}</pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Endpoint: Anchor Document -->
|
||
<section class="api-docs-section">
|
||
<div class="endpoint-card">
|
||
<div class="endpoint-header">
|
||
<span class="method-badge method-post">POST</span>
|
||
<span class="endpoint-path">/api/anchor/document</span>
|
||
</div>
|
||
|
||
<div class="endpoint-description">
|
||
<p>Ancre un document sur la blockchain Bitcoin Signet en créant une transaction qui inclut le hash du document dans un OP_RETURN.</p>
|
||
</div>
|
||
|
||
<div class="endpoint-params">
|
||
<h4>Paramètres (Body JSON)</h4>
|
||
<table class="param-table">
|
||
<thead>
|
||
<tr>
|
||
<th>Paramètre</th>
|
||
<th>Type</th>
|
||
<th>Requis</th>
|
||
<th>Description</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td class="param-name">hash</td>
|
||
<td>string</td>
|
||
<td><span class="param-required">Oui</span></td>
|
||
<td>Hash SHA256 du document en hexadécimal (64 caractères)</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="param-name">documentUid</td>
|
||
<td>string</td>
|
||
<td><span class="param-optional">Non</span></td>
|
||
<td>Identifiant optionnel du document (pour le logging)</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
|
||
<div class="response-example">
|
||
<h4>Exemple de requête</h4>
|
||
<div class="code-block">
|
||
<pre>curl -X POST https://certificator.4nkweb.com/api/anchor/document \
|
||
-H "Content-Type: application/json" \
|
||
-H "X-API-Key: votre-clé-api" \
|
||
-d '{
|
||
"hash": "a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456",
|
||
"documentUid": "doc-12345"
|
||
}'</pre>
|
||
</div>
|
||
<button class="copy-button" onclick="copyCode(this)">📋 Copier</button>
|
||
</div>
|
||
|
||
<div class="response-example">
|
||
<h4>Réponse (200 OK)</h4>
|
||
<div class="code-block">
|
||
<pre>{
|
||
"txid": "abc123def456...",
|
||
"status": "pending",
|
||
"confirmations": 0,
|
||
"block_height": null
|
||
}</pre>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="response-example">
|
||
<h4>Codes de statut possibles</h4>
|
||
<ul style="margin-left: 20px;">
|
||
<li><span class="status-code status-200">200</span> Succès - Transaction créée et envoyée au mempool</li>
|
||
<li><span class="status-code status-400">400</span> Requête invalide - Hash manquant ou format incorrect</li>
|
||
<li><span class="status-code status-401">401</span> Non autorisé - Clé API manquante ou invalide</li>
|
||
<li><span class="status-code status-402">402</span> Solde insuffisant - Pas assez de fonds pour créer la transaction</li>
|
||
<li><span class="status-code status-500">500</span> Erreur serveur - Erreur interne lors de la création de la transaction</li>
|
||
</ul>
|
||
</div>
|
||
|
||
<div class="error-box">
|
||
<h4>Exemple d'erreur (402 Payment Required)</h4>
|
||
<div class="code-block">
|
||
<pre>{
|
||
"error": "Insufficient Balance",
|
||
"message": "Insufficient balance to create anchor transaction"
|
||
}</pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Endpoint: Verify -->
|
||
<section class="api-docs-section">
|
||
<div class="endpoint-card">
|
||
<div class="endpoint-header">
|
||
<span class="method-badge method-post">POST</span>
|
||
<span class="endpoint-path">/api/anchor/verify</span>
|
||
</div>
|
||
|
||
<div class="endpoint-description">
|
||
<p>Vérifie si un hash est ancré sur la blockchain Bitcoin Signet. Recherche dans les transactions OP_RETURN pour trouver le hash.</p>
|
||
</div>
|
||
|
||
<div class="endpoint-params">
|
||
<h4>Paramètres (Body JSON)</h4>
|
||
<table class="param-table">
|
||
<thead>
|
||
<tr>
|
||
<th>Paramètre</th>
|
||
<th>Type</th>
|
||
<th>Requis</th>
|
||
<th>Description</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td class="param-name">hash</td>
|
||
<td>string</td>
|
||
<td><span class="param-required">Oui</span></td>
|
||
<td>Hash SHA256 à vérifier (64 caractères hex)</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="param-name">txid</td>
|
||
<td>string</td>
|
||
<td><span class="param-optional">Non</span></td>
|
||
<td>ID de transaction optionnel pour accélérer la recherche</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
|
||
<div class="response-example">
|
||
<h4>Exemple de requête</h4>
|
||
<div class="code-block">
|
||
<pre>curl -X POST https://certificator.4nkweb.com/api/anchor/verify \
|
||
-H "Content-Type: application/json" \
|
||
-H "X-API-Key: votre-clé-api" \
|
||
-d '{
|
||
"hash": "a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456",
|
||
"txid": "abc123def456..."
|
||
}'</pre>
|
||
</div>
|
||
<button class="copy-button" onclick="copyCode(this)">📋 Copier</button>
|
||
</div>
|
||
|
||
<div class="response-example">
|
||
<h4>Réponse (200 OK) - Hash trouvé</h4>
|
||
<div class="code-block">
|
||
<pre>{
|
||
"found": true,
|
||
"txid": "abc123def456...",
|
||
"block_height": 12345,
|
||
"confirmations": 100,
|
||
"timestamp": "2026-01-25T10:00:00.000Z"
|
||
}</pre>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="response-example">
|
||
<h4>Réponse (200 OK) - Hash non trouvé</h4>
|
||
<div class="code-block">
|
||
<pre>{
|
||
"found": false,
|
||
"txid": null,
|
||
"block_height": null,
|
||
"confirmations": null,
|
||
"timestamp": null
|
||
}</pre>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="response-example">
|
||
<h4>Codes de statut possibles</h4>
|
||
<ul style="margin-left: 20px;">
|
||
<li><span class="status-code status-200">200</span> Succès - Vérification effectuée</li>
|
||
<li><span class="status-code status-400">400</span> Requête invalide - Hash manquant ou format incorrect</li>
|
||
<li><span class="status-code status-401">401</span> Non autorisé - Clé API manquante ou invalide</li>
|
||
<li><span class="status-code status-500">500</span> Erreur serveur - Erreur interne lors de la vérification</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Endpoint: Locked UTXOs -->
|
||
<section class="api-docs-section">
|
||
<div class="endpoint-card">
|
||
<div class="endpoint-header">
|
||
<span class="method-badge method-get">GET</span>
|
||
<span class="endpoint-path">/api/anchor/locked-utxos</span>
|
||
</div>
|
||
|
||
<div class="endpoint-description">
|
||
<p>Retourne la liste des UTXO actuellement verrouillés par le mutex de l'API. Cet endpoint est public et ne nécessite pas d'authentification.</p>
|
||
</div>
|
||
|
||
<div class="response-example">
|
||
<h4>Exemple de requête</h4>
|
||
<div class="code-block">
|
||
<pre>curl -X GET https://certificator.4nkweb.com/api/anchor/locked-utxos</pre>
|
||
</div>
|
||
<button class="copy-button" onclick="copyCode(this)">📋 Copier</button>
|
||
</div>
|
||
|
||
<div class="response-example">
|
||
<h4>Réponse (200 OK)</h4>
|
||
<div class="code-block">
|
||
<pre>{
|
||
"locked": [
|
||
{
|
||
"txid": "abc123def456...",
|
||
"vout": 0
|
||
},
|
||
{
|
||
"txid": "def456abc123...",
|
||
"vout": 1
|
||
}
|
||
],
|
||
"count": 2
|
||
}</pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Endpoint: Faucet Request -->
|
||
<section class="api-docs-section">
|
||
<div class="endpoint-card">
|
||
<div class="endpoint-header">
|
||
<span class="method-badge method-post">POST</span>
|
||
<span class="endpoint-path">/api/faucet/request</span>
|
||
</div>
|
||
|
||
<div class="endpoint-description">
|
||
<p>Demande des sats (testnet coins) via le faucet. Distribue 50 000 sats (0.0005 BTC) par défaut sur une adresse Bitcoin Signet valide. Nécessite une clé API valide dans le header <code>x-api-key</code>.</p>
|
||
</div>
|
||
|
||
<div class="endpoint-params">
|
||
<h4>Paramètres (Body JSON)</h4>
|
||
<table class="param-table">
|
||
<thead>
|
||
<tr>
|
||
<th>Paramètre</th>
|
||
<th>Type</th>
|
||
<th>Requis</th>
|
||
<th>Description</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td class="param-name">address</td>
|
||
<td>string</td>
|
||
<td><span class="param-required">Oui</span></td>
|
||
<td>Adresse Bitcoin Signet valide (commence par <code>tb1</code>, <code>bcrt1</code>, <code>2</code> ou <code>3</code>)</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
|
||
<div class="response-example">
|
||
<h4>Exemple de requête</h4>
|
||
<div class="code-block">
|
||
<pre>curl -X POST https://certificator.4nkweb.com/api/faucet/request \
|
||
-H "Content-Type: application/json" \
|
||
-H "x-api-key: votre-clé-api" \
|
||
-d '{
|
||
"address": "tb1qwe0nv3s0ewedd63w20r8kwnv22uw8dp2tnj3qc"
|
||
}'</pre>
|
||
</div>
|
||
<button class="copy-button" onclick="copyCode(this)">📋 Copier</button>
|
||
</div>
|
||
|
||
<div class="response-example">
|
||
<h4>Réponse (200 OK)</h4>
|
||
<div class="code-block">
|
||
<pre>{
|
||
"success": true,
|
||
"txid": "a1b2c3d4e5f6789012345678901234567890123456789012345678901234567890",
|
||
"address": "tb1qwe0nv3s0ewedd63w20r8kwnv22uw8dp2tnj3qc",
|
||
"amount": 0.0005,
|
||
"amount_sats": 50000,
|
||
"status": "pending",
|
||
"confirmations": 0,
|
||
"block_height": null
|
||
}</pre>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="response-example">
|
||
<h4>Codes de statut possibles</h4>
|
||
<ul style="margin-left: 20px;">
|
||
<li><span class="status-code status-200">200</span> Succès - Transaction créée et envoyée au mempool</li>
|
||
<li><span class="status-code status-400">400</span> Requête invalide - Adresse manquante ou format incorrect</li>
|
||
<li><span class="status-code status-401">401</span> Non autorisé - Clé API manquante ou invalide</li>
|
||
<li><span class="status-code status-503">503</span> Service indisponible - Solde insuffisant dans le wallet du faucet</li>
|
||
<li><span class="status-code status-500">500</span> Erreur serveur - Erreur interne lors de la création de la transaction</li>
|
||
</ul>
|
||
</div>
|
||
|
||
<div class="error-box">
|
||
<h4>Exemple d'erreur (401 Unauthorized)</h4>
|
||
<div class="code-block">
|
||
<pre>{
|
||
"error": "Unauthorized",
|
||
"message": "Invalid or missing API key"
|
||
}</pre>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="error-box">
|
||
<h4>Exemple d'erreur (503 Service Unavailable)</h4>
|
||
<div class="code-block">
|
||
<pre>{
|
||
"error": "Insufficient Balance",
|
||
"message": "Insufficient balance to send coins"
|
||
}</pre>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="info-box">
|
||
<h4>ℹ️ Notes importantes</h4>
|
||
<ul style="margin-left: 20px; margin-top: 10px;">
|
||
<li>Le montant par défaut est de 50 000 sats (0.0005 BTC)</li>
|
||
<li>L'adresse doit être une adresse Bitcoin Signet valide</li>
|
||
<li>La transaction est envoyée au mempool immédiatement</li>
|
||
<li>Le statut "pending" signifie que la transaction est dans le mempool mais pas encore confirmée</li>
|
||
<li>Les confirmations augmentent à mesure que les blocs sont minés</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Section Informations -->
|
||
<section class="api-docs-section">
|
||
<div class="endpoint-card">
|
||
<h2>ℹ️ Informations Complémentaires</h2>
|
||
|
||
<div class="info-box">
|
||
<h4>Format du Hash</h4>
|
||
<p>Le hash doit être un hash SHA256 en format hexadécimal, exactement 64 caractères.</p>
|
||
<div class="code-block">
|
||
<pre>Exemple valide: a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456
|
||
Longueur: 64 caractères
|
||
Format: hexadécimal (0-9, a-f, A-F)</pre>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="info-box">
|
||
<h4>Format de la Transaction</h4>
|
||
<p>Les transactions d'ancrage incluent :</p>
|
||
<ul style="margin-left: 20px; margin-top: 10px;">
|
||
<li>Un output OP_RETURN contenant "ANCHOR:" suivi du hash</li>
|
||
<li>Un output d'ancrage de 2500 sats</li>
|
||
<li>7 outputs de provisionnement de 2500 sats chacun</li>
|
||
<li>Un output de change (si nécessaire)</li>
|
||
</ul>
|
||
</div>
|
||
|
||
<div class="info-box">
|
||
<h4>Base URL</h4>
|
||
<p>L'API est accessible à l'adresse :</p>
|
||
<div class="code-block">
|
||
<pre>https://certificator.4nkweb.com</pre>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="warning-box">
|
||
<h4>⚠️ Notes importantes</h4>
|
||
<ul style="margin-left: 20px; margin-top: 10px;">
|
||
<li>Les transactions sont envoyées au mempool immédiatement</li>
|
||
<li>Le statut "pending" signifie que la transaction est dans le mempool mais pas encore confirmée</li>
|
||
<li>Les confirmations augmentent à mesure que les blocs sont minés</li>
|
||
<li>En cas d'erreur 402 (Solde insuffisant), vous devez approvisionner le wallet de l'API</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
</main>
|
||
|
||
<footer>
|
||
<p>Bitcoin Ancrage Dashboard - Équipe 4NK</p>
|
||
</footer>
|
||
</div>
|
||
|
||
<script>
|
||
function copyCode(button) {
|
||
const codeBlock = button.previousElementSibling;
|
||
const code = codeBlock.querySelector('pre')?.textContent || codeBlock.textContent;
|
||
|
||
navigator.clipboard.writeText(code).then(() => {
|
||
const originalText = button.textContent;
|
||
button.textContent = '✅ Copié !';
|
||
setTimeout(() => {
|
||
button.textContent = originalText;
|
||
}, 2000);
|
||
}).catch(err => {
|
||
console.error('Erreur lors de la copie:', err);
|
||
alert('Erreur lors de la copie. Veuillez sélectionner et copier manuellement.');
|
||
});
|
||
}
|
||
</script>
|
||
</body>
|
||
</html>
|