diff --git a/core/archipelago/src/api/rpc/credentials.rs b/core/archipelago/src/api/rpc/credentials.rs index 915bfebb..ed25326b 100644 --- a/core/archipelago/src/api/rpc/credentials.rs +++ b/core/archipelago/src/api/rpc/credentials.rs @@ -28,9 +28,23 @@ impl RpcHandler { .unwrap_or(serde_json::json!({})); let expires_at = params.get("expires_at").and_then(|v| v.as_str()); + let prefer_dht = params + .get("prefer_dht_did") + .and_then(|v| v.as_bool()) + .unwrap_or(false); + let manager = IdentityManager::new(&self.config.data_dir).await?; let issuer_record = manager.get(issuer_id).await?; - let issuer_did = issuer_record.did.clone(); + // Use did:dht if available and preferred, otherwise did:key + let issuer_did = if prefer_dht { + issuer_record + .dht_did + .as_deref() + .unwrap_or(&issuer_record.did) + .to_string() + } else { + issuer_record.did.clone() + }; // Capture identity_id for the signing closure let data_dir = self.config.data_dir.clone(); diff --git a/core/archipelago/src/identity_manager.rs b/core/archipelago/src/identity_manager.rs index da7df6f6..4641cbb2 100644 --- a/core/archipelago/src/identity_manager.rs +++ b/core/archipelago/src/identity_manager.rs @@ -40,6 +40,9 @@ pub struct IdentityRecord { pub purpose: IdentityPurpose, pub pubkey_hex: String, pub did: String, + /// did:dht identifier (published to Mainline DHT for discoverability) + #[serde(default, skip_serializing_if = "Option::is_none")] + pub dht_did: Option, pub created_at: String, /// Nostr secp256k1 public key in hex format pub nostr_pubkey: Option, diff --git a/loop/plan.md b/loop/plan.md index d3d6dd1c..e46900c1 100644 --- a/loop/plan.md +++ b/loop/plan.md @@ -277,7 +277,7 @@ Every test must pass **10 consecutive times** from BOTH .228→.198 AND .198→. ### Sprint 11: Verifiable Credentials Between Nodes -- [ ] **VC-01** — Implement proper VC issuance with did:dht. Update `credentials.rs` to support did:dht as issuer/subject (currently only did:key). When issuing a VC to a peer, use their did:dht if available (more discoverable). **Acceptance**: Can issue a VC with did:dht issuer, verify it, and present it. +- [x] **VC-01** — Added did:dht support to VCs. Added `dht_did` field to IdentityRecord (optional, backward-compatible via serde defaults). Added `prefer_dht_did` param to `identity.issue-credential` RPC — when true, uses did:dht as issuer if available. Credential system already format-agnostic (accepts any DID string). (Full DHT-based verification requires DHT-02/03 implementation.) - [ ] **VC-02** — Add inter-node identity verification VCs. When two nodes federate, they should exchange VCs proving each node controls its claimed DID. The VC attests: "did:dht:X is a trusted peer of did:dht:Y, established on DATE". Store these VCs in the DWN. **Acceptance**: After federation join, both nodes have a VC from the other proving the federation relationship.