/ API_REFERENCE.md
API_REFERENCE.md
  1  # API Reference
  2  
  3  This document covers the APIs provided by kabashira's daemons.
  4  
  5  ## kabashirad APIs
  6  
  7  kabashirad provides two APIs:
  8  - **UNIX Socket API** (JSON-lines) - for local tool integration
  9  - **HTTP API** - for shimi coordination and monitoring
 10  
 11  ### UNIX Socket API
 12  
 13  Connect to the socket (default: `/tmp/kabashira.sock`) and exchange JSON messages, one per line.
 14  
 15  #### Protocol
 16  
 17  ```
 18  Client: {"cmd": "CommandName", "param": "value"}\n
 19  Server: {"type": "ResponseType", ...}\n
 20  ```
 21  
 22  #### Commands
 23  
 24  ##### Status
 25  
 26  Get daemon status.
 27  
 28  ```json
 29  // Request
 30  {"cmd": "Status"}
 31  
 32  // Response
 33  {
 34    "type": "Status",
 35    "overlay": "1234abcd...",
 36    "peers": 1500,
 37    "captured": 0,
 38    "uptime_secs": 3600,
 39    "stats": {
 40      "fetches_attempted": 100,
 41      "fetches_succeeded": 95,
 42      "connections_made": 200,
 43      "connections_rejected": 180
 44    }
 45  }
 46  ```
 47  
 48  ##### Topology
 49  
 50  Find peers closest to a chunk hash.
 51  
 52  ```json
 53  // Request
 54  {"cmd": "Topology", "hash": "162499c6b85bd8bd...", "limit": 10}
 55  
 56  // Response
 57  {
 58    "type": "Topology",
 59    "hash": "162499c6b85bd8bd...",
 60    "underlays": [
 61      "/ip4/1.2.3.4/tcp/1634/p2p/16Uiu2HAm...",
 62      "/ip4/5.6.7.8/tcp/1634/p2p/16Uiu2HAm..."
 63    ]
 64  }
 65  ```
 66  
 67  ##### ListPeers
 68  
 69  List known peers, optionally filtered by proximity.
 70  
 71  ```json
 72  // Request - all peers (limited)
 73  {"cmd": "ListPeers", "limit": 50}
 74  
 75  // Request - closest to a hash
 76  {"cmd": "ListPeers", "closest_to": "abcd1234...", "limit": 10}
 77  
 78  // Response
 79  {
 80    "type": "Peers",
 81    "count": 50,
 82    "peers": [
 83      {
 84        "overlay": "1234abcd...",
 85        "underlays": ["/ip4/1.2.3.4/tcp/1634/p2p/16Uiu2HAm..."],
 86        "full_node": true,
 87        "last_seen": 1704067200,
 88        "success_count": 15,
 89        "failure_count": 2
 90      }
 91    ]
 92  }
 93  ```
 94  
 95  ##### ReportResult
 96  
 97  Report a fetch result for peer health tracking.
 98  
 99  ```json
100  // Request
101  {"cmd": "ReportResult", "peer": "/ip4/1.2.3.4/tcp/1634/p2p/16Uiu2HAm...", "success": true}
102  
103  // Response
104  {"type": "Ok", "message": "Result recorded"}
105  ```
106  
107  ##### GetHealth
108  
109  Get peer list health analysis.
110  
111  ```json
112  // Request
113  {"cmd": "GetHealth"}
114  
115  // Response
116  {
117    "type": "Health",
118    "health": {
119      "total_peers": 1500,
120      "healthy_peers": 1200,
121      "unhealthy_peers": 300,
122      "bins": [45, 52, 48, ...],  // peers per PO bin
123      "coverage": 0.85,
124      "avg_success_rate": 0.92
125    }
126  }
127  ```
128  
129  ##### FetchChunk
130  
131  Fetch a chunk using the daemon's connection pool.
132  
133  ```json
134  // Request
135  {"cmd": "FetchChunk", "hash": "162499c6b85bd8bd...", "max_retries": 20}
136  
137  // Response (success)
138  {
139    "type": "Chunk",
140    "hash": "162499c6b85bd8bd...",
141    "data": "0000000000000ec8...",  // hex-encoded span + payload
142    "size": 3784,
143    "from_peer": "/ip4/1.2.3.4/tcp/1634/p2p/16Uiu2HAm..."
144  }
145  
146  // Response (failure)
147  {"type": "Error", "message": "Chunk not found after 20 attempts"}
148  ```
149  
150  ##### PoolStats
151  
152  Get connection pool statistics.
153  
154  ```json
155  // Request
156  {"cmd": "PoolStats"}
157  
158  // Response
159  {
160    "type": "PoolStats",
161    "total": 200,
162    "ready": 45,
163    "busy": 3,
164    "failed": 152
165  }
166  ```
167  
168  ##### ExportGraph
169  
170  Export peer graph for visualization.
171  
172  ```json
173  // Request
174  {"cmd": "ExportGraph", "format": "graphml"}
175  
176  // Response
177  {
178    "type": "Graph",
179    "format": "graphml",
180    "nodes": 1500,
181    "edges": 15000,
182    "data": "<?xml version=\"1.0\"?>..."
183  }
184  ```
185  
186  Supported formats: `graphml`, `gexf`, `dot`, `json`
187  
188  ##### AddPeer
189  
190  Add a peer manually.
191  
192  ```json
193  // Request
194  {"cmd": "AddPeer", "addr": "/ip4/1.2.3.4/tcp/1634/p2p/16Uiu2HAm..."}
195  
196  // Response
197  {"type": "Ok", "message": "Peer added"}
198  ```
199  
200  ##### Ping
201  
202  Test connection.
203  
204  ```json
205  // Request
206  {"cmd": "Ping"}
207  
208  // Response
209  {"type": "Pong"}
210  ```
211  
212  ##### Shutdown
213  
214  Gracefully shutdown the daemon.
215  
216  ```json
217  // Request
218  {"cmd": "Shutdown"}
219  
220  // Response
221  {"type": "Ok", "message": "Shutting down"}
222  ```
223  
224  #### Example Client Code
225  
226  ```python
227  import socket
228  import json
229  
230  def query_daemon(cmd):
231      sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
232      sock.connect('/tmp/kabashira.sock')
233  
234      sock.send((json.dumps(cmd) + '\n').encode())
235      response = sock.recv(65536).decode()
236      sock.close()
237  
238      return json.loads(response)
239  
240  # Get peers closest to a chunk
241  result = query_daemon({
242      "cmd": "Topology",
243      "hash": "162499c6b85bd8bd2d8c52ae0129e1b0e8c795a43528529098a48af41f22a0e3",
244      "limit": 5
245  })
246  print(result['underlays'])
247  ```
248  
249  ---
250  
251  ### HTTP API
252  
253  Default port: 9100. Used for shimi coordination and monitoring.
254  
255  #### GET /health
256  
257  Health check endpoint.
258  
259  ```bash
260  curl http://localhost:9100/health
261  ```
262  
263  Response:
264  ```json
265  {
266    "status": "ok",
267    "peers": 1500,
268    "uptime_secs": 3600
269  }
270  ```
271  
272  #### GET /topology/peers
273  
274  List known peers with optional filtering.
275  
276  ```bash
277  # All peers
278  curl http://localhost:9100/topology/peers
279  
280  # Filter by minimum success rate
281  curl "http://localhost:9100/topology/peers?min_success_rate=0.8"
282  ```
283  
284  Response:
285  ```json
286  {
287    "count": 1500,
288    "peers": [
289      {
290        "overlay": "1234abcd...",
291        "underlays": [...],
292        "full_node": true,
293        "success_count": 15,
294        "failure_count": 2
295      }
296    ]
297  }
298  ```
299  
300  #### GET /topology/stats
301  
302  Get topology statistics.
303  
304  ```bash
305  curl http://localhost:9100/topology/stats
306  ```
307  
308  Response:
309  ```json
310  {
311    "total_peers": 1500,
312    "healthy_peers": 1200,
313    "bins": [45, 52, 48, ...],
314    "shimis_registered": 3,
315    "fetches_total": 1000,
316    "fetches_succeeded": 950
317  }
318  ```
319  
320  #### GET /topology/graph/:format
321  
322  Export peer graph in specified format.
323  
324  ```bash
325  # GraphML format
326  curl http://localhost:9100/topology/graph/graphml > graph.graphml
327  
328  # GEXF format (for Gephi)
329  curl http://localhost:9100/topology/graph/gexf > graph.gexf
330  
331  # DOT format (for Graphviz)
332  curl http://localhost:9100/topology/graph/dot > graph.dot
333  
334  # JSON format
335  curl http://localhost:9100/topology/graph/json > graph.json
336  ```
337  
338  #### POST /register
339  
340  Register a shimi instance with the topology daemon.
341  
342  ```bash
343  curl -X POST http://localhost:9100/register \
344    -H "Content-Type: application/json" \
345    -d '{
346      "overlay": "abcd1234...",
347      "underlay": "/ip4/192.168.1.10/tcp/1634/p2p/16Uiu2HAm...",
348      "radius": 9
349    }'
350  ```
351  
352  Response:
353  ```json
354  {
355    "status": "registered",
356    "overlay": "abcd1234...",
357    "peer_revision": 42,
358    "peers": [...]  // Initial peer list
359  }
360  ```
361  
362  #### POST /heartbeat/:overlay
363  
364  Send heartbeat from a shimi instance.
365  
366  ```bash
367  curl -X POST http://localhost:9100/heartbeat/abcd1234... \
368    -H "Content-Type: application/json" \
369    -d '{
370      "chunks_stored": 50000,
371      "chunks_served": 150,
372      "uptime_secs": 3600,
373      "peer_revision": 42
374    }'
375  ```
376  
377  Response:
378  ```json
379  {
380    "status": "ok",
381    "peer_revision": 45,
382    "peers": [...]  // Peer delta if revision changed
383  }
384  ```
385  
386  #### DELETE /register/:overlay
387  
388  Deregister a shimi instance.
389  
390  ```bash
391  curl -X DELETE http://localhost:9100/register/abcd1234...
392  ```
393  
394  Response:
395  ```json
396  {"status": "deregistered"}
397  ```
398  
399  ---
400  
401  ## kusarid API
402  
403  kusarid provides chain state over HTTP. Default port: 9101.
404  
405  ### State Persistence
406  
407  kusarid supports persisting its state to a gzipped JSON file via `--state <PATH>`. This avoids re-syncing from the chain on restart. The state file contains:
408  
409  - Last synced block number
410  - Current price and storage radius
411  - All valid postage batches
412  
413  See [CLI Reference](./CLI_REFERENCE.md#kusarid-鎖d) for usage.
414  
415  ### Endpoints
416  
417  #### GET /health
418  
419  Health and sync status.
420  
421  ```bash
422  curl http://localhost:9101/health
423  ```
424  
425  Response:
426  ```json
427  {
428    "status": "synced",
429    "block": 12345678,
430    "behind_blocks": 0,
431    "last_update": "2024-01-01T12:00:00Z"
432  }
433  ```
434  
435  #### GET /chain/state
436  
437  Current chain state.
438  
439  ```bash
440  curl http://localhost:9101/chain/state
441  ```
442  
443  Response:
444  ```json
445  {
446    "block": 12345678,
447    "price": "1000000000000",
448    "radius": 9,
449    "total_batches": 17092,
450    "valid_batches": 17092
451  }
452  ```
453  
454  #### GET /chain/batches
455  
456  List valid postage batches.
457  
458  ```bash
459  curl http://localhost:9101/chain/batches
460  ```
461  
462  Response:
463  ```json
464  {
465    "count": 4500,
466    "batches": [
467      {
468        "id": "abcd1234...",
469        "owner": "0x1234...",
470        "depth": 20,
471        "amount": "100000000000",
472        "bucket_depth": 16,
473        "immutable": true,
474        "created_block": 12340000,
475        "expires_block": 12500000
476      }
477    ]
478  }
479  ```
480  
481  #### GET /chain/batch/:id
482  
483  Get specific batch info.
484  
485  ```bash
486  curl http://localhost:9101/chain/batch/abcd1234...
487  ```
488  
489  Response:
490  ```json
491  {
492    "id": "abcd1234...",
493    "owner": "0x1234...",
494    "depth": 20,
495    "amount": "100000000000",
496    "bucket_depth": 16,
497    "immutable": true,
498    "created_block": 12340000,
499    "expires_block": 12500000,
500    "utilization": 0.75
501  }
502  ```
503  
504  #### GET /chain/radius
505  
506  Get current storage radius.
507  
508  ```bash
509  curl http://localhost:9101/chain/radius
510  ```
511  
512  Response:
513  ```json
514  {
515    "radius": 9,
516    "calculated_at_block": 44239957
517  }
518  ```
519  
520  ---
521  
522  ## Error Responses
523  
524  All APIs return errors in a consistent format:
525  
526  ```json
527  {
528    "type": "Error",
529    "message": "Description of what went wrong"
530  }
531  ```
532  
533  HTTP APIs use appropriate status codes:
534  - `200` - Success
535  - `400` - Bad request (invalid parameters)
536  - `404` - Not found (unknown batch, peer, etc.)
537  - `500` - Internal error
538  - `503` - Service unavailable (still syncing, etc.)