docs: did:dht integration architecture and DWN protocol schemas
- DHT-01: docs/did-dht-integration.md — did:dht spec analysis, DNS packet encoding, mainline crate, publication/resolution flows, security notes - SCHEMA-01: docs/dwn-protocols.md — 4 DWN protocol definitions with JSON schemas: node-identity, file-catalog, federation, app-deploy Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
642446312d
commit
0f6df9a021
@@ -0,0 +1,400 @@
|
||||
# Archipelago DWN Protocol Definitions
|
||||
|
||||
## Overview
|
||||
|
||||
These protocol definitions specify the data schemas used when Archipelago nodes exchange data via Decentralized Web Nodes (DWN). By defining protocols in the standard DWN format, any DWN-compatible application can read and write Archipelago data.
|
||||
|
||||
Each protocol defines:
|
||||
- A unique URI identifier
|
||||
- Data types with JSON schemas
|
||||
- Structure rules (who can read/write what)
|
||||
|
||||
## Protocol 1: Node Identity Announcements
|
||||
|
||||
**URI**: `https://archipelago.dev/protocols/node-identity/v1`
|
||||
|
||||
Nodes publish their identity information so federated peers can discover capabilities and status.
|
||||
|
||||
```json
|
||||
{
|
||||
"protocol": "https://archipelago.dev/protocols/node-identity/v1",
|
||||
"published": true,
|
||||
"types": {
|
||||
"announcement": {
|
||||
"schema": "https://archipelago.dev/schemas/node-announcement/v1",
|
||||
"dataFormats": ["application/json"]
|
||||
}
|
||||
},
|
||||
"structure": {
|
||||
"announcement": {
|
||||
"$actions": [
|
||||
{ "who": "anyone", "can": ["read"] },
|
||||
{ "who": "author", "of": "announcement", "can": ["write", "update", "delete"] }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Schema**: `node-announcement/v1`
|
||||
|
||||
```json
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "object",
|
||||
"required": ["did", "version", "apps", "timestamp"],
|
||||
"properties": {
|
||||
"did": {
|
||||
"type": "string",
|
||||
"description": "Node's DID (did:key or did:dht)"
|
||||
},
|
||||
"version": {
|
||||
"type": "string",
|
||||
"description": "Archipelago version (semver)"
|
||||
},
|
||||
"apps": {
|
||||
"type": "array",
|
||||
"items": { "type": "string" },
|
||||
"description": "List of installed app IDs"
|
||||
},
|
||||
"capabilities": {
|
||||
"type": "array",
|
||||
"items": { "type": "string" },
|
||||
"description": "Node capabilities (e.g., 'file-sharing', 'dwn-sync', 'tor')"
|
||||
},
|
||||
"timestamp": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"description": "ISO 8601 timestamp of announcement"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Protocol 2: File Sharing Catalog
|
||||
|
||||
**URI**: `https://archipelago.dev/protocols/file-catalog/v1`
|
||||
|
||||
Nodes publish their shared file catalogs so peers can browse available content.
|
||||
|
||||
```json
|
||||
{
|
||||
"protocol": "https://archipelago.dev/protocols/file-catalog/v1",
|
||||
"published": true,
|
||||
"types": {
|
||||
"entry": {
|
||||
"schema": "https://archipelago.dev/schemas/file-entry/v1",
|
||||
"dataFormats": ["application/json"]
|
||||
}
|
||||
},
|
||||
"structure": {
|
||||
"entry": {
|
||||
"$actions": [
|
||||
{ "who": "anyone", "can": ["read"] },
|
||||
{ "who": "author", "of": "entry", "can": ["write", "update", "delete"] }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Schema**: `file-entry/v1`
|
||||
|
||||
```json
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "object",
|
||||
"required": ["id", "title", "access", "size_bytes", "created_at"],
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"description": "Unique file entry ID"
|
||||
},
|
||||
"title": {
|
||||
"type": "string",
|
||||
"description": "Display title"
|
||||
},
|
||||
"description": {
|
||||
"type": "string",
|
||||
"description": "Optional description"
|
||||
},
|
||||
"content_type": {
|
||||
"type": "string",
|
||||
"description": "MIME type (e.g., 'application/pdf')"
|
||||
},
|
||||
"size_bytes": {
|
||||
"type": "integer",
|
||||
"description": "File size in bytes"
|
||||
},
|
||||
"access": {
|
||||
"type": "string",
|
||||
"enum": ["free", "peers-only", "paid"],
|
||||
"description": "Access level"
|
||||
},
|
||||
"price_sats": {
|
||||
"type": "integer",
|
||||
"description": "Price in satoshis (for paid access)"
|
||||
},
|
||||
"hash": {
|
||||
"type": "string",
|
||||
"description": "SHA-256 hash of file content"
|
||||
},
|
||||
"created_at": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
"tags": {
|
||||
"type": "array",
|
||||
"items": { "type": "string" },
|
||||
"description": "Content tags for filtering"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Protocol 3: Federation State
|
||||
|
||||
**URI**: `https://archipelago.dev/protocols/federation/v1`
|
||||
|
||||
Nodes publish their federation membership and peer trust status.
|
||||
|
||||
```json
|
||||
{
|
||||
"protocol": "https://archipelago.dev/protocols/federation/v1",
|
||||
"published": false,
|
||||
"types": {
|
||||
"membership": {
|
||||
"schema": "https://archipelago.dev/schemas/federation-membership/v1",
|
||||
"dataFormats": ["application/json"]
|
||||
},
|
||||
"peerStatus": {
|
||||
"schema": "https://archipelago.dev/schemas/peer-status/v1",
|
||||
"dataFormats": ["application/json"]
|
||||
}
|
||||
},
|
||||
"structure": {
|
||||
"membership": {
|
||||
"$actions": [
|
||||
{ "who": "recipient", "of": "membership", "can": ["read"] },
|
||||
{ "who": "author", "of": "membership", "can": ["write", "update", "delete"] }
|
||||
]
|
||||
},
|
||||
"peerStatus": {
|
||||
"$actions": [
|
||||
{ "who": "recipient", "of": "peerStatus", "can": ["read"] },
|
||||
{ "who": "author", "of": "peerStatus", "can": ["write", "update"] }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Schema**: `federation-membership/v1`
|
||||
|
||||
```json
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "object",
|
||||
"required": ["node_did", "trust_level", "joined_at"],
|
||||
"properties": {
|
||||
"node_did": {
|
||||
"type": "string",
|
||||
"description": "DID of the federated node"
|
||||
},
|
||||
"trust_level": {
|
||||
"type": "string",
|
||||
"enum": ["trusted", "verified", "untrusted"],
|
||||
"description": "Trust level assigned to this peer"
|
||||
},
|
||||
"joined_at": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
"last_seen": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
"apps": {
|
||||
"type": "array",
|
||||
"items": { "type": "string" },
|
||||
"description": "Apps reported by this peer"
|
||||
},
|
||||
"credential_id": {
|
||||
"type": "string",
|
||||
"description": "VC ID proving federation relationship"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Schema**: `peer-status/v1`
|
||||
|
||||
```json
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "object",
|
||||
"required": ["node_did", "online", "timestamp"],
|
||||
"properties": {
|
||||
"node_did": {
|
||||
"type": "string"
|
||||
},
|
||||
"online": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"cpu_percent": {
|
||||
"type": "number"
|
||||
},
|
||||
"memory_used_mb": {
|
||||
"type": "integer"
|
||||
},
|
||||
"disk_used_percent": {
|
||||
"type": "number"
|
||||
},
|
||||
"container_count": {
|
||||
"type": "integer"
|
||||
},
|
||||
"uptime_seconds": {
|
||||
"type": "integer"
|
||||
},
|
||||
"timestamp": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Protocol 4: App Deployment Requests
|
||||
|
||||
**URI**: `https://archipelago.dev/protocols/app-deploy/v1`
|
||||
|
||||
Enables trusted peers to request app installations on remote nodes.
|
||||
|
||||
```json
|
||||
{
|
||||
"protocol": "https://archipelago.dev/protocols/app-deploy/v1",
|
||||
"published": false,
|
||||
"types": {
|
||||
"request": {
|
||||
"schema": "https://archipelago.dev/schemas/deploy-request/v1",
|
||||
"dataFormats": ["application/json"]
|
||||
},
|
||||
"response": {
|
||||
"schema": "https://archipelago.dev/schemas/deploy-response/v1",
|
||||
"dataFormats": ["application/json"]
|
||||
}
|
||||
},
|
||||
"structure": {
|
||||
"request": {
|
||||
"$actions": [
|
||||
{ "who": "recipient", "of": "request", "can": ["read"] },
|
||||
{ "who": "author", "of": "request", "can": ["write"] }
|
||||
],
|
||||
"response": {
|
||||
"$actions": [
|
||||
{ "who": "author", "of": "request", "can": ["read"] },
|
||||
{ "who": "recipient", "of": "request", "can": ["write"] }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Schema**: `deploy-request/v1`
|
||||
|
||||
```json
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "object",
|
||||
"required": ["app_id", "requester_did", "target_did", "action"],
|
||||
"properties": {
|
||||
"app_id": {
|
||||
"type": "string",
|
||||
"description": "Application identifier (e.g., 'bitcoin-knots')"
|
||||
},
|
||||
"requester_did": {
|
||||
"type": "string",
|
||||
"description": "DID of the requesting node"
|
||||
},
|
||||
"target_did": {
|
||||
"type": "string",
|
||||
"description": "DID of the target node"
|
||||
},
|
||||
"action": {
|
||||
"type": "string",
|
||||
"enum": ["install", "update", "uninstall"],
|
||||
"description": "Deployment action"
|
||||
},
|
||||
"image": {
|
||||
"type": "string",
|
||||
"description": "Docker/OCI image reference"
|
||||
},
|
||||
"version": {
|
||||
"type": "string",
|
||||
"description": "Requested version"
|
||||
},
|
||||
"reason": {
|
||||
"type": "string",
|
||||
"description": "Human-readable reason for request"
|
||||
},
|
||||
"requested_at": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Schema**: `deploy-response/v1`
|
||||
|
||||
```json
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "object",
|
||||
"required": ["request_id", "status"],
|
||||
"properties": {
|
||||
"request_id": {
|
||||
"type": "string",
|
||||
"description": "ID of the original request"
|
||||
},
|
||||
"status": {
|
||||
"type": "string",
|
||||
"enum": ["accepted", "rejected", "completed", "failed"],
|
||||
"description": "Response status"
|
||||
},
|
||||
"reason": {
|
||||
"type": "string",
|
||||
"description": "Reason for rejection or failure"
|
||||
},
|
||||
"completed_at": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Registration
|
||||
|
||||
On backend startup, all 4 protocols should be auto-registered via `dwn.register-protocol`:
|
||||
|
||||
```rust
|
||||
const ARCHIPELAGO_PROTOCOLS: &[&str] = &[
|
||||
"https://archipelago.dev/protocols/node-identity/v1",
|
||||
"https://archipelago.dev/protocols/file-catalog/v1",
|
||||
"https://archipelago.dev/protocols/federation/v1",
|
||||
"https://archipelago.dev/protocols/app-deploy/v1",
|
||||
];
|
||||
```
|
||||
|
||||
## Interoperability
|
||||
|
||||
These protocols follow the DWN protocol definition format. Any application that implements DWN can:
|
||||
|
||||
1. **Read** node announcements to discover Archipelago nodes
|
||||
2. **Browse** file catalogs to find shared content
|
||||
3. **Query** federation state to understand network topology
|
||||
4. **Request** app deployments through the standard DWN messaging interface
|
||||
|
||||
The `published: true` flag on protocols 1 and 2 means any DWN node can query for these records. Protocols 3 and 4 are `published: false` (private — only shared with authorized peers).
|
||||
Reference in New Issue
Block a user